diff --git a/src/dmr_block.c b/src/dmr_block.c index 05149af..dd13342 100644 --- a/src/dmr_block.c +++ b/src/dmr_block.c @@ -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. diff --git a/src/dsd_audio2.c b/src/dsd_audio2.c index b7dabdf..c00300f 100644 --- a/src/dsd_audio2.c +++ b/src/dsd_audio2.c @@ -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 diff --git a/src/dsd_file.c b/src/dsd_file.c index 04c223f..f252888 100644 --- a/src/dsd_file.c +++ b/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) diff --git a/src/dsd_mbe.c b/src/dsd_mbe.c index 026d4cd..658cf8c 100644 --- a/src/dsd_mbe.c +++ b/src/dsd_mbe.c @@ -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++]; diff --git a/src/fec.c b/src/fec.c index d257fb8..b936e59 100644 --- a/src/fec.c +++ b/src/fec.c @@ -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]) diff --git a/src/nxdn_frame.c b/src/nxdn_frame.c index 850ac5c..ce6df3d 100644 --- a/src/nxdn_frame.c +++ b/src/nxdn_frame.c @@ -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 diff --git a/src/p25_12.c b/src/p25_12.c index a98544c..ea7363d 100644 --- a/src/p25_12.c +++ b/src/p25_12.c @@ -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));