mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-13 17:27:21 -05:00
MBE: Support for SDRTrunk NXDN MBE files (WIP); #298
DMR: Clarify and Decode FSN Value on Data Headers; #350 NXDN: Fix errors on KS creation on AES discard bytes on voice application; GCC: Fix Misc unused-but-set-variable warnings (GCC Version GNU 16.1.1);
This commit is contained in:
@@ -293,8 +293,19 @@ void dmr_dheader (dsd_opts * opts, dsd_state * state, uint8_t dheader[], uint8_t
|
||||
//Confirmed or Unconfirmed Data Packets Header
|
||||
if (dpf == 2 || dpf == 3)
|
||||
{
|
||||
if (dpf == 2) fprintf (stderr, "\n SAP %02d [%s] - FMF %d - BLOCKS %02d - PAD %02d - FSN %d", sap, sap_string, f, bf, poc, fsn);
|
||||
if (dpf == 3) fprintf (stderr, "\n SAP %02d [%s] - FMF %d - BLOCKS %02d - PAD %02d - S %d - NS %d - FSN %d", sap, sap_string, f, bf, poc, s, ns, fsn);
|
||||
|
||||
uint8_t fsn_number = (fsn & 7) + 1;
|
||||
|
||||
char fsn_string[50];
|
||||
memset(fsn_string, 0, sizeof(fsn_string));
|
||||
|
||||
if (fsn == 0) sprintf(fsn_string, "%s", "Unconfirmed data single fragment");
|
||||
else if (fsn == 8) sprintf(fsn_string, "%s", "Confirmed data single fragment");
|
||||
else if (fsn >= 9) sprintf(fsn_string, "%s", "Last confirmed data fragment with number");
|
||||
else sprintf(fsn_string, "%s", "Subsequent confirmed data fragment with number");
|
||||
|
||||
if (dpf == 2) fprintf (stderr, "\n SAP %02d [%s] - FMF %d - BLOCKS %02d - PAD %02d - FSN: [%X] - %s %d; ", sap, sap_string, f, bf, poc, fsn, fsn_string, fsn_number);
|
||||
if (dpf == 3) fprintf (stderr, "\n SAP %02d [%s] - FMF %d - BLOCKS %02d - PAD %02d - S %d - NS %d - FSN: [%X] - %s %d; ", sap, sap_string, f, bf, poc, s, ns, fsn, fsn_string, fsn_number);
|
||||
state->data_header_blocks[slot] = bf;
|
||||
if (dpf == 3) state->data_conf_data[slot] = 1; //set confirmed data delivery flag for additional CRC checks, block assembly, etc.
|
||||
|
||||
|
||||
@@ -2194,6 +2194,8 @@ void agsm (dsd_opts * opts, dsd_state * state, short * input, int len)
|
||||
|
||||
state->aout_gainA = coeff; //store for internal use
|
||||
|
||||
UNUSED(avg);
|
||||
|
||||
}
|
||||
|
||||
//until analog agc is fixed, going to use a manual gain control on this
|
||||
|
||||
159
src/dsd_file.c
159
src/dsd_file.c
@@ -1345,6 +1345,18 @@ void read_sdrtrunk_json_format (dsd_opts * opts, dsd_state * state)
|
||||
state->lastsynctype = 10;
|
||||
}
|
||||
|
||||
if (strncmp ("NXDN", str_buffer, 4) == 0)
|
||||
{
|
||||
//set AMBE+2 protocol here
|
||||
protocol = 3;
|
||||
|
||||
//disable dmra (+7 on ks_idx)
|
||||
is_dmra = 0;
|
||||
|
||||
state->synctype = 28;
|
||||
state->lastsynctype = 28;
|
||||
}
|
||||
|
||||
//open .imb or .amb file, if desired, but only after setting a synctype
|
||||
if (state->synctype != -1)
|
||||
{
|
||||
@@ -1355,6 +1367,57 @@ void read_sdrtrunk_json_format (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
}
|
||||
|
||||
if (strncmp ("tag", str_buffer, 3) == 0)
|
||||
{
|
||||
|
||||
str_buffer = strtok(NULL, "\n"); //copies to End of Line
|
||||
|
||||
//debug
|
||||
// fprintf (stderr, " TAG: %s", str_buffer);
|
||||
|
||||
//NOTE: Nothing coded for SDRTrunk MBE files provides information regarding
|
||||
//possible FACCH1 steals on voice frames, so keystrem index position here can
|
||||
//become unsynced on some voice frames if trunking or other does FACCH1 steals
|
||||
//when the system is really busy, or radio drops out. Writing code to read ahead
|
||||
//would still not tell us if the FACCH1 steal was in vocoder socket 1 or 2
|
||||
|
||||
//NOTE: Above may become even more noticeable on DES or AES as those keystreams
|
||||
//are generated for two voice superframes, and the decryption may become unsynced
|
||||
//until the next VCALL_IV is read in from the MBE file.
|
||||
|
||||
//Check NXDN tag value, set the ks_idx to proper position
|
||||
//by looking for SACCH_1, SACCH_2, SACCH_3, or SACCH_4 for scrambler
|
||||
if (alg_id == 1 && protocol == 3)
|
||||
{
|
||||
if (strncmp ("SACCH 1", str_buffer+4, 7) == 0)
|
||||
{
|
||||
ks_idx = 0;
|
||||
if (opts->payload == 1)
|
||||
fprintf (stderr, "\n PF 1/4");
|
||||
}
|
||||
else if (strncmp ("SACCH 2", str_buffer+4, 7) == 0)
|
||||
{
|
||||
ks_idx = 49*4;
|
||||
if (opts->payload == 1)
|
||||
fprintf (stderr, "\n PF 2/4");
|
||||
}
|
||||
else if (strncmp ("SACCH 3", str_buffer+4, 7) == 0)
|
||||
{
|
||||
ks_idx = 49*8;
|
||||
if (opts->payload == 1)
|
||||
fprintf (stderr, "\n PF 3/4");
|
||||
}
|
||||
else if (strncmp ("SACCH 4", str_buffer+4, 7) == 0)
|
||||
{
|
||||
ks_idx = 49*12;
|
||||
if (opts->payload == 1)
|
||||
fprintf (stderr, "\n PF 4/4");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (strncmp ("call_type", str_buffer, 9) == 0)
|
||||
{
|
||||
str_buffer = strtok(NULL, " : \""); //next value after any : "" string
|
||||
@@ -1388,6 +1451,29 @@ void read_sdrtrunk_json_format (dsd_opts * opts, dsd_state * state)
|
||||
key_id = 0;
|
||||
iv_hex = 0;
|
||||
|
||||
//NXDN Forced Scrambler
|
||||
if (is_enc == 1 && state->forced_alg_id == 1 && protocol == 3)
|
||||
{
|
||||
|
||||
alg_id = state->forced_alg_id;
|
||||
|
||||
//TEST: Key Load Forced Scrambler Key by TGT or SRC value?
|
||||
if (state->forced_alg_id == 1 && state->keyloader == 1)
|
||||
{
|
||||
if (state->rkey_array[target] != 0)
|
||||
state->R = target;
|
||||
else if (state->rkey_array[source] != 0)
|
||||
state->R = source;
|
||||
}
|
||||
|
||||
if (alg_id == 1 && state->R != 0)
|
||||
{
|
||||
pdu_scrambler_keystream_creation(ks, state->R, 16*49);
|
||||
ks_available = 1;
|
||||
}
|
||||
//DES and AES still require the IV for KS creation
|
||||
}
|
||||
|
||||
//debug set value
|
||||
// fprintf (stderr, " ENC: %d;", is_enc);
|
||||
|
||||
@@ -1523,6 +1609,23 @@ void read_sdrtrunk_json_format (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
key_id = strtol (str_buffer, NULL, 10);
|
||||
|
||||
//NXDN Scrambler Setup
|
||||
if (alg_id == 1 && protocol == 3)
|
||||
{
|
||||
|
||||
state->payload_keyid = key_id;
|
||||
|
||||
//Scrambler Key Loading
|
||||
if (state->keyloader == 1)
|
||||
keyring(opts, state);
|
||||
|
||||
if (state->R != 0)
|
||||
{
|
||||
pdu_scrambler_keystream_creation(ks, state->R, 16*49);
|
||||
ks_available = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//debug set value
|
||||
if (opts->payload == 1)
|
||||
fprintf (stderr, "\n Key ID: %04X;", key_id);
|
||||
@@ -1708,6 +1811,29 @@ void read_sdrtrunk_json_format (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
}
|
||||
|
||||
//WIP: Add handling for NXDN DES and AES256
|
||||
//NOTE: This hinges on where SDRTrunk places the IV for the call,
|
||||
//ideally needs to be after the SACCH4 voice frames
|
||||
else if (protocol == 3 && alg_id == 2 && state->R != 0)
|
||||
{
|
||||
//double check discards (seems same as in dsd_mbe)
|
||||
des_multi_keystream_output(iv_hex, state->R, ks_bytes, 1, 32);
|
||||
|
||||
unpack_byte_array_into_bit_array(ks_bytes+8, ks, 256-8);
|
||||
|
||||
ambe2_counter = 0;
|
||||
ks_idx = 0;
|
||||
|
||||
ks_available = 1;
|
||||
}
|
||||
else if (protocol == 3 && alg_id == 3 && state->aes_key_loaded[0] == 1)
|
||||
{
|
||||
//TODO: All of This
|
||||
|
||||
// ambe2_counter = 0;
|
||||
// ks_idx = 0;
|
||||
}
|
||||
|
||||
//Pull request: https://github.com/DSheirer/sdrtrunk/pull/2273
|
||||
//Merged into SDRTrunk nightly so should be able to handle this better now
|
||||
|
||||
@@ -1776,7 +1902,7 @@ void read_sdrtrunk_json_format (dsd_opts * opts, dsd_state * state)
|
||||
// fprintf (stderr, " Enc Play;");
|
||||
|
||||
}
|
||||
else if (protocol == 2) //P25p2 AMBE
|
||||
else if (protocol == 2) //P25p2 or DMR AMBE+2
|
||||
{
|
||||
//debug print current str_buffer
|
||||
// fprintf (stderr, "\n AMBE HEX: %s", str_buffer);
|
||||
@@ -1801,6 +1927,37 @@ void read_sdrtrunk_json_format (dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else if (protocol == 3) //NXDN AMBE+2 (EHR)
|
||||
{
|
||||
//debug print current str_buffer
|
||||
// fprintf (stderr, "\n AMBE HEX: %s", str_buffer);
|
||||
|
||||
//18 hex characters on 'hex' which is the AMBE interleaved C codewords
|
||||
ks_idx = ambe2_str_to_decode(opts, state, str_buffer, ks, ks_idx, is_dmra, is_enc, ks_available);
|
||||
|
||||
//debug
|
||||
// if (is_enc == 1 && ks_available == 0)
|
||||
// fprintf (stderr, " Enc Mute;");
|
||||
// else if (is_enc == 1 && ks_available == 1)
|
||||
// fprintf (stderr, " Enc Play;");
|
||||
|
||||
//increment AMBE+2 counter
|
||||
ambe2_counter++;
|
||||
|
||||
//Really actually need the Structure Field (PF values here)
|
||||
//reset if over for NXDN 16 AMBE+2 frames for Scrambler
|
||||
if (alg_id == 1 && ambe2_counter == 16)
|
||||
{
|
||||
ambe2_counter = 0;
|
||||
ks_idx = 0;
|
||||
}
|
||||
else if (alg_id > 1 && ambe2_counter == 32)
|
||||
{
|
||||
ambe2_counter = 0;
|
||||
ks_idx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strncmp ("time", str_buffer, 4) == 0)
|
||||
|
||||
@@ -535,7 +535,7 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
||||
state->bit_counterL = 0;
|
||||
|
||||
//unpack the octets into a bit-wise keystream
|
||||
unpack_byte_array_into_bit_array(state->ks_octetL+8, state->ks_bitstreamL, 15*8);
|
||||
unpack_byte_array_into_bit_array(state->ks_octetL+16, state->ks_bitstreamL, 14*16);
|
||||
|
||||
//reset flag to 0
|
||||
state->nxdn_new_iv = 0;
|
||||
@@ -546,7 +546,7 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
||||
if (state->bit_counterL > (1568-49))
|
||||
state->bit_counterL = (1568-49);
|
||||
|
||||
//Keystream creation is currently inside of the NXDN_decode_VCALL_IV function
|
||||
//Keystream Application (no +7 discard like DMRA)
|
||||
for (i = 0; i < 49; i++)
|
||||
ambe_d[i] ^= state->ks_bitstreamL[state->bit_counterL++];
|
||||
|
||||
|
||||
@@ -1479,7 +1479,7 @@ bool QR_16_7_6_decode(unsigned char *rxBits)
|
||||
unsigned int syndromeI = 0; // syndrome index
|
||||
int is = 0;
|
||||
int i = 0;
|
||||
int corrections = 0;
|
||||
int corrections = 0; UNUSED(corrections);
|
||||
for (is = 0; is < 9; is++)
|
||||
{
|
||||
syndromeI += (((rxBits[0] * QR_16_7_6_m_H[16*is + 0])
|
||||
|
||||
@@ -111,7 +111,7 @@ void nxdn_frame (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
//debug look at the "off bits" of the encoded lich, should be all 1's (8)
|
||||
//disble this code if sync issues arise, this may not be ideal of marginal signal
|
||||
uint8_t lich_off_hex = 0;
|
||||
uint8_t lich_off_hex = 0; UNUSED(lich_off_hex);
|
||||
for (int i=0; i<8; i++)
|
||||
lich_off_hex += lich_bits[(i*2)+1];
|
||||
#ifdef NXDN_LICH_OFFBITS
|
||||
|
||||
@@ -57,7 +57,7 @@ int count_bits(uint8_t b, int slen)
|
||||
int p25_12(uint8_t * input, uint8_t treturn[12])
|
||||
{
|
||||
int i, t;
|
||||
int total_err = 0;
|
||||
int total_err = 0; UNUSED(total_err);
|
||||
|
||||
uint8_t deinterleaved_dibits[98];
|
||||
memset(deinterleaved_dibits, 0, sizeof(deinterleaved_dibits));
|
||||
|
||||
Reference in New Issue
Block a user