mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-13 09:17:20 -05:00
SDRTrunk .mbe File Replay Initial Commit; #298
This commit is contained in:
@@ -617,7 +617,8 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot)
|
||||
event_struct->Event_History_Items[0].source_id = source_id;
|
||||
event_struct->Event_History_Items[0].target_id = target_id;
|
||||
event_struct->Event_History_Items[0].channel = channel; //need to add this to trunking messages, if tuned from call grant
|
||||
event_struct->Event_History_Items[0].event_time = time(NULL);
|
||||
if (opts->playfiles == 0) //if playing back .mbe files with a time in it, don't set this
|
||||
event_struct->Event_History_Items[0].event_time = time(NULL);
|
||||
sprintf (event_struct->Event_History_Items[0].sysid_string, "%s", sysid_string);
|
||||
sprintf (event_struct->Event_History_Items[0].src_str, "%s", src_str);
|
||||
sprintf (event_struct->Event_History_Items[0].tgt_str, "%s", tgt_str);
|
||||
|
||||
622
src/dsd_file.c
622
src/dsd_file.c
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
|
||||
#include "dsd.h"
|
||||
#include "p25p1_const.h" //for imbe fr (7200)
|
||||
#include "dmr_const.h" //for ambe+2 fr
|
||||
|
||||
void saveImbe4400Data (dsd_opts * opts, dsd_state * state, char *imbe_d)
|
||||
{
|
||||
@@ -244,9 +246,17 @@ openMbeInFile (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
opts->mbe_in_f = fopen (opts->mbe_in_file, "ro");
|
||||
if (opts->mbe_in_f == NULL)
|
||||
{
|
||||
fprintf (stderr,"Error: could not open %s\n", opts->mbe_in_file);
|
||||
}
|
||||
fprintf (stderr,"Error: could not open %s\n", opts->mbe_in_file);
|
||||
|
||||
//this will check the last 4 characters of the opts->mbe_in_file string
|
||||
char ext[5]; memset(ext, 0, sizeof(ext));
|
||||
uint16_t str_len = strlen((const char*)opts->mbe_in_file);
|
||||
uint16_t ext_ptr = str_len - 4;
|
||||
strncpy (ext, opts->mbe_in_file+ext_ptr, 4);
|
||||
|
||||
//debug
|
||||
// fprintf (stderr, "EXT: %s;", ext);
|
||||
|
||||
|
||||
// read cookie
|
||||
cookie[0] = fgetc (opts->mbe_in_f);
|
||||
@@ -254,26 +264,27 @@ openMbeInFile (dsd_opts * opts, dsd_state * state)
|
||||
cookie[2] = fgetc (opts->mbe_in_f);
|
||||
cookie[3] = fgetc (opts->mbe_in_f);
|
||||
cookie[4] = 0;
|
||||
|
||||
//ambe+2
|
||||
if (strstr (cookie, ".amb") != NULL)
|
||||
{
|
||||
state->mbe_file_type = 1;
|
||||
}
|
||||
//p1 and pv
|
||||
else if (strstr (cookie, ".imb") != NULL)
|
||||
{
|
||||
state->mbe_file_type = 0;
|
||||
}
|
||||
//d-star ambe
|
||||
else if (strstr (cookie, ".dmb") != NULL)
|
||||
{
|
||||
state->mbe_file_type = 2;
|
||||
}
|
||||
//sdrtrunk formated mbe json file
|
||||
else if (strncmp (".mbe", ext, 4) == 0)
|
||||
state->mbe_file_type = 3;
|
||||
else
|
||||
{
|
||||
state->mbe_file_type = -1;
|
||||
fprintf (stderr,"Error - unrecognized file type\n");
|
||||
}
|
||||
{
|
||||
state->mbe_file_type = -1;
|
||||
fprintf (stderr,"Error - unrecognized file type\n");
|
||||
|
||||
//try SDRTrunk JSON format as last resort
|
||||
state->mbe_file_type = 3;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -323,6 +334,9 @@ void openMbeOutFile (dsd_opts * opts, dsd_state * state)
|
||||
char * timestr; //add timestr here, so we can assign it and also free it to prevent memory leak
|
||||
char * datestr;
|
||||
|
||||
//random element of filename, so two files won't overwrite one another
|
||||
uint16_t random_number = rand() & 0xFFFF;
|
||||
|
||||
timestr = getTime();
|
||||
datestr = getDate();
|
||||
|
||||
@@ -350,7 +364,7 @@ void openMbeOutFile (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
state->tgcount = 0;
|
||||
|
||||
sprintf (opts->mbe_out_file, "%s %s S1%s", datestr, timestr, ext);
|
||||
sprintf (opts->mbe_out_file, "%s_%s_%04X_S1%s", datestr, timestr, random_number, ext);
|
||||
|
||||
sprintf (opts->mbe_out_path, "%s%s", opts->mbe_out_dir, opts->mbe_out_file);
|
||||
|
||||
@@ -385,6 +399,9 @@ void openMbeOutFileR (dsd_opts * opts, dsd_state * state)
|
||||
char * timestr; //add timestr here, so we can assign it and also free it to prevent memory leak
|
||||
char * datestr;
|
||||
|
||||
//random element of filename, so two files won't overwrite one another
|
||||
uint16_t random_number = rand() & 0xFFFF;
|
||||
|
||||
timestr = getTime();
|
||||
datestr = getDate();
|
||||
|
||||
@@ -412,7 +429,7 @@ void openMbeOutFileR (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
state->tgcount = 0;
|
||||
|
||||
sprintf (opts->mbe_out_fileR, "%s %s S2%s", datestr, timestr, ext);
|
||||
sprintf (opts->mbe_out_fileR, "%s_%s_%04X_S2%s", datestr, timestr, random_number, ext);
|
||||
|
||||
sprintf (opts->mbe_out_path, "%s%s", opts->mbe_out_dir, opts->mbe_out_fileR);
|
||||
|
||||
@@ -488,8 +505,9 @@ SNDFILE * close_and_rename_wav_file(SNDFILE * wav_file, char * wav_out_filename,
|
||||
{
|
||||
sf_close(wav_file);
|
||||
|
||||
char * datestr = getDate();
|
||||
char * timestr = getTime();
|
||||
time_t event_time = event_struct->Event_History_Items[0].event_time;
|
||||
char * datestr = getDateF(event_time);
|
||||
char * timestr = getTimeF(event_time);
|
||||
uint16_t random_number = rand();
|
||||
|
||||
uint32_t source_id = event_struct->Event_History_Items[0].source_id;
|
||||
@@ -849,4 +867,574 @@ uint16_t parse_raw_user_string (char * input, uint8_t * output)
|
||||
if (shift) output[len-1] <<= 4;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
uint16_t ambe2_str_to_decode(dsd_opts * opts, dsd_state * state, char * ambe_str, uint8_t * ks, uint16_t ks_idx, uint8_t dmra)
|
||||
{
|
||||
UNUSED(opts);
|
||||
|
||||
char ambe_fr[4][24]; memset (ambe_fr, 0, sizeof(ambe_fr));
|
||||
uint8_t dibit_pair = 0;
|
||||
uint8_t dibit1 = 0, dibit2 = 0;
|
||||
const int *w, *x, *y, *z;
|
||||
w = rW;
|
||||
x = rX;
|
||||
y = rY;
|
||||
z = rZ;
|
||||
for (size_t i = 0; i < 18; i++)
|
||||
{
|
||||
|
||||
char octet_char[2];
|
||||
octet_char[1] = 0;
|
||||
|
||||
strncpy (octet_char, ambe_str+i, 1);
|
||||
sscanf (octet_char, "%hhX", &dibit_pair);
|
||||
|
||||
dibit1 = (dibit_pair >> 2) & 0x3;
|
||||
dibit2 = (dibit_pair >> 0) & 0x3;
|
||||
|
||||
//debug
|
||||
// fprintf (stderr, "\n dibit_pair: %X = %d, %d;", dibit_pair, dibit1, dibit2);
|
||||
|
||||
//load into ambe_fr
|
||||
ambe_fr[*w][*x] = (1 & (dibit1 >> 1)); // bit 1
|
||||
ambe_fr[*y][*z] = (1 & (dibit1 >> 0)); // bit 0
|
||||
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
|
||||
ambe_fr[*w][*x] = (1 & (dibit2 >> 1)); // bit 1
|
||||
ambe_fr[*y][*z] = (1 & (dibit2 >> 0)); // bit 0
|
||||
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
|
||||
//working now!
|
||||
|
||||
}
|
||||
|
||||
char ambe_d[49]; memset(ambe_d, 0, sizeof(ambe_d));
|
||||
state->errs = mbe_eccAmbe3600x2450C0 (ambe_fr);
|
||||
state->errs2 = state->errs;
|
||||
mbe_demodulateAmbe3600x2450Data (ambe_fr);
|
||||
state->errs2 += mbe_eccAmbe3600x2450Data (ambe_fr, ambe_d);
|
||||
state->debug_audio_errors += state->errs2;
|
||||
|
||||
//keystream application
|
||||
for (uint8_t i = 0; i < 49; i++)
|
||||
ambe_d[i] ^= ks[(ks_idx++)%3000];
|
||||
|
||||
//DMRA or P25 KS, skip the left over 7 bits from a byte
|
||||
if (dmra == 1)
|
||||
ks_idx += 7;
|
||||
|
||||
mbe_processAmbe2450Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str,
|
||||
ambe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
|
||||
PrintAMBEData (opts, state, ambe_d);
|
||||
|
||||
//convert and save to .amb file if desired
|
||||
if (opts->mbe_out_f != NULL)
|
||||
saveAmbe2450Data (opts, state, ambe_d);
|
||||
|
||||
//audio out stack
|
||||
if (opts->floating_point == 0)
|
||||
processAudio(opts, state);
|
||||
|
||||
if (opts->wav_out_f != NULL)
|
||||
writeSynthesizedVoice (opts, state);
|
||||
|
||||
if (opts->audio_out == 1 && opts->floating_point == 0)
|
||||
playSynthesizedVoiceMS (opts, state);
|
||||
|
||||
if (opts->floating_point == 1)
|
||||
{
|
||||
memcpy (state->f_l, state->audio_out_temp_buf, sizeof(state->f_l));
|
||||
playSynthesizedVoiceFM (opts, state);
|
||||
}
|
||||
//else if not floating point audio or audio out, then purge the audio buffers before they overflow and segfault
|
||||
else if (opts->audio_out == 0)
|
||||
{
|
||||
if (state->audio_out_idx2 >= 800000)
|
||||
{
|
||||
state->audio_out_float_buf_p = state->audio_out_float_buf + 100;
|
||||
state->audio_out_buf_p = state->audio_out_buf + 100;
|
||||
memset (state->audio_out_float_buf, 0, 100 * sizeof (float));
|
||||
memset (state->audio_out_buf, 0, 100 * sizeof (short));
|
||||
state->audio_out_idx2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ks_idx; //return current ks_idx
|
||||
|
||||
}
|
||||
|
||||
uint16_t imbe_str_to_decode(dsd_opts * opts, dsd_state * state, char * imbe_str, uint8_t * ks, uint16_t ks_idx)
|
||||
{
|
||||
UNUSED(opts);
|
||||
|
||||
char imbe_fr[8][23]; memset (imbe_fr, 0, sizeof(imbe_fr));
|
||||
uint8_t dibit_pair = 0;
|
||||
uint8_t dibit1 = 0, dibit2 = 0;
|
||||
const int *w, *x, *y, *z;
|
||||
w = iW;
|
||||
x = iX;
|
||||
y = iY;
|
||||
z = iZ;
|
||||
for (size_t i = 0; i < 36; i++)
|
||||
{
|
||||
|
||||
char octet_char[2];
|
||||
octet_char[1] = 0;
|
||||
|
||||
strncpy (octet_char, imbe_str+i, 1);
|
||||
sscanf (octet_char, "%hhX", &dibit_pair);
|
||||
|
||||
dibit1 = (dibit_pair >> 2) & 0x3;
|
||||
dibit2 = (dibit_pair >> 0) & 0x3;
|
||||
|
||||
//debug
|
||||
// fprintf (stderr, "\n dibit_pair: %X = %d, %d;", dibit_pair, dibit1, dibit2);
|
||||
|
||||
//load into imbe_fr
|
||||
imbe_fr[*w][*x] = (1 & (dibit1 >> 1)); // bit 1
|
||||
imbe_fr[*y][*z] = (1 & (dibit1 >> 0)); // bit 0
|
||||
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
|
||||
imbe_fr[*w][*x] = (1 & (dibit2 >> 1)); // bit 1
|
||||
imbe_fr[*y][*z] = (1 & (dibit2 >> 0)); // bit 0
|
||||
|
||||
w++;
|
||||
x++;
|
||||
y++;
|
||||
z++;
|
||||
|
||||
//working now!
|
||||
|
||||
}
|
||||
|
||||
char imbe_d[88]; memset(imbe_d, 0, sizeof(imbe_d));
|
||||
state->errs = mbe_eccImbe7200x4400C0 (imbe_fr);
|
||||
state->errs2 = state->errs;
|
||||
mbe_demodulateImbe7200x4400Data (imbe_fr);
|
||||
state->errs2 += mbe_eccImbe7200x4400Data (imbe_fr, imbe_d);
|
||||
state->debug_audio_errors += state->errs2;
|
||||
|
||||
//keystream application
|
||||
for (uint8_t i = 0; i < 88; i++)
|
||||
imbe_d[i] ^= ks[(ks_idx++)%3000];
|
||||
|
||||
mbe_processImbe4400Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str,
|
||||
imbe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
|
||||
PrintIMBEData (opts, state, imbe_d);
|
||||
|
||||
//convert and save to .imb file if desired
|
||||
if (opts->mbe_out_f != NULL)
|
||||
saveImbe4400Data (opts, state, imbe_d);
|
||||
|
||||
//audio out stack
|
||||
if (opts->floating_point == 0)
|
||||
processAudio(opts, state);
|
||||
|
||||
if (opts->wav_out_f != NULL)
|
||||
writeSynthesizedVoice (opts, state);
|
||||
|
||||
if (opts->audio_out == 1 && opts->floating_point == 0)
|
||||
playSynthesizedVoiceMS (opts, state);
|
||||
|
||||
if (opts->floating_point == 1)
|
||||
{
|
||||
memcpy (state->f_l, state->audio_out_temp_buf, sizeof(state->f_l));
|
||||
playSynthesizedVoiceFM (opts, state);
|
||||
}
|
||||
//else if not floating point audio or audio out, then purge the audio buffers before they overflow and segfault
|
||||
else if (opts->audio_out == 0)
|
||||
{
|
||||
if (state->audio_out_idx2 >= 800000)
|
||||
{
|
||||
state->audio_out_float_buf_p = state->audio_out_float_buf + 100;
|
||||
state->audio_out_buf_p = state->audio_out_buf + 100;
|
||||
memset (state->audio_out_float_buf, 0, 100 * sizeof (float));
|
||||
memset (state->audio_out_buf, 0, 100 * sizeof (short));
|
||||
state->audio_out_idx2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ks_idx; //return current ks_idx
|
||||
|
||||
}
|
||||
|
||||
void read_sdrtrunk_json_format (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
|
||||
char * source_str = calloc(0x100000, sizeof(char));
|
||||
size_t source_size;
|
||||
|
||||
int8_t protocol = -1;
|
||||
uint32_t source = 0; UNUSED(source);
|
||||
uint32_t target = 0; UNUSED(target);
|
||||
int8_t gi = -1; UNUSED(gi);
|
||||
uint8_t is_enc = 0; UNUSED(is_enc);
|
||||
uint8_t is_dmra = 1; //Denny, we need an MFID in the JSON file plz
|
||||
|
||||
uint8_t alg_id = 0;
|
||||
uint16_t key_id = 0;
|
||||
unsigned long long int iv_hex = 0;
|
||||
int rc4_db = 256;
|
||||
int rc4_mod = 13;
|
||||
|
||||
time_t event_time = time(NULL); UNUSED(event_time);
|
||||
|
||||
//for event history items
|
||||
state->dmr_color_code = 0;
|
||||
state->lastsrc = 0;
|
||||
state->lasttg = 0;
|
||||
state->gi[0] = -1;
|
||||
state->synctype = -1;
|
||||
state->lastsynctype = -1;
|
||||
|
||||
//watchdog for event history
|
||||
watchdog_event_history(opts, state, 0);
|
||||
watchdog_event_current(opts, state, 0);
|
||||
|
||||
uint8_t ks[3000]; memset (ks, 0, sizeof(ks));
|
||||
uint16_t ks_idx = 0; //keystream index value
|
||||
|
||||
source_size = fread (source_str, 1, 0x100000, opts->mbe_in_f);
|
||||
|
||||
//debug
|
||||
// fprintf (stderr, " Source Size: %d.\n", source_size);
|
||||
// fprintf (stderr, "\n");
|
||||
|
||||
char * str_buffer = calloc(source_size, sizeof(char));
|
||||
|
||||
str_buffer = strtok(source_str, "{ \""); //value after initial { open bracket
|
||||
|
||||
//debug print current str_buffer
|
||||
// fprintf (stderr, "%s", str_buffer);
|
||||
|
||||
for (size_t i = 0; i < source_size; i++)
|
||||
{
|
||||
|
||||
//debug print current str_buffer
|
||||
// fprintf (stderr, "%s", str_buffer);
|
||||
|
||||
//compare and set items accordingly
|
||||
if (strncmp ("protocol", str_buffer, 8) == 0)
|
||||
{
|
||||
str_buffer = strtok(NULL, " : \""); //next value after any : "" string
|
||||
|
||||
//debug print current str_buffer
|
||||
fprintf (stderr, "\n Protocol: %s", str_buffer);
|
||||
|
||||
//compare protocol and set to proper codec etc
|
||||
if (strncmp ("APCO25-PHASE1", str_buffer, 13) == 0)
|
||||
{
|
||||
//set IMBE protocol here
|
||||
protocol = 1;
|
||||
|
||||
//rc4 dropbyte and key len mod
|
||||
rc4_db = 267;
|
||||
rc4_mod = 13;
|
||||
|
||||
state->synctype = 0;
|
||||
state->lastsynctype = 0;
|
||||
}
|
||||
|
||||
if (strncmp ("APCO25-PHASE2", str_buffer, 13) == 0)
|
||||
{
|
||||
//set AMBE+2 protocol here
|
||||
protocol = 2;
|
||||
|
||||
//rc4 dropbyte and key len mod
|
||||
rc4_db = 256;
|
||||
rc4_mod = 13;
|
||||
|
||||
state->synctype = 35;
|
||||
state->lastsynctype = 35;
|
||||
}
|
||||
|
||||
if (strncmp ("DMR", str_buffer, 3) == 0)
|
||||
{
|
||||
//set AMBE+2 protocol here
|
||||
protocol = 2;
|
||||
|
||||
//rc4 dropbyte and key len mod
|
||||
rc4_db = 256;
|
||||
rc4_mod = 9;
|
||||
|
||||
state->synctype = 10;
|
||||
state->lastsynctype = 10;
|
||||
}
|
||||
|
||||
//open .imb or .amb file, if desired, but only after setting a synctype
|
||||
if (state->synctype != -1)
|
||||
{
|
||||
//if converting to .amb or .imb, open that file format as well
|
||||
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
||||
openMbeOutFile (opts, state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (strncmp ("call_type", str_buffer, 9) == 0)
|
||||
{
|
||||
str_buffer = strtok(NULL, " : \""); //next value after any : "" string
|
||||
|
||||
//set gi value based on this
|
||||
if (strncmp ("GROUP", str_buffer, 5) == 0)
|
||||
gi = 0;
|
||||
else gi = 1;
|
||||
|
||||
state->gi[0] = gi;
|
||||
|
||||
//debug set value
|
||||
// fprintf (stderr, " GI: %d;", gi);
|
||||
|
||||
//debug print current str_buffer
|
||||
fprintf (stderr, "\n Call Type: %s", str_buffer);
|
||||
|
||||
}
|
||||
|
||||
if (strncmp ("encrypted", str_buffer, 9) == 0)
|
||||
{
|
||||
str_buffer = strtok(NULL, " : \""); //next value after any : "" string
|
||||
|
||||
//set enc value based on this
|
||||
if (strncmp ("true", str_buffer, 4) == 0)
|
||||
is_enc = 1;
|
||||
else is_enc = 0;
|
||||
|
||||
//reset other enc variables (filled in later on if available)
|
||||
alg_id = 0;
|
||||
key_id = 0;
|
||||
iv_hex = 0;
|
||||
|
||||
//debug set value
|
||||
// fprintf (stderr, " ENC: %d;", is_enc);
|
||||
|
||||
//debug print current str_buffer
|
||||
fprintf (stderr, "\n Encryption: %s", str_buffer);
|
||||
|
||||
}
|
||||
|
||||
if (strncmp ("to", str_buffer, 2) == 0)
|
||||
{
|
||||
str_buffer = strtok(NULL, " : \""); //next value after any : "" string
|
||||
|
||||
target = strtol (str_buffer, NULL, 10);
|
||||
|
||||
state->lasttg = target;
|
||||
|
||||
//debug set value
|
||||
// fprintf (stderr, " Target: %d;", target);
|
||||
|
||||
//debug print current str_buffer
|
||||
fprintf (stderr, "\n To: %s", str_buffer);
|
||||
|
||||
}
|
||||
|
||||
if (strncmp ("from", str_buffer, 4) == 0)
|
||||
{
|
||||
str_buffer = strtok(NULL, " : \""); //next value after any : "" string
|
||||
|
||||
source = strtol (str_buffer, NULL, 10);
|
||||
|
||||
state->lastsrc = source;
|
||||
|
||||
//debug set value
|
||||
// fprintf (stderr, " Source: %d;", source);
|
||||
|
||||
//debug print current str_buffer
|
||||
fprintf (stderr, "\n From: %s", str_buffer);
|
||||
|
||||
}
|
||||
|
||||
if (strncmp ("encryption_algorithm", str_buffer, 20) == 0)
|
||||
{
|
||||
str_buffer = strtok(NULL, " : \""); //next value after any : "" string
|
||||
|
||||
alg_id = strtol (str_buffer, NULL, 10);
|
||||
|
||||
//debug set value
|
||||
fprintf (stderr, "\n Alg ID: %02X;", alg_id);
|
||||
|
||||
//debug print current str_buffer
|
||||
// fprintf (stderr, "\n Encryption Alg: %s", str_buffer);
|
||||
|
||||
}
|
||||
|
||||
if (strncmp ("encryption_key_id", str_buffer, 17) == 0)
|
||||
{
|
||||
str_buffer = strtok(NULL, " : \""); //next value after any : "" string
|
||||
|
||||
key_id = strtol (str_buffer, NULL, 10);
|
||||
|
||||
//debug set value
|
||||
fprintf (stderr, "\n Key ID: %04X;", key_id);
|
||||
|
||||
//debug print current str_buffer
|
||||
// fprintf (stderr, "\n Encryption KID: %s", str_buffer);
|
||||
|
||||
}
|
||||
|
||||
if (strncmp ("encryption_mi", str_buffer, 13) == 0)
|
||||
{
|
||||
str_buffer = strtok(NULL, " : \""); //next value after any : "" string
|
||||
|
||||
uint16_t iv_len = strlen((const char*)str_buffer);
|
||||
char iv_str[20]; memset(iv_str, 0, sizeof(iv_str));
|
||||
|
||||
//debug this str_buffer len
|
||||
// fprintf (stderr, " IV STR LEN: %d;", iv_len);
|
||||
|
||||
if (iv_len == 18) //P25 MI has an extra zero byte (two zeroes) appended to MI, remove those
|
||||
iv_len = 16;
|
||||
strncpy(iv_str, str_buffer, iv_len); //copy out final IV value from the MI
|
||||
|
||||
iv_hex = strtoull (iv_str, NULL, 16); //Note: The 16 here is for base 16 (hex), not 16 chars
|
||||
|
||||
//debug set value
|
||||
fprintf (stderr, "\n IV: %016llX;", iv_hex); //not really needed if loaded into array
|
||||
|
||||
//debug print current str_buffer
|
||||
// fprintf (stderr, "\n Encryption MI/IV: %s", str_buffer);
|
||||
|
||||
//WIP: This is the last field of enc, so we create a new keystream here, if needed
|
||||
state->currentslot = 0;
|
||||
state->payload_algid = alg_id;
|
||||
state->payload_mi = iv_hex;
|
||||
state->payload_keyid = key_id;
|
||||
if (state->keyloader == 1)
|
||||
keyring(opts, state);
|
||||
|
||||
//TODO: Handle multi keystream creation with a new function
|
||||
uint8_t ks_bytes[375]; memset(ks_bytes, 0, sizeof(ks_bytes));
|
||||
uint8_t kiv[15]; memset(kiv, 0, sizeof(kiv));
|
||||
|
||||
//Test: Setup a simple RC4 for now (working)
|
||||
if ( (alg_id == 0xAA || alg_id == 0x21) && state->R != 0 )
|
||||
{
|
||||
|
||||
//load key into key portion of kiv
|
||||
kiv[0] = ((state->R & 0xFF00000000) >> 32);
|
||||
kiv[1] = ((state->R & 0xFF000000) >> 24);
|
||||
kiv[2] = ((state->R & 0xFF0000) >> 16);
|
||||
kiv[3] = ((state->R & 0xFF00) >> 8);
|
||||
kiv[4] = ((state->R & 0xFF) >> 0);
|
||||
|
||||
//load the str_buffer into the IV portion of kiv
|
||||
parse_raw_user_string(str_buffer, kiv+5);
|
||||
|
||||
rc4_block_output (rc4_db, rc4_mod, 375, kiv, ks_bytes);
|
||||
|
||||
unpack_byte_array_into_bit_array(ks_bytes, ks, 375);
|
||||
|
||||
} //end test
|
||||
|
||||
//reset ks_idx to 0
|
||||
ks_idx = 0;
|
||||
|
||||
}
|
||||
|
||||
if (strncmp ("hex", str_buffer, 3) == 0)
|
||||
{
|
||||
str_buffer = strtok(NULL, " : \""); //next value after any : "" string
|
||||
|
||||
if (protocol == 1) //P25p1 IMBE
|
||||
{
|
||||
//debug print current str_buffer
|
||||
// fprintf (stderr, "\n IMBE HEX: %s", str_buffer);
|
||||
|
||||
//36 hex characters on 'hex' which is the IMBE interleaved C codewords
|
||||
ks_idx = imbe_str_to_decode(opts, state, str_buffer, ks, ks_idx);
|
||||
}
|
||||
else if (protocol == 2) //P25p2 AMBE
|
||||
{
|
||||
//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);
|
||||
}
|
||||
}
|
||||
|
||||
if (strncmp ("time", str_buffer, 4) == 0)
|
||||
{
|
||||
str_buffer = strtok(NULL, " : \""); //next value after any : "" string
|
||||
|
||||
char time_str[20]; memset(time_str, 0, sizeof(time_str));
|
||||
strncpy(time_str, str_buffer, 10); //full string is 13, but not copying milliseconds to match time(NULL)
|
||||
|
||||
event_time = strtol (time_str, NULL, 10);
|
||||
|
||||
//working now with tweak
|
||||
state->event_history_s[0].Event_History_Items[0].event_time = event_time;
|
||||
|
||||
//debug set value
|
||||
// fprintf (stderr, " Time: %ld;", event_time);
|
||||
|
||||
//what is actual time_t for time(NULL);
|
||||
// fprintf (stderr, " Time(NULL): %ld;", time(NULL));
|
||||
|
||||
//convert to legible time and date format
|
||||
char * timestr = getTimeN(event_time); UNUSED(timestr);
|
||||
char * datestr = getDateN(event_time); UNUSED(datestr);
|
||||
|
||||
//user legible time
|
||||
fprintf (stderr, " Date: %s Time: %s;", datestr, timestr);
|
||||
|
||||
if (timestr != NULL)
|
||||
{
|
||||
free (timestr);
|
||||
timestr = NULL;
|
||||
}
|
||||
if (datestr != NULL)
|
||||
{
|
||||
free (datestr);
|
||||
datestr = NULL;
|
||||
}
|
||||
|
||||
//debug print current str_buffer
|
||||
// fprintf (stderr, "\n Time: %s", str_buffer);
|
||||
|
||||
}
|
||||
|
||||
str_buffer = strtok(NULL, " : \""); //next value after any : "" string
|
||||
|
||||
if (str_buffer == NULL)
|
||||
break;
|
||||
|
||||
//exit loop if signal
|
||||
if (exitflag == 1)
|
||||
break;
|
||||
}
|
||||
|
||||
//free allocated memory from the source string
|
||||
if (source_str != NULL)
|
||||
{
|
||||
free (source_str);
|
||||
source_str = NULL;
|
||||
}
|
||||
|
||||
//watchdog for event history
|
||||
watchdog_event_history(opts, state, 0);
|
||||
watchdog_event_current(opts, state, 0);
|
||||
|
||||
//if .imb or .amb file open, close it now
|
||||
if (opts->mbe_out_f != NULL)
|
||||
closeMbeOutFile (opts, state);
|
||||
|
||||
//end line break
|
||||
fprintf (stderr, "\n");
|
||||
|
||||
}
|
||||
@@ -1412,7 +1412,7 @@
|
||||
printf (" -n <float> Audio Analog Output Gain (Default: 0 = Auto; 0-100%% )\n");
|
||||
//printf (" -w <file> Output synthesized speech to a .wav file, FDMA modes only.\n"); //disabled
|
||||
printf (" -6 <file> Output raw audio .wav file (48K/1). (WARNING! Large File Sizes 1 Hour ~= 360 MB)\n");
|
||||
printf (" -7 <dir> Create/Use Custom directory for Per Call decoded .wav file saving.\n");
|
||||
// printf (" -7 <dir> Create/Use Custom directory for Per Call decoded .wav file saving.\n"); //disabled
|
||||
printf (" (Use ./folder for Nested Directory!)\n");
|
||||
printf (" (Use /path/to/folder for hard coded directory!)\n");
|
||||
printf (" (Use Before the -P option!)\n");
|
||||
@@ -2223,17 +2223,17 @@
|
||||
fprintf (stderr,"Writing + Appending Event History to file %s\n", opts.event_out_file);
|
||||
break;
|
||||
|
||||
case '7': //make a custom wav file directory in the current working directory -- use this before -P
|
||||
strncpy(opts.wav_out_dir, optarg, 511);
|
||||
opts.wav_out_dir[511] = '\0';
|
||||
if (stat(opts.wav_out_dir, &st) == -1)
|
||||
{
|
||||
fprintf (stderr, "%s directory does not exist\n", opts.wav_out_dir);
|
||||
fprintf (stderr, "Creating directory %s to save wav files\n", opts.wav_out_dir);
|
||||
mkdir(opts.wav_out_dir, 0700);
|
||||
}
|
||||
else fprintf (stderr,"Writing wav decoded audio files to directory %s\n", opts.wav_out_dir);
|
||||
break;
|
||||
// case '7': //make a custom wav file directory in the current working directory -- use this before -P
|
||||
// strncpy(opts.wav_out_dir, optarg, 511);
|
||||
// opts.wav_out_dir[511] = '\0';
|
||||
// if (stat(opts.wav_out_dir, &st) == -1)
|
||||
// {
|
||||
// fprintf (stderr, "%s directory does not exist\n", opts.wav_out_dir);
|
||||
// fprintf (stderr, "Creating directory %s to save wav files\n", opts.wav_out_dir);
|
||||
// mkdir(opts.wav_out_dir, 0700);
|
||||
// }
|
||||
// else fprintf (stderr,"Writing wav decoded audio files to directory %s\n", opts.wav_out_dir);
|
||||
// break;
|
||||
|
||||
case 'P': //Per Call Wav Files
|
||||
sprintf (wav_file_directory, "%s", opts.wav_out_dir);
|
||||
|
||||
@@ -68,6 +68,7 @@ void playMbeFiles (dsd_opts * opts, dsd_state * state, int argc, char **argv)
|
||||
int i;
|
||||
char imbe_d[88];
|
||||
char ambe_d[49];
|
||||
srand(time(NULL)); //random seed for some file names using random numbers in file name
|
||||
|
||||
for (i = state->optind; i < argc; i++)
|
||||
{
|
||||
@@ -100,6 +101,10 @@ void playMbeFiles (dsd_opts * opts, dsd_state * state, int argc, char **argv)
|
||||
playSynthesizedVoiceFM (opts, state);
|
||||
}
|
||||
}
|
||||
else if (state->mbe_file_type == 3)
|
||||
{
|
||||
read_sdrtrunk_json_format (opts, state);
|
||||
}
|
||||
else if (state->mbe_file_type > 0) //ambe files
|
||||
{
|
||||
readAmbe2450Data (opts, state, ambe_d);
|
||||
|
||||
@@ -79,3 +79,20 @@ char * getDateN(time_t t)
|
||||
return curr;
|
||||
}
|
||||
|
||||
//get HHmmss timestamp no colon (file operations)
|
||||
char * getTimeF(time_t t)
|
||||
{
|
||||
char * curr = calloc(7, sizeof(char));
|
||||
struct tm * ptm = localtime(& t);
|
||||
sprintf(curr,"%02d%02d%02d", ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
|
||||
return curr;
|
||||
}
|
||||
|
||||
//get YYYYMMDD without hyphen (file operations)
|
||||
char * getDateF(time_t t)
|
||||
{
|
||||
char * curr = calloc(25, sizeof(char));
|
||||
struct tm * ptm = localtime(& t);
|
||||
sprintf(curr,"%04d%02d%02d", ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday);
|
||||
return curr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user