mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-13 17:27:21 -05:00
Rewrite NXDN Dibit PN95 Code and allow custom seed value; #318
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
Build Version: AW 2025-182-g24c1dd9
|
||||
Build Version: AW 2025-197-gf3b89f1
|
||||
MBElib Version: 1.3.4
|
||||
CODEC2 Support Enabled
|
||||
|
||||
@@ -137,6 +137,8 @@ Decoder options:
|
||||
Advanced Decoder options:
|
||||
-X <hex> Manually Set P2 Parameters (WACN, SYSID, CC/NAC)
|
||||
(-X BEE00ABC123)
|
||||
-* <dec> Manually Set NXDN PN95 Dibit Scrambler Seed (1-511)
|
||||
(-* 261)
|
||||
-D <dec> Manually Set TIII DMR Location Area n bit len (0-10)(10 max)
|
||||
(Value defaults to max n bit value for site model size)
|
||||
(Setting 0 will show full Site ID, no area/subarea)
|
||||
|
||||
@@ -898,6 +898,7 @@ typedef struct
|
||||
uint8_t nxdn_sacch_frame_segcrc[4];
|
||||
uint8_t nxdn_alias_block_number;
|
||||
char nxdn_alias_block_segment[4][4][8];
|
||||
uint16_t nxdn_pn95_seed;
|
||||
|
||||
//site/srv/cch info
|
||||
char nxdn_location_category[14];
|
||||
@@ -1281,7 +1282,7 @@ void ncursesClose ();
|
||||
|
||||
//new NXDN Functions start here!
|
||||
void nxdn_frame (dsd_opts * opts, dsd_state * state);
|
||||
void nxdn_descramble (uint8_t dibits[], int len);
|
||||
void nxdn_pn95_dibit_scrambler(dsd_state * state, uint8_t * dibits, int len);
|
||||
//nxdn deinterleaving/depuncturing functions
|
||||
void nxdn_deperm_facch (dsd_opts * opts, dsd_state * state, uint8_t bits[144]);
|
||||
void nxdn_deperm_sacch (dsd_opts * opts, dsd_state * state, uint8_t bits[60]);
|
||||
|
||||
@@ -1214,6 +1214,7 @@
|
||||
memset (state->nxdn_sacch_frame_segment, 1, sizeof(state->nxdn_sacch_frame_segment));
|
||||
state->nxdn_alias_block_number = 0;
|
||||
memset (state->nxdn_alias_block_segment, 0, sizeof(state->nxdn_alias_block_segment));
|
||||
state->nxdn_pn95_seed = 228; //default value
|
||||
|
||||
//site/srv/cch info
|
||||
state->nxdn_location_site_code = 0;
|
||||
@@ -1526,6 +1527,8 @@
|
||||
printf ("Advanced Decoder options:\n");
|
||||
printf (" -X <hex> Manually Set P2 Parameters (WACN, SYSID, CC/NAC)\n");
|
||||
printf (" (-X BEE00ABC123)\n");
|
||||
printf (" -* <dec> Manually Set NXDN PN95 Dibit Scrambler Seed (1-511)\n");
|
||||
printf (" (-* 261)\n");
|
||||
printf (" -D <dec> Manually Set TIII DMR Location Area n bit len (0-10)(10 max)\n");
|
||||
printf (" (Value defaults to max n bit value for site model size)\n");
|
||||
printf (" (Setting 0 will show full Site ID, no area/subarea)\n");
|
||||
@@ -1906,7 +1909,7 @@
|
||||
|
||||
exitflag = 0;
|
||||
|
||||
while ((c = getopt (argc, argv, "~yhaepPqs:t:v:z:i:o:d:c:g:n:w:B:C:R:f:m:u:x:A:S:M:G:D:L:V:U:YK:b:H:X:NQ:WrlZTF@:!:01:2:345:6:7:89:Ek:I:J:O")) != -1)
|
||||
while ((c = getopt (argc, argv, "~yhaepPqs:t:v:z:i:o:d:c:g:n:w:B:C:R:f:m:u:x:A:S:M:G:D:L:V:U:YK:b:H:X:NQ:WrlZTF@:!:01:2:345:6:7:8*:9:Ek:I:J:O")) != -1)
|
||||
{
|
||||
|
||||
switch (c)
|
||||
@@ -2217,7 +2220,15 @@
|
||||
if (state.R > 0x7FFF) state.R = 0x7FFF;
|
||||
//disable keyloader in case user tries to use this and it at the same time
|
||||
state.keyloader = 0;
|
||||
fprintf (stderr, "NXDN Scrambler Key set to: %05d;", state.R);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
sscanf (optarg, "%hu", &state.nxdn_pn95_seed);
|
||||
if (state.nxdn_pn95_seed > 0x1FF) state.nxdn_pn95_seed = 0x1FF;
|
||||
else if (state.nxdn_pn95_seed == 0) state.nxdn_pn95_seed = 228;
|
||||
fprintf (stderr, "NXDN PN9 Seed Value set to: %03d;", state.nxdn_pn95_seed);
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
//new handling for 10/32/64 Char Key
|
||||
|
||||
@@ -25,26 +25,48 @@
|
||||
#include "dsd.h"
|
||||
#include "nxdn_const.h"
|
||||
|
||||
//NOTE: Descrambling was having an issue without a value inside the brackets, but only when
|
||||
//the PARITY table was disabled, was this due to a memory issue or overflow?
|
||||
static const uint8_t scramble_t[182] = { //values are the position values we need to invert in the descramble
|
||||
2, 5, 6, 7, 10, 12, 14, 16, 17, 22, 23, 25, 26, 27, 28, 30, 33, 34, 36, 37, 38, 41, 45, 47,
|
||||
52, 54, 56, 57, 59, 62, 63, 64, 65, 66, 67, 69, 70, 73, 76, 79, 81, 82, 84, 85, 86, 87, 88,
|
||||
89, 92, 95, 96, 98, 100, 103, 104, 107, 108, 116, 117, 121, 122, 125, 127, 131, 132, 134,
|
||||
137, 139, 140, 141, 142, 143, 144, 145, 147, 151, 153, 154, 158, 159, 160, 162, 164, 165,
|
||||
168, 170, 171, 174, 175, 176, 177, 181
|
||||
};
|
||||
|
||||
|
||||
//decoding functions here
|
||||
void nxdn_descramble(uint8_t dibits[], int len)
|
||||
void nxdn_pn95_dibit_scrambler(dsd_state * state, uint8_t * dibits, int len)
|
||||
{
|
||||
for (int i=0; i<len; i++)
|
||||
|
||||
uint16_t lfsr = state->nxdn_pn95_seed; //default value is 228 / 0xE4
|
||||
|
||||
//debug hard set
|
||||
// lfsr = 261;
|
||||
|
||||
uint16_t bit = 0;
|
||||
uint8_t pN95[182]; memset (pN95, 0, sizeof(pN95));
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
if (scramble_t[i] >= len)
|
||||
break;
|
||||
dibits[scramble_t[i]] ^= 0x2; // invert sign of scrambled dibits
|
||||
//before feedback, take the bit
|
||||
pN95[i] = lfsr & 1;
|
||||
|
||||
//since this is right shift, the taps are 0 and 4, and not 8 and 4 (9,5)
|
||||
bit = ((lfsr >> 4) ^ (lfsr >> 0)) & 1;
|
||||
lfsr >>= 1;
|
||||
lfsr |= (bit << 8);
|
||||
|
||||
}
|
||||
|
||||
//convert the pN sequence to a scramble table
|
||||
uint8_t scramble_table[182]; memset(scramble_table, 0, sizeof(scramble_table));
|
||||
int k = 0;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
if (pN95[i] == 1)
|
||||
scramble_table[k++] = i;
|
||||
}
|
||||
|
||||
//the entries into the scramble_table are the dibits (symbols) that are inverted
|
||||
for (int i = 0; i < k; i++)
|
||||
{
|
||||
dibits[scramble_table[i]] ^= 0x2;
|
||||
dibits[scramble_table[i]] &= 0x3;
|
||||
}
|
||||
|
||||
//debug, make sure we don't overflow dibits array
|
||||
// fprintf (stderr, " PN95: K: %d; Len: %d; ", k, len);
|
||||
|
||||
}
|
||||
|
||||
void nxdn_deperm_facch(dsd_opts * opts, dsd_state * state, uint8_t bits[144])
|
||||
|
||||
@@ -90,7 +90,7 @@ void nxdn_frame (dsd_opts * opts, dsd_state * state)
|
||||
//collect lich bits first, if they are good, then we can collect the rest of them
|
||||
for (int i = 0; i < 8; i++) lich_dibits[i] = dbuf[i] = getDibit(opts, state);
|
||||
|
||||
nxdn_descramble (lich_dibits, 8);
|
||||
nxdn_pn95_dibit_scrambler (state, lich_dibits, 8);
|
||||
|
||||
lich = 0;
|
||||
for (int i=0; i<8; i++) lich |= (lich_dibits[i] >> 1) << (7-i);
|
||||
@@ -343,7 +343,7 @@ void nxdn_frame (dsd_opts * opts, dsd_state * state)
|
||||
dbuf[i+8] = getDibit(opts, state);
|
||||
}
|
||||
|
||||
nxdn_descramble (dbuf, 182); //sizeof(dbuf)
|
||||
nxdn_pn95_dibit_scrambler (state, dbuf, 182);
|
||||
|
||||
//seperate our dbuf (dibit_buffer) into individual bit array
|
||||
for (int i = 0; i < 182; i++)
|
||||
|
||||
Reference in New Issue
Block a user