mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-14 09:47:30 -05:00
New Event History Setup and Logging to a Log File, part 1; #186
This commit is contained in:
@@ -88,6 +88,34 @@
|
|||||||
|
|
||||||
extern volatile uint8_t exitflag; //fix for issue #136
|
extern volatile uint8_t exitflag; //fix for issue #136
|
||||||
|
|
||||||
|
//event history (each item)
|
||||||
|
typedef struct {
|
||||||
|
uint8_t write; //if this event needs to be written to a log file
|
||||||
|
int8_t systype; //indentifier of which decoded system type this is from (P25, DMR, etc)
|
||||||
|
int8_t subtype; //subtype of systpe (VLC, TLC, PDU data, System Event, etc)
|
||||||
|
uint8_t gi; //group or individual
|
||||||
|
uint8_t enc; //clear or encrypted
|
||||||
|
uint8_t enc_alg; //alg if encrypted
|
||||||
|
uint16_t enc_key; //enc key id value, if encrypted (not key value or key variable)
|
||||||
|
uint64_t mi; //mi, or iv base value from OTA if provided
|
||||||
|
uint16_t svc; //other relevant svc opts if applicable
|
||||||
|
uint32_t source_id;//source radio id or other source value
|
||||||
|
uint32_t target_id;//group or individual target, or destination value
|
||||||
|
uint32_t channel; //if this occurs on a trunking channel, which channel
|
||||||
|
time_t event_time; //time event occurred
|
||||||
|
|
||||||
|
uint8_t pdu[128*24]; //relevant link control, or full PDU if data call (in bytes)
|
||||||
|
char alias[2000]; //if this event has a source radio talker alias or similar
|
||||||
|
char gps_s[2000]; //gps, if returned, expressed as a string
|
||||||
|
char text_message[2000]; //if this event is a decoded text message, then it goes here
|
||||||
|
char event_string[2000]; //user legible and printable string for the event that happened
|
||||||
|
} Event_History;
|
||||||
|
|
||||||
|
//event history for number of each items above
|
||||||
|
typedef struct {
|
||||||
|
Event_History Event_History_Items[255];
|
||||||
|
} Event_History_I;
|
||||||
|
|
||||||
//new audio filter stuff from: https://github.com/NedSimao/FilteringLibrary
|
//new audio filter stuff from: https://github.com/NedSimao/FilteringLibrary
|
||||||
typedef struct {
|
typedef struct {
|
||||||
float coef[2];
|
float coef[2];
|
||||||
@@ -280,6 +308,7 @@ typedef struct
|
|||||||
char wav_out_file_raw[1024];
|
char wav_out_file_raw[1024];
|
||||||
char symbol_out_file[1024];
|
char symbol_out_file[1024];
|
||||||
char lrrp_out_file[1024];
|
char lrrp_out_file[1024];
|
||||||
|
char event_out_file[1024];
|
||||||
char szNumbers[1024]; //**tera 10/32/64 char str
|
char szNumbers[1024]; //**tera 10/32/64 char str
|
||||||
short int mbe_out; //flag for mbe out, don't attempt fclose more than once
|
short int mbe_out; //flag for mbe out, don't attempt fclose more than once
|
||||||
short int mbe_outR; //flag for mbe out, don't attempt fclose more than once
|
short int mbe_outR; //flag for mbe out, don't attempt fclose more than once
|
||||||
@@ -546,6 +575,8 @@ typedef struct
|
|||||||
int lasttgR;
|
int lasttgR;
|
||||||
int lastsrc;
|
int lastsrc;
|
||||||
int lastsrcR;
|
int lastsrcR;
|
||||||
|
uint8_t gi[2]; //group, or private call, per slot
|
||||||
|
uint8_t eh_index;
|
||||||
int nac;
|
int nac;
|
||||||
int errs;
|
int errs;
|
||||||
int errs2;
|
int errs2;
|
||||||
@@ -688,8 +719,8 @@ typedef struct
|
|||||||
uint8_t dmr_alias_format[2]; //per slot
|
uint8_t dmr_alias_format[2]; //per slot
|
||||||
uint8_t dmr_alias_len[2]; //per slot
|
uint8_t dmr_alias_len[2]; //per slot
|
||||||
char dmr_alias_block_segment[2][4][7][16]; //2 slots, by 4 blocks, by up to 7 alias bytes that are up to 16-bit chars
|
char dmr_alias_block_segment[2][4][7][16]; //2 slots, by 4 blocks, by up to 7 alias bytes that are up to 16-bit chars
|
||||||
char dmr_embedded_gps[2][200]; //2 slots by 99 char string for string embedded gps
|
char dmr_embedded_gps[2][600]; //2 slots by 99 char string for string embedded gps
|
||||||
char dmr_lrrp_gps[2][200]; //2 slots by 99 char string for string lrrp gps
|
char dmr_lrrp_gps[2][600]; //2 slots by 99 char string for string lrrp gps
|
||||||
char dmr_site_parms[200]; //string for site/net info depending on type of DMR system (TIII or Con+)
|
char dmr_site_parms[200]; //string for site/net info depending on type of DMR system (TIII or Con+)
|
||||||
char call_string[2][200]; //string for call information
|
char call_string[2][200]; //string for call information
|
||||||
char active_channel[31][200]; //string for storing and displaying active trunking channels
|
char active_channel[31][200]; //string for storing and displaying active trunking channels
|
||||||
@@ -699,6 +730,9 @@ typedef struct
|
|||||||
|
|
||||||
dPMRVoiceFS2Frame_t dPMRVoiceFS2Frame;
|
dPMRVoiceFS2Frame_t dPMRVoiceFS2Frame;
|
||||||
|
|
||||||
|
//event history itemized per slot
|
||||||
|
Event_History_I event_history_s[2];
|
||||||
|
|
||||||
//new audio filter structs
|
//new audio filter structs
|
||||||
LPFilter RCFilter;
|
LPFilter RCFilter;
|
||||||
HPFilter HRCFilter;
|
HPFilter HRCFilter;
|
||||||
@@ -1354,6 +1388,14 @@ char * getDateH();
|
|||||||
char * getDateS();
|
char * getDateS();
|
||||||
char * getDateN(time_t t);
|
char * getDateN(time_t t);
|
||||||
|
|
||||||
|
//event history functions
|
||||||
|
void init_event_history (Event_History_I * event_struct, uint8_t start, uint8_t stop);
|
||||||
|
void push_event_history (Event_History_I * event_struct);
|
||||||
|
void write_event_to_log_file (dsd_opts * opts, dsd_state * state, char * event_string);
|
||||||
|
void watchdog_event_history (dsd_opts * opts, dsd_state * state, uint8_t slot);
|
||||||
|
void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot);
|
||||||
|
void watchdog_event_datacall (dsd_opts * opts, dsd_state * state, uint32_t src, uint32_t dst, char * data_string, uint8_t slot);
|
||||||
|
|
||||||
//dmr alg stuff
|
//dmr alg stuff
|
||||||
void dmr_alg_reset (dsd_opts * opts, dsd_state * state);
|
void dmr_alg_reset (dsd_opts * opts, dsd_state * state);
|
||||||
void dmr_alg_refresh (dsd_opts * opts, dsd_state * state);
|
void dmr_alg_refresh (dsd_opts * opts, dsd_state * state);
|
||||||
|
|||||||
@@ -1050,8 +1050,12 @@ void dmr_block_assembler (dsd_opts * opts, dsd_state * state, uint8_t block_byte
|
|||||||
if (enc_check == 1 && decrypted_pdu == 0) //check for encryption and if it was decrypted first or not
|
if (enc_check == 1 && decrypted_pdu == 0) //check for encryption and if it was decrypted first or not
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s", KRED);
|
fprintf (stderr, "%s", KRED);
|
||||||
fprintf (stderr, "\n Slot %d - Encrypted Data Packet;", slot+1);
|
fprintf (stderr, "\n Slot %d - Encrypted PDU;", slot+1);
|
||||||
fprintf (stderr, "%s", KNRM);
|
fprintf (stderr, "%s", KNRM);
|
||||||
|
|
||||||
|
char enc_str[200]; memset (enc_str, 200, sizeof(enc_str));
|
||||||
|
sprintf (enc_str, "DATA TGT: %d; SRC: %d; Encrypted PDU;", state->dmr_lrrp_source[slot], state->dmr_lrrp_target[slot]);
|
||||||
|
watchdog_event_datacall (opts, state, state->dmr_lrrp_source[slot], state->dmr_lrrp_target[slot], enc_str, slot);
|
||||||
}
|
}
|
||||||
else if (CRCCorrect || opts->aggressive_framesync == 0)
|
else if (CRCCorrect || opts->aggressive_framesync == 0)
|
||||||
{
|
{
|
||||||
@@ -1108,6 +1112,19 @@ void dmr_block_assembler (dsd_opts * opts, dsd_state * state, uint8_t block_byte
|
|||||||
else if (mnis_type == 0x33) //check any potential texts in this message
|
else if (mnis_type == 0x33) //check any potential texts in this message
|
||||||
utf8_to_text(state, 0, 15, state->dmr_pdu_sf[slot]+7); //seen some ARS radio IDs in ASCII/ISO7/UTF8 format here
|
utf8_to_text(state, 0, 15, state->dmr_pdu_sf[slot]+7); //seen some ARS radio IDs in ASCII/ISO7/UTF8 format here
|
||||||
|
|
||||||
|
if (mnis_type != 0x11)
|
||||||
|
{
|
||||||
|
char mnis_str[200]; memset (mnis_str, 200, sizeof(mnis_str));
|
||||||
|
sprintf (mnis_str, "MNIS TGT: %d; SRC: %d;", state->dmr_lrrp_source[slot], state->dmr_lrrp_target[slot]);
|
||||||
|
watchdog_event_datacall (opts, state, state->dmr_lrrp_source[slot], state->dmr_lrrp_target[slot], mnis_str, slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char unk_str[200]; memset (unk_str, 200, sizeof(unk_str));
|
||||||
|
sprintf (unk_str, "DATA TGT: %d; SRC: %d; Unknown PDU Format;", state->dmr_lrrp_source[slot], state->dmr_lrrp_target[slot]);
|
||||||
|
watchdog_event_datacall (opts, state, state->dmr_lrrp_source[slot], state->dmr_lrrp_target[slot], unk_str, slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -584,6 +584,14 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
|||||||
ncursesPrinter(opts, state);
|
ncursesPrinter(opts, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//slot 1
|
||||||
|
watchdog_event_history(opts, state, 0);
|
||||||
|
watchdog_event_current(opts, state, 0);
|
||||||
|
|
||||||
|
//slot 2 for TDMA systems
|
||||||
|
watchdog_event_history(opts, state, 1);
|
||||||
|
watchdog_event_current(opts, state, 1);
|
||||||
|
|
||||||
//
|
//
|
||||||
if (timestr != NULL)
|
if (timestr != NULL)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -402,8 +402,8 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C
|
|||||||
{
|
{
|
||||||
state->dmr_fid = 0;
|
state->dmr_fid = 0;
|
||||||
state->dmr_so = 0;
|
state->dmr_so = 0;
|
||||||
// state->lasttg = 0;
|
state->lasttg = 0;
|
||||||
// state->lastsrc = 0;
|
state->lastsrc = 0;
|
||||||
state->payload_algid = 0;
|
state->payload_algid = 0;
|
||||||
state->payload_mi = 0;
|
state->payload_mi = 0;
|
||||||
state->payload_keyid = 0;
|
state->payload_keyid = 0;
|
||||||
@@ -415,8 +415,8 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C
|
|||||||
{
|
{
|
||||||
state->dmr_fidR = 0;
|
state->dmr_fidR = 0;
|
||||||
state->dmr_soR = 0;
|
state->dmr_soR = 0;
|
||||||
// state->lasttgR = 0;
|
state->lasttgR = 0;
|
||||||
// state->lastsrcR = 0;
|
state->lastsrcR = 0;
|
||||||
state->payload_algidR = 0;
|
state->payload_algidR = 0;
|
||||||
state->payload_miR = 0;
|
state->payload_miR = 0;
|
||||||
state->payload_keyidR = 0;
|
state->payload_keyidR = 0;
|
||||||
|
|||||||
@@ -310,6 +310,10 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
|
|||||||
ncursesPrinter(opts, state);
|
ncursesPrinter(opts, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//slot 1
|
||||||
|
watchdog_event_history(opts, state, 0);
|
||||||
|
watchdog_event_current(opts, state, 0);
|
||||||
|
|
||||||
} // end loop
|
} // end loop
|
||||||
|
|
||||||
END:
|
END:
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ uint16_t convert_hex_to_dec(uint16_t input)
|
|||||||
void utf16_to_text (dsd_state * state, uint8_t wr, uint16_t len, uint8_t * input)
|
void utf16_to_text (dsd_state * state, uint8_t wr, uint16_t len, uint8_t * input)
|
||||||
{
|
{
|
||||||
uint8_t slot = state->currentslot;
|
uint8_t slot = state->currentslot;
|
||||||
|
sprintf (state->event_history_s[slot].Event_History_Items[0].text_message, "%s", "Full Text: "); //full text string
|
||||||
// fprintf (stderr, "\n UTF16 Text: ");
|
// fprintf (stderr, "\n UTF16 Text: ");
|
||||||
uint16_t ch16 = 0;
|
uint16_t ch16 = 0;
|
||||||
for (uint16_t i = 0; i < len; i += 2)
|
for (uint16_t i = 0; i < len; i += 2)
|
||||||
@@ -43,9 +44,14 @@ void utf16_to_text (dsd_state * state, uint8_t wr, uint16_t len, uint8_t * input
|
|||||||
//for now, just rip the first 40 or so chars lower byte value
|
//for now, just rip the first 40 or so chars lower byte value
|
||||||
//in the ASCII Range (should be alright for a quick visual)
|
//in the ASCII Range (should be alright for a quick visual)
|
||||||
char c[2]; c[0] = (char)input[i+1]; c[2] = 0;
|
char c[2]; c[0] = (char)input[i+1]; c[2] = 0;
|
||||||
if (wr == 1&& i < 76 && input[i+1] < 0x7F && input[i+1] >= 0x20)
|
if (wr == 1 && i < 76 && input[i+1] < 0x7F && input[i+1] >= 0x20)
|
||||||
strcat (state->dmr_lrrp_gps[slot], c);
|
strcat (state->dmr_lrrp_gps[slot], c);
|
||||||
|
|
||||||
|
//this is the long version, complete message for logging purposes
|
||||||
|
if (wr == 1 && input[i+1] < 0x7F && input[i+1] >= 0x20)
|
||||||
|
// if (wr == 1)
|
||||||
|
strcat (state->event_history_s[slot].Event_History_Items[0].text_message, c);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//add elipses to indicate this is possibly truncated
|
//add elipses to indicate this is possibly truncated
|
||||||
@@ -104,6 +110,11 @@ void dmr_sd_pdu (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t * DMR
|
|||||||
// utf16_to_text(state, 0, len, DMR_PDU); //generic catch-all to see if anything relevant is there
|
// utf16_to_text(state, 0, len, DMR_PDU); //generic catch-all to see if anything relevant is there
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: This
|
||||||
|
// char comp_string[500]; memset (comp_string, 0, sizeof(comp_string));
|
||||||
|
// sprintf (comp_string, "Src Port Idx: %d (%s); Dst Port Idx: %d (%s); ", spid, portstring[0], dpid, portstring[1]);
|
||||||
|
// watchdog_event_datacall (opts, state, said, daid, comp_string, slot);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//reading ETSI, seems like these aren't compressed, just that they are preset indexed values on the radio
|
//reading ETSI, seems like these aren't compressed, just that they are preset indexed values on the radio
|
||||||
@@ -235,6 +246,14 @@ void dmr_udp_comp_pdu (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t
|
|||||||
}
|
}
|
||||||
else fprintf (stderr, "Unknown Decode Format;");
|
else fprintf (stderr, "Unknown Decode Format;");
|
||||||
|
|
||||||
|
uint8_t slot = 0;
|
||||||
|
if (state->currentslot == 1)
|
||||||
|
slot = 1;
|
||||||
|
|
||||||
|
char comp_string[500]; memset (comp_string, 0, sizeof(comp_string));
|
||||||
|
sprintf (comp_string, "Src Port Idx: %d (%s); Dst Port Idx: %d (%s); ", spid, portstring[0], dpid, portstring[1]);
|
||||||
|
watchdog_event_datacall (opts, state, said, daid, comp_string, slot);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//IP PDU header decode and port forward to appropriate decoder
|
//IP PDU header decode and port forward to appropriate decoder
|
||||||
@@ -459,7 +478,7 @@ void decode_ip_pdu (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t *
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf (state->dmr_lrrp_gps[slot], " IP Call SRC: %d; Port; %d; DST: %d; Port: %d;", src24, port1, dst24, port2);
|
sprintf (state->dmr_lrrp_gps[slot], "IP SRC: %d.%d.%d.%d:%d; DST: %d.%d.%d.%d:%d;", input[12], input[13], input[14], input[15], port1, input[16], input[17], input[18], input[19], port2);
|
||||||
fprintf (stderr, "Unknown UDP Port;");
|
fprintf (stderr, "Unknown UDP Port;");
|
||||||
// if (len > 28) //default catch all (debug only)
|
// if (len > 28) //default catch all (debug only)
|
||||||
// utf8_to_text(state, 0, len-28, input+28);
|
// utf8_to_text(state, 0, len-28, input+28);
|
||||||
@@ -470,13 +489,15 @@ void decode_ip_pdu (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t *
|
|||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf (state->dmr_lrrp_gps[slot], " IP Call SRC: %d; DST: %d; Protocol: %d;", src24, dst24, prot);
|
sprintf (state->dmr_lrrp_gps[slot], "IP SRC: %d; DST: %d; Protocol: %d;", input[12], input[13], input[14], input[15], input[16], input[17], input[18], input[19], prot);
|
||||||
fprintf(stderr, "Unknown IP Protocol: %02X;", prot);
|
fprintf(stderr, "Unknown IP Protocol: %02X;", prot);
|
||||||
// if (len > 28) //default catch all (debug only)
|
// if (len > 28) //default catch all (debug only)
|
||||||
// utf8_to_text(state, 0, len-28, input+28);
|
// utf8_to_text(state, 0, len-28, input+28);
|
||||||
// else utf8_to_text(state, 0, len, input+28);
|
// else utf8_to_text(state, 0, len, input+28);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watchdog_event_datacall (opts, state, src24, dst24, state->dmr_lrrp_gps[slot], slot);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//The contents of this function are mostly trial and error
|
//The contents of this function are mostly trial and error
|
||||||
@@ -745,6 +766,7 @@ void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint16_t len, uint32_t source
|
|||||||
sprintf (velstr, "%s", "");
|
sprintf (velstr, "%s", "");
|
||||||
sprintf (degstr, "%s", "");
|
sprintf (degstr, "%s", "");
|
||||||
if (lat) sprintf (lrrpstr, "LRRP SRC: %0d; (%lf, %lf)", source, lat_fin, lon_fin);
|
if (lat) sprintf (lrrpstr, "LRRP SRC: %0d; (%lf, %lf)", source, lat_fin, lon_fin);
|
||||||
|
else sprintf (lrrpstr, "LRRP SRC: %0d; Unknown Format; ", source);
|
||||||
if (vel_set) sprintf (velstr, " %.4lf km/h", velocity * 3.6);
|
if (vel_set) sprintf (velstr, " %.4lf km/h", velocity * 3.6);
|
||||||
if (deg_set) sprintf (degstr, " %d%s ", degrees, deg_glyph);
|
if (deg_set) sprintf (degstr, " %d%s ", degrees, deg_glyph);
|
||||||
sprintf (state->dmr_lrrp_gps[slot], "%s%s%s", lrrpstr, velstr, degstr);
|
sprintf (state->dmr_lrrp_gps[slot], "%s%s%s", lrrpstr, velstr, degstr);
|
||||||
|
|||||||
@@ -230,6 +230,14 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
|||||||
ncursesPrinter(opts, state);
|
ncursesPrinter(opts, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//slot 1
|
||||||
|
watchdog_event_history(opts, state, 0);
|
||||||
|
watchdog_event_current(opts, state, 0);
|
||||||
|
|
||||||
|
//slot 2 for TDMA systems
|
||||||
|
watchdog_event_history(opts, state, 1);
|
||||||
|
watchdog_event_current(opts, state, 1);
|
||||||
|
|
||||||
if ((opts->symboltiming == 1) && (state->carrier == 1))
|
if ((opts->symboltiming == 1) && (state->carrier == 1))
|
||||||
{
|
{
|
||||||
//fprintf (stderr,"\nSymbol Timing:\n");
|
//fprintf (stderr,"\nSymbol Timing:\n");
|
||||||
|
|||||||
@@ -265,6 +265,8 @@ noCarrier (dsd_opts * opts, dsd_state * state)
|
|||||||
state->lastsrc = 0;
|
state->lastsrc = 0;
|
||||||
state->lasttgR = 0;
|
state->lasttgR = 0;
|
||||||
state->lastsrcR = 0;
|
state->lastsrcR = 0;
|
||||||
|
state->gi[0] = 0;
|
||||||
|
state->gi[1] = 0;
|
||||||
|
|
||||||
//zero out vc frequencies?
|
//zero out vc frequencies?
|
||||||
state->p25_vc_freq[0] = 0;
|
state->p25_vc_freq[0] = 0;
|
||||||
@@ -301,6 +303,8 @@ noCarrier (dsd_opts * opts, dsd_state * state)
|
|||||||
state->lastsrc = 0;
|
state->lastsrc = 0;
|
||||||
state->lasttgR = 0;
|
state->lasttgR = 0;
|
||||||
state->lastsrcR = 0;
|
state->lastsrcR = 0;
|
||||||
|
state->gi[0] = 0;
|
||||||
|
state->gi[1] = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,6 +628,7 @@ initOpts (dsd_opts * opts)
|
|||||||
opts->wav_out_file_raw[0] = 0;
|
opts->wav_out_file_raw[0] = 0;
|
||||||
opts->symbol_out_file[0] = 0;
|
opts->symbol_out_file[0] = 0;
|
||||||
opts->lrrp_out_file[0] = 0;
|
opts->lrrp_out_file[0] = 0;
|
||||||
|
opts->event_out_file[0] = 0;
|
||||||
//csv import filenames
|
//csv import filenames
|
||||||
opts->group_in_file[0] = 0;
|
opts->group_in_file[0] = 0;
|
||||||
opts->lcn_in_file[0] = 0;
|
opts->lcn_in_file[0] = 0;
|
||||||
@@ -942,6 +947,9 @@ initState (dsd_state * state)
|
|||||||
state->lastsrc = 0;
|
state->lastsrc = 0;
|
||||||
state->lasttgR = 0;
|
state->lasttgR = 0;
|
||||||
state->lastsrcR = 0;
|
state->lastsrcR = 0;
|
||||||
|
state->gi[0] = 0;
|
||||||
|
state->gi[1] = 0;
|
||||||
|
state->eh_index = 0;
|
||||||
state->nac = 0;
|
state->nac = 0;
|
||||||
state->errs = 0;
|
state->errs = 0;
|
||||||
state->errs2 = 0;
|
state->errs2 = 0;
|
||||||
@@ -1313,6 +1321,10 @@ initState (dsd_state * state)
|
|||||||
|
|
||||||
state->dmr_color_code = 16;
|
state->dmr_color_code = 16;
|
||||||
|
|
||||||
|
//initialize event history items (0 to 255)
|
||||||
|
for (uint8_t i = 0; i < 2; i++)
|
||||||
|
init_event_history(&state->event_history_s[i], 0, 255);
|
||||||
|
|
||||||
} //init_state
|
} //init_state
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1779,7 +1791,7 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
exitflag = 0;
|
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:WrlZTF01:2:345:6:7:89Ek:I:JO")) != -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:WrlZTF01:2:345:6:7:89Ek:I:JO")) != -1)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (c)
|
switch (c)
|
||||||
@@ -2142,6 +2154,12 @@ main (int argc, char **argv)
|
|||||||
fprintf (stderr,"Writing + Appending LRRP data to file %s\n", opts.lrrp_out_file);
|
fprintf (stderr,"Writing + Appending LRRP data to file %s\n", opts.lrrp_out_file);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case '~': //Event output to file
|
||||||
|
strncpy(opts.event_out_file, optarg, 1023);
|
||||||
|
opts.event_out_file[1023] = '\0';
|
||||||
|
fprintf (stderr,"Writing + Appending Event History to file %s\n", opts.lrrp_out_file);
|
||||||
|
break;
|
||||||
|
|
||||||
case '7': //make a custom wav file directory in the current working directory -- use this before -P
|
case '7': //make a custom wav file directory in the current working directory -- use this before -P
|
||||||
strncpy(opts.wav_out_dir, optarg, 511);
|
strncpy(opts.wav_out_dir, optarg, 511);
|
||||||
opts.wav_out_dir[511] = '\0';
|
opts.wav_out_dir[511] = '\0';
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ struct stat st_wav = {0};
|
|||||||
static char alias_ch[10][50];
|
static char alias_ch[10][50];
|
||||||
int reset = 0;
|
int reset = 0;
|
||||||
|
|
||||||
|
uint8_t eh_slot = 0; //testing only, have a toggle slot for history
|
||||||
|
uint8_t eh_off = 0; //testing only, index offset for scrolling history
|
||||||
|
|
||||||
int tg;
|
int tg;
|
||||||
int tgR;
|
int tgR;
|
||||||
@@ -59,24 +61,24 @@ char * FM_bannerN[9] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
char * SyncTypes[44] = {
|
char * SyncTypes[44] = {
|
||||||
"P25P1",
|
"P25p1",
|
||||||
"P25P1",
|
"P25p1",
|
||||||
"X2TDMA DATA",
|
"X2TDMA DATA",
|
||||||
"X2TDMA DATA",
|
"X2TDMA DATA",
|
||||||
"X2TDMA VOICE",
|
"X2TDMA VOICE",
|
||||||
"X2TDMA VOICE",
|
"X2TDMA VOICE",
|
||||||
"DSTAR", //voice
|
"DSTAR", //voice
|
||||||
"DSTAR", //voice
|
"DSTAR", //voice
|
||||||
"NXDN VOICE",
|
"M17",
|
||||||
"NXDN VOICE",
|
"M17",
|
||||||
"DMR", //10
|
"DMR", //10
|
||||||
"DMR",
|
"DMR",
|
||||||
"DMR",
|
"DMR",
|
||||||
"DMR",
|
"DMR",
|
||||||
"EDACS/PV",
|
"EDACS/PV",
|
||||||
"EDACS/PV",
|
"EDACS/PV",
|
||||||
"NXDN VOICE", //DATA
|
"M17 STR", //M17 Voice Stream
|
||||||
"NXDN VOICE", //DATA
|
"M17 STR", //M17 Voice Stream
|
||||||
"DSTAR", //header
|
"DSTAR", //header
|
||||||
"DSTAR", //header
|
"DSTAR", //header
|
||||||
"dPMR", //20
|
"dPMR", //20
|
||||||
@@ -94,12 +96,12 @@ char * SyncTypes[44] = {
|
|||||||
"DMR",
|
"DMR",
|
||||||
"DMR",
|
"DMR",
|
||||||
"DMR",
|
"DMR",
|
||||||
"P25P2",
|
"P25p2",
|
||||||
"P25P2",
|
"P25p2",
|
||||||
"EDACS/PV", //37
|
"EDACS/PV", //37
|
||||||
"EDACS/PV", //38
|
"EDACS/PV", //38
|
||||||
"",
|
"ANALOG", //39 Generic Sync Types
|
||||||
""
|
"DIGITAL" //40 Generic Sync Types
|
||||||
};
|
};
|
||||||
|
|
||||||
char * DMRBusrtTypes[32] = {
|
char * DMRBusrtTypes[32] = {
|
||||||
@@ -3823,7 +3825,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printw ("| Monitoring VC - LCN [%02d]", state->edacs_tuned_lcn);
|
printw ("| Monitoring VC - LCN [%02d]\n", state->edacs_tuned_lcn);
|
||||||
//since we are tuned, keep updating the time so it doesn't disappear during call
|
//since we are tuned, keep updating the time so it doesn't disappear during call
|
||||||
call_matrix[state->edacs_tuned_lcn][5] = time(NULL);
|
call_matrix[state->edacs_tuned_lcn][5] = time(NULL);
|
||||||
}
|
}
|
||||||
@@ -4003,233 +4005,23 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||||||
if (opts->ncurses_history == 1)
|
if (opts->ncurses_history == 1)
|
||||||
{
|
{
|
||||||
attron(COLOR_PAIR(4)); //cyan for history
|
attron(COLOR_PAIR(4)); //cyan for history
|
||||||
printw ("--Call History----------------------------------------------------------------\n");
|
printw ("--Latest Event History ([|])---Slot %d (\\)-------------------------------------\n", eh_slot+1);
|
||||||
for (short int j = 0; j < 10; j++)
|
for (uint8_t i = (state->eh_index+1); i < (state->eh_index+11); i++)
|
||||||
{
|
{
|
||||||
//only print if a valid time was assigned to the matrix, and not EDACS/PV, and source is not zero
|
char text_string[2000];
|
||||||
if ( ((time(NULL) - call_matrix[9-j][5]) < 999999) && call_matrix[9-j][0] != 14 && call_matrix[9-j][0] != 15 && call_matrix[9-j][0] != 37 && call_matrix[9-j][0] != 38 && call_matrix[9-j][2] != 0) //
|
sprintf (text_string, "%s", "BUMBLEBEETUNA");
|
||||||
|
uint8_t slot = eh_slot;
|
||||||
|
|
||||||
|
if (strncmp(text_string, state->event_history_s[slot].Event_History_Items[i].event_string, 13) != 0)
|
||||||
{
|
{
|
||||||
char * timestrCH = getTimeN(call_matrix[9-j][5]);
|
memcpy(text_string, state->event_history_s[slot].Event_History_Items[i].event_string, 71*sizeof(char));
|
||||||
char * datestrCH = getDateN(call_matrix[9-j][5]);
|
text_string[71] = 0; //terminate string
|
||||||
|
printw ("| #%02d %s \n", i, text_string);
|
||||||
printw ("| ");
|
|
||||||
printw ("%s ", datestrCH);
|
|
||||||
printw ("%s ", timestrCH);
|
|
||||||
|
|
||||||
if (datestrCH != NULL)
|
|
||||||
{
|
|
||||||
free (datestrCH);
|
|
||||||
datestrCH = NULL;
|
|
||||||
}
|
|
||||||
if (timestrCH != NULL)
|
|
||||||
{
|
|
||||||
free (timestrCH);
|
|
||||||
timestrCH = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lls == 28 || lls == 29)
|
|
||||||
{
|
|
||||||
if (idas == 0) printw ("RAN [%02lld] ", call_matrix[9-j][4]);
|
|
||||||
if (idas == 1) printw ("Area [%02lld] ", call_matrix[9-j][4]);
|
|
||||||
printw ("TG [%5lld] ", call_matrix[9-j][1]);
|
|
||||||
printw ("RID [%5lld] ", call_matrix[9-j][2]);
|
|
||||||
}
|
|
||||||
//dPMR
|
|
||||||
if (lls == 20 || lls == 21 || lls == 22 || lls == 23 ||lls == 24 || lls == 25 || lls == 26 || lls == 27)
|
|
||||||
{
|
|
||||||
printw ("TGT [%8lld] ", call_matrix[9-j][1]);
|
|
||||||
printw ("SRC [%8lld] ", call_matrix[9-j][2]);
|
|
||||||
printw ("DCC [%2lld] ", call_matrix[9-j][4]);
|
|
||||||
}
|
|
||||||
//P25
|
|
||||||
if (call_matrix[9-j][0] == 0 || call_matrix[9-j][0] == 1 || call_matrix[9-j][0] == 35 || call_matrix[9-j][0] == 36)
|
|
||||||
{
|
|
||||||
printw ("TGT [%8lld] ", call_matrix[9-j][1]);
|
|
||||||
printw ("SRC [%8lld] ", call_matrix[9-j][2]);
|
|
||||||
printw ("NAC [0x%03llX] ", call_matrix[9-j][4]);
|
|
||||||
}
|
|
||||||
//DMR BS Types
|
|
||||||
if (call_matrix[9-j][0] == 12 || call_matrix[9-j][0] == 13 || call_matrix[9-j][0] == 10 || call_matrix[9-j][0] == 11 )
|
|
||||||
{
|
|
||||||
// printw ("S[%lld] ", call_matrix[9-j][3]); //%d
|
|
||||||
printw ("TGT [%8lld] ", call_matrix[9-j][1]);
|
|
||||||
printw ("SRC [%8lld] ", call_matrix[9-j][2]);
|
|
||||||
printw ("DCC [%02lld] ", call_matrix[9-j][4]);
|
|
||||||
}
|
|
||||||
//DMR MS Types
|
|
||||||
if (call_matrix[9-j][0] == 32 || call_matrix[9-j][0] == 33 || call_matrix[9-j][0] == 34 )
|
|
||||||
{
|
|
||||||
// printw ("S[%lld] ", call_matrix[9-j][3]);
|
|
||||||
printw ("TGT [%8lld] ", call_matrix[9-j][1]);
|
|
||||||
printw ("SRC [%8lld] ", call_matrix[9-j][2]);
|
|
||||||
printw ("DCC [%02lld] ", call_matrix[9-j][4]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// #ifdef LIMAZULUTWEAKS
|
|
||||||
//Group Name Labels from CSV import
|
|
||||||
for (int k = 0; k < state->group_tally; k++)
|
|
||||||
{
|
|
||||||
if (state->group_array[k].groupNumber == call_matrix[9-j][1])
|
|
||||||
{
|
|
||||||
attron(COLOR_PAIR(4));
|
|
||||||
printw ("[%s]", state->group_array[k].groupName);
|
|
||||||
printw ("[%s] ", state->group_array[k].groupMode);
|
|
||||||
}
|
|
||||||
else if (state->group_array[k].groupNumber == call_matrix[9-j][2])
|
|
||||||
{
|
|
||||||
attron(COLOR_PAIR(4));
|
|
||||||
printw ("[%s]", state->group_array[k].groupName);
|
|
||||||
printw ("[%s] ", state->group_array[k].groupMode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//alias values here
|
|
||||||
printw ("%s", alias_ch[9-j]);
|
|
||||||
|
|
||||||
// #endif
|
|
||||||
printw ("\n");
|
|
||||||
}
|
}
|
||||||
|
sprintf (text_string, "%s", "BUMBLEBEETUNA");
|
||||||
//EDACS and ProVoice, outside of timestamp loop
|
if (strncmp(text_string, state->event_history_s[slot].Event_History_Items[i].text_message, 13) != 0)
|
||||||
if (call_matrix[j][0] == 14 || call_matrix[j][0] == 15 || call_matrix[j][0] == 37 || call_matrix[j][0] == 38 )
|
printw ("| %s \n", state->event_history_s[slot].Event_History_Items[i].text_message);
|
||||||
{
|
}
|
||||||
if (call_matrix[j][2] != 0)
|
|
||||||
{
|
|
||||||
printw ("| ");
|
|
||||||
char * timestrCHE = getTimeN(call_matrix[j][5]);
|
|
||||||
char * datestrCHE = getDateN(call_matrix[j][5]);
|
|
||||||
|
|
||||||
printw ("%s ", datestrCHE);
|
|
||||||
printw ("%s ", timestrCHE);
|
|
||||||
|
|
||||||
if (datestrCHE != NULL)
|
|
||||||
{
|
|
||||||
free (datestrCHE);
|
|
||||||
datestrCHE = NULL;
|
|
||||||
}
|
|
||||||
if (timestrCHE != NULL)
|
|
||||||
{
|
|
||||||
free (timestrCHE);
|
|
||||||
timestrCHE = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
printw ("LCN [%2lld] ", call_matrix[j][1]);
|
|
||||||
if (state->ea_mode == 1)
|
|
||||||
{
|
|
||||||
// Voice call
|
|
||||||
if ((call_matrix[j][4] & EDACS_IS_VOICE) != 0)
|
|
||||||
{
|
|
||||||
// Group call
|
|
||||||
if ((call_matrix[j][4] & EDACS_IS_GROUP) != 0)
|
|
||||||
printw ("Target [%8lld] Source [%8lld]", call_matrix[j][2], call_matrix[j][3]);
|
|
||||||
// I-Call
|
|
||||||
else if ((call_matrix[j][4] & EDACS_IS_INDIVIDUAL) != 0)
|
|
||||||
printw ("Target [%8lld] Source [%8lld] I-Call", call_matrix[j][2], call_matrix[j][3]);
|
|
||||||
// System all-call
|
|
||||||
else if ((call_matrix[j][4] & EDACS_IS_ALL_CALL) != 0)
|
|
||||||
printw ("Target [ SYSTEM ] Source [%8lld] All-Call", call_matrix[j][3]);
|
|
||||||
// Interconnect
|
|
||||||
else if ((call_matrix[j][4] & EDACS_IS_INTERCONNECT) != 0)
|
|
||||||
printw ("Target [ SYSTEM ] Source [%8lld] Interconnect", call_matrix[j][3]);
|
|
||||||
// Test call
|
|
||||||
else if ((call_matrix[j][4] & EDACS_IS_TEST_CALL) != 0)
|
|
||||||
printw ("Target [ SYSTEM ] Source [ SYSTEM ] Test Call");
|
|
||||||
// Unknown call
|
|
||||||
else
|
|
||||||
printw ("Unknown call type");
|
|
||||||
|
|
||||||
// Call flags
|
|
||||||
if ((call_matrix[j][4] & EDACS_IS_TEST_CALL) != 0) {}
|
|
||||||
else if ((call_matrix[j][4] & EDACS_IS_DIGITAL) == 0) printw (" [Ana]");
|
|
||||||
else printw (" [Dig]");
|
|
||||||
if ((call_matrix[j][4] & EDACS_IS_EMERGENCY) != 0) printw ("[EM]");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// Data call
|
|
||||||
printw ("Target [ DATA ] Source [%8lld] Data", call_matrix[j][3]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Voice call
|
|
||||||
if ((call_matrix[j][4] & EDACS_IS_VOICE) != 0)
|
|
||||||
{
|
|
||||||
// Compute AFS for display purposes only
|
|
||||||
int a = (call_matrix[j][2] >> state->edacs_a_shift) & state->edacs_a_mask;
|
|
||||||
int f = (call_matrix[j][2] >> state->edacs_f_shift) & state->edacs_f_mask;
|
|
||||||
int s = call_matrix[j][2] & state->edacs_s_mask;
|
|
||||||
|
|
||||||
// Group call
|
|
||||||
if ((call_matrix[j][4] & EDACS_IS_GROUP) != 0) {
|
|
||||||
char afs_str[8];
|
|
||||||
getAfsString(state, afs_str, a, f, s);
|
|
||||||
printw ("Target [%6lld][%s] Source [%5lld]", call_matrix[j][2], afs_str, call_matrix[j][3]);
|
|
||||||
}
|
|
||||||
// I-Call
|
|
||||||
else if ((call_matrix[j][4] & EDACS_IS_INDIVIDUAL) != 0)
|
|
||||||
if (getAfsStringLength(state) == 6)
|
|
||||||
printw ("Target [%6lld][ UNIT ] Source [%5lld] I-Call", call_matrix[j][2], call_matrix[j][3]);
|
|
||||||
else
|
|
||||||
printw ("Target [%6lld][ UNIT ] Source [%5lld] I-Call", call_matrix[j][2], call_matrix[j][3]);
|
|
||||||
// System all-call
|
|
||||||
else if ((call_matrix[j][4] & EDACS_IS_ALL_CALL) != 0)
|
|
||||||
if (getAfsStringLength(state) == 6)
|
|
||||||
printw ("Target [ SYSTEM ] Source [%5lld] All-Call", call_matrix[j][3]);
|
|
||||||
else
|
|
||||||
printw ("Target [ SYSTEM ] Source [%5lld] All-Call", call_matrix[j][3]);
|
|
||||||
// Interconnect
|
|
||||||
else if ((call_matrix[j][4] & EDACS_IS_INTERCONNECT) != 0)
|
|
||||||
if (getAfsStringLength(state) == 6)
|
|
||||||
printw ("Target [ SYSTEM ] Source [%5lld] Interconnect", call_matrix[j][3]);
|
|
||||||
else
|
|
||||||
printw ("Target [ SYSTEM ] Source [%5lld] Interconnect", call_matrix[j][3]);
|
|
||||||
// Test call
|
|
||||||
else if ((call_matrix[j][4] & EDACS_IS_TEST_CALL) != 0)
|
|
||||||
if (getAfsStringLength(state) == 6)
|
|
||||||
printw ("Target [ SYSTEM ] Source [ SYS ] Test Call");
|
|
||||||
else
|
|
||||||
printw ("Target [ SYSTEM ] Source [ SYS ] Test Call");
|
|
||||||
// Unknown call
|
|
||||||
else
|
|
||||||
printw ("Unknown call type");
|
|
||||||
|
|
||||||
// Call flags
|
|
||||||
if ((call_matrix[j][4] & EDACS_IS_TEST_CALL) != 0) {}
|
|
||||||
else if ((call_matrix[j][4] & EDACS_IS_DIGITAL) == 0) printw (" [Ana]");
|
|
||||||
else printw (" [Dig]");
|
|
||||||
if ((call_matrix[j][4] & EDACS_IS_AGENCY_CALL) != 0) printw ("[A]");
|
|
||||||
if ((call_matrix[j][4] & EDACS_IS_FLEET_CALL) != 0) printw ("[F]");
|
|
||||||
if ((call_matrix[j][4] & EDACS_IS_EMERGENCY) != 0) printw ("[EM]");
|
|
||||||
}
|
|
||||||
// Data call
|
|
||||||
else
|
|
||||||
if (getAfsStringLength(state) == 6)
|
|
||||||
printw ("Target [ DATA ] Source [%5lld] Data", call_matrix[j][3]);
|
|
||||||
else
|
|
||||||
printw ("Target [ DATA ] Source [%5lld] Data", call_matrix[j][3]);
|
|
||||||
}
|
|
||||||
//test
|
|
||||||
for (int k = 0; k < state->group_tally; k++)
|
|
||||||
{
|
|
||||||
if (state->group_array[k].groupNumber == call_matrix[j][2] && call_matrix[j][2] != 0)
|
|
||||||
{
|
|
||||||
attron(COLOR_PAIR(4));
|
|
||||||
printw ("[%s] ", state->group_array[k].groupName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (state->group_array[k].groupNumber == call_matrix[j][3] && call_matrix[j][3] != 0)
|
|
||||||
{
|
|
||||||
attron(COLOR_PAIR(4));
|
|
||||||
printw ("[%s] ", state->group_array[k].groupName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//end test
|
|
||||||
printw ("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} //end Call History
|
|
||||||
//fence bottom
|
|
||||||
printw ("------------------------------------------------------------------------------\n");
|
printw ("------------------------------------------------------------------------------\n");
|
||||||
attroff(COLOR_PAIR(4)); //cyan for history
|
attroff(COLOR_PAIR(4)); //cyan for history
|
||||||
}
|
}
|
||||||
@@ -4798,6 +4590,28 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||||||
noCarrier(opts, state);
|
noCarrier(opts, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c == 93) //']' key - increment event history indexer
|
||||||
|
{
|
||||||
|
if (state->eh_index < 244)
|
||||||
|
state->eh_index++;
|
||||||
|
else state->eh_index = 0; //rollover just before we run out of items in the arrray
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == 91) //'[' key - decrement event history indexer
|
||||||
|
{
|
||||||
|
if (state->eh_index > 0)
|
||||||
|
state->eh_index--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == 92) //'\' key - toggle events for slot displayed, and reset eh_index
|
||||||
|
{
|
||||||
|
eh_slot ^= 1;
|
||||||
|
state->eh_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//attempt retry to TCP Audio server
|
//attempt retry to TCP Audio server
|
||||||
if (c == 56) // '8' key, try audio in type 8 (TCP Audio Server connection) using defaults OR whatever the user last specified
|
if (c == 56) // '8' key, try audio in type 8 (TCP Audio Server connection) using defaults OR whatever the user last specified
|
||||||
{
|
{
|
||||||
@@ -5062,9 +4876,6 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||||||
//so probably just write a function to handle c input, and when c = certain values
|
//so probably just write a function to handle c input, and when c = certain values
|
||||||
//needing an entry box, then stop all of those
|
//needing an entry box, then stop all of those
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//allocated memory pointer needs to be free'd
|
//allocated memory pointer needs to be free'd
|
||||||
if (timestr != NULL)
|
if (timestr != NULL)
|
||||||
{
|
{
|
||||||
@@ -5084,3 +4895,402 @@ void ncursesClose ()
|
|||||||
endwin();
|
endwin();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//init each event history struct passed into here
|
||||||
|
void init_event_history (Event_History_I * event_struct, uint8_t start, uint8_t stop)
|
||||||
|
{
|
||||||
|
for (uint8_t i = start; i < stop; i++)
|
||||||
|
{
|
||||||
|
event_struct->Event_History_Items[i].write = 0;
|
||||||
|
event_struct->Event_History_Items[i].systype = -1;
|
||||||
|
event_struct->Event_History_Items[i].subtype = -1;
|
||||||
|
event_struct->Event_History_Items[i].gi = 0;
|
||||||
|
event_struct->Event_History_Items[i].enc = 0;
|
||||||
|
event_struct->Event_History_Items[i].enc_alg = 0;
|
||||||
|
event_struct->Event_History_Items[i].enc_key = 0;
|
||||||
|
event_struct->Event_History_Items[i].mi = 0;
|
||||||
|
event_struct->Event_History_Items[i].svc = 0;
|
||||||
|
event_struct->Event_History_Items[i].source_id = 0;
|
||||||
|
event_struct->Event_History_Items[i].target_id = 0;
|
||||||
|
event_struct->Event_History_Items[i].channel = 0;
|
||||||
|
event_struct->Event_History_Items[i].event_time = 0;
|
||||||
|
|
||||||
|
memset (event_struct->Event_History_Items[i].pdu, 0, sizeof(event_struct->Event_History_Items[0].pdu));
|
||||||
|
sprintf (event_struct->Event_History_Items[i].alias, "%s", "BUMBLEBEETUNA");
|
||||||
|
sprintf (event_struct->Event_History_Items[i].gps_s, "%s", "BUMBLEBEETUNA");
|
||||||
|
sprintf (event_struct->Event_History_Items[i].text_message, "%s", "BUMBLEBEETUNA");
|
||||||
|
sprintf (event_struct->Event_History_Items[i].event_string, "%s", "BUMBLEBEETUNA");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_event_history (Event_History_I * event_struct)
|
||||||
|
{
|
||||||
|
|
||||||
|
//Fixed, had it going in the wrong direction first time
|
||||||
|
for (uint8_t i = 254; i >= 1; i--)
|
||||||
|
{
|
||||||
|
event_struct->Event_History_Items[i].write = event_struct->Event_History_Items[i-1].write;
|
||||||
|
event_struct->Event_History_Items[i].systype = event_struct->Event_History_Items[i-1].systype;
|
||||||
|
event_struct->Event_History_Items[i].subtype = event_struct->Event_History_Items[i-1].subtype;
|
||||||
|
event_struct->Event_History_Items[i].gi = event_struct->Event_History_Items[i-1].gi;
|
||||||
|
event_struct->Event_History_Items[i].enc = event_struct->Event_History_Items[i-1].enc;
|
||||||
|
event_struct->Event_History_Items[i].enc_alg = event_struct->Event_History_Items[i-1].enc_alg;
|
||||||
|
event_struct->Event_History_Items[i].enc_key = event_struct->Event_History_Items[i-1].enc_key;
|
||||||
|
event_struct->Event_History_Items[i].mi = event_struct->Event_History_Items[i-1].mi;
|
||||||
|
event_struct->Event_History_Items[i].svc = event_struct->Event_History_Items[i-1].svc;
|
||||||
|
event_struct->Event_History_Items[i].source_id = event_struct->Event_History_Items[i-1].source_id;
|
||||||
|
event_struct->Event_History_Items[i].target_id = event_struct->Event_History_Items[i-1].target_id;
|
||||||
|
event_struct->Event_History_Items[i].channel = event_struct->Event_History_Items[i-1].channel;
|
||||||
|
event_struct->Event_History_Items[i].event_time = event_struct->Event_History_Items[i+1].event_time;
|
||||||
|
|
||||||
|
memcpy (event_struct->Event_History_Items[i].pdu, event_struct->Event_History_Items[i-1].pdu, sizeof(event_struct->Event_History_Items[0].pdu));
|
||||||
|
sprintf (event_struct->Event_History_Items[i].alias, "%s", event_struct->Event_History_Items[i-1].alias);
|
||||||
|
sprintf (event_struct->Event_History_Items[i].gps_s, "%s", event_struct->Event_History_Items[i-1].gps_s);
|
||||||
|
sprintf (event_struct->Event_History_Items[i].text_message, "%s", event_struct->Event_History_Items[i-1].text_message);
|
||||||
|
sprintf (event_struct->Event_History_Items[i].event_string, "%s", event_struct->Event_History_Items[i-1].event_string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_event_to_log_file (dsd_opts * opts, dsd_state * state, char * event_string) //pass completed event string here that is in the struct
|
||||||
|
{
|
||||||
|
|
||||||
|
//May reconfigure this to pull the struct directly, or pass supplimental strings for text messages, etc
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
|
FILE * event_log_file;
|
||||||
|
|
||||||
|
event_log_file = fopen(opts->event_out_file, "a");
|
||||||
|
|
||||||
|
fprintf (event_log_file, "%s \n", event_string);
|
||||||
|
char text_string[2000]; sprintf (text_string, "%s", "BUMBLEBEETUNA");
|
||||||
|
uint8_t slot = state->currentslot;
|
||||||
|
if (strncmp(text_string, state->event_history_s[slot].Event_History_Items[0].text_message, 13) != 0)
|
||||||
|
fprintf (event_log_file, "%s \n", state->event_history_s[slot].Event_History_Items[0].text_message);
|
||||||
|
|
||||||
|
fflush (event_log_file);
|
||||||
|
fclose (event_log_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
// run once per loop to check for and push and update event history
|
||||||
|
void watchdog_event_history (dsd_opts * opts, dsd_state * state, uint8_t slot)
|
||||||
|
{
|
||||||
|
|
||||||
|
//create a pointer to the current slot event history
|
||||||
|
Event_History_I * event_struct = &state->event_history_s[slot];
|
||||||
|
|
||||||
|
//who is currently talking
|
||||||
|
uint32_t source_id = 0;
|
||||||
|
|
||||||
|
//last values pulled from the event history
|
||||||
|
uint32_t last_source_id = event_struct->Event_History_Items[0].source_id;
|
||||||
|
|
||||||
|
if (slot == 0)
|
||||||
|
source_id = state->lastsrc;
|
||||||
|
else
|
||||||
|
source_id = state->lastsrcR;
|
||||||
|
|
||||||
|
if (slot == 0) //BUGFIX: generic catch on FDMA systems so that we don't write duplicate data to slot 2 event history
|
||||||
|
{
|
||||||
|
//NXDN RID (TODO: Changeover to lastsrc later on)
|
||||||
|
if (state->lastsynctype == 28 || state->lastsynctype == 29)
|
||||||
|
source_id = state->nxdn_last_rid;
|
||||||
|
|
||||||
|
if (state->lastsynctype == 30 || state->lastsynctype == 30) //YSF Fusion
|
||||||
|
{
|
||||||
|
source_id = 0;
|
||||||
|
for (uint8_t i = 0; i < 11; i++)
|
||||||
|
source_id += state->ysf_src[i]; //convert to sum value to make a distinct enough src value
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->lastsynctype == 16 || state->lastsynctype == 17) //M17 STR
|
||||||
|
{
|
||||||
|
source_id = 0;
|
||||||
|
for (uint8_t i = 0; i < 9; i++)
|
||||||
|
source_id += state->m17_src_csd[i]; //convert to sum value to make a distinct enough src value
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->lastsynctype == 6 || state->lastsynctype == 7 || state->lastsynctype == 18 || state->lastsynctype == 19) //DSTAR
|
||||||
|
{
|
||||||
|
source_id = 0;
|
||||||
|
for (uint8_t i = 0; i < 12; i++)
|
||||||
|
source_id += state->dstar_src[i]; //convert to sum value to make a distinct enough src value
|
||||||
|
|
||||||
|
//need a strncmp here for 8 spaces in this field first so we don't blip a blank into the event history
|
||||||
|
if (strncmp(state->dstar_src, " ", 8) == 0)
|
||||||
|
source_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->lastsynctype == 16 || state->lastsynctype == 17 || state->lastsynctype == 20 || state->lastsynctype == 24 || state->lastsynctype == 21 || state->lastsynctype == 25 || state->lastsynctype == 22 || state->lastsynctype == 26 || state->lastsynctype == 23 || state->lastsynctype == 27) //dPMR
|
||||||
|
{
|
||||||
|
source_id = 0;
|
||||||
|
for (uint8_t i = 0; i < 20; i++)
|
||||||
|
source_id += state->dpmr_caller_id[i]; //convert to sum value to make a distinct enough src value
|
||||||
|
|
||||||
|
//need a strncmp here for 8 spaces in this field first so we don't blip a blank into the event history
|
||||||
|
if (strncmp(state->dpmr_caller_id, " ", 6) == 0)
|
||||||
|
source_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->lastsynctype == 14 || state->lastsynctype == 15 || state->lastsynctype == 37 || state->lastsynctype == 38) //EDACS Calls
|
||||||
|
{
|
||||||
|
source_id = 0;
|
||||||
|
if (opts->p25_is_tuned == 1)
|
||||||
|
source_id = state->lastsrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source_id != last_source_id && last_source_id != 0) //test without != 0 if we want to constantly update the current event
|
||||||
|
{
|
||||||
|
|
||||||
|
if (opts->event_out_file[0] != 0)
|
||||||
|
write_event_to_log_file(opts, state, event_struct->Event_History_Items[0].event_string);
|
||||||
|
|
||||||
|
push_event_history (event_struct);
|
||||||
|
init_event_history (event_struct, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//similar to above, but constantly testing and checking the most recent event only
|
||||||
|
//this will hopefully be more useful when dealing with an ongoing event with
|
||||||
|
//features that update over time with embedded signalling, etc
|
||||||
|
void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot)
|
||||||
|
{
|
||||||
|
|
||||||
|
//create a pointer to the current slot event history
|
||||||
|
Event_History_I * event_struct = &state->event_history_s[slot];
|
||||||
|
|
||||||
|
//TODO: Flesh out more later on.
|
||||||
|
uint32_t source_id = 0;
|
||||||
|
uint32_t target_id = 0;
|
||||||
|
uint16_t svc_opts = 0;
|
||||||
|
uint8_t subtype = 0;
|
||||||
|
|
||||||
|
uint8_t enc = 0;
|
||||||
|
uint8_t alg_id = 0;
|
||||||
|
uint16_t key_id = 0;
|
||||||
|
unsigned long long int mi;
|
||||||
|
|
||||||
|
if (slot == 0)
|
||||||
|
{
|
||||||
|
source_id = state->lastsrc;
|
||||||
|
target_id = state->lasttg;
|
||||||
|
|
||||||
|
subtype = state->dmrburstL;
|
||||||
|
|
||||||
|
svc_opts = state->dmr_so;
|
||||||
|
enc = (svc_opts >> 6) & 1;
|
||||||
|
alg_id = state->payload_algid;
|
||||||
|
key_id = (uint16_t)state->payload_keyid;
|
||||||
|
|
||||||
|
mi = state->payload_mi;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
source_id = state->lastsrcR;
|
||||||
|
target_id = state->lasttgR;
|
||||||
|
subtype = state->dmrburstR;
|
||||||
|
|
||||||
|
svc_opts = state->dmr_soR;
|
||||||
|
enc = (svc_opts >> 6) & 1;
|
||||||
|
|
||||||
|
alg_id = state->payload_algidR;
|
||||||
|
key_id = (uint16_t)state->payload_keyidR;
|
||||||
|
mi = state->payload_miR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slot == 0) //BUGFIX: generic catch on FDMA systems so that we don't write duplicate data to slot 2 event history
|
||||||
|
{
|
||||||
|
//NXDN RID (TODO: Changeover to lastsrc and lasttg later on)
|
||||||
|
if (state->lastsynctype == 28 || state->lastsynctype == 29)
|
||||||
|
{
|
||||||
|
source_id = state->nxdn_last_rid;
|
||||||
|
target_id = state->nxdn_last_tg;
|
||||||
|
if (state->nxdn_cipher_type != 0)
|
||||||
|
enc = 1;
|
||||||
|
alg_id = state->nxdn_cipher_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->lastsynctype == 30 || state->lastsynctype == 30) //YSF Fusion
|
||||||
|
{
|
||||||
|
source_id = 0;
|
||||||
|
for (uint8_t i = 0; i < 11; i++)
|
||||||
|
source_id += state->ysf_src[i]; //convert to sum value to make a distinct enough src value
|
||||||
|
|
||||||
|
//TODO: Add src and dst as aliases?
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->lastsynctype == 16 || state->lastsynctype == 17) //M17 STR
|
||||||
|
{
|
||||||
|
source_id = 0;
|
||||||
|
for (uint8_t i = 0; i < 9; i++)
|
||||||
|
source_id += state->m17_src_csd[i]; //convert to sum value to make a distinct enough src value
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->lastsynctype == 6 || state->lastsynctype == 7 || state->lastsynctype == 18 || state->lastsynctype == 19) //DSTAR
|
||||||
|
{
|
||||||
|
source_id = 0;
|
||||||
|
for (uint8_t i = 0; i < 12; i++)
|
||||||
|
source_id += state->dstar_src[i]; //convert to sum value to make a distinct enough src value
|
||||||
|
|
||||||
|
//need a strncmp here for 8 spaces in this field first so we don't blip a blank into the event history
|
||||||
|
if (strncmp(state->dstar_src, " ", 8) == 0)
|
||||||
|
source_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->lastsynctype == 16 || state->lastsynctype == 17 || state->lastsynctype == 20 || state->lastsynctype == 24 || state->lastsynctype == 21 || state->lastsynctype == 25 || state->lastsynctype == 22 || state->lastsynctype == 26 || state->lastsynctype == 23 || state->lastsynctype == 27) //dPMR
|
||||||
|
{
|
||||||
|
source_id = 0;
|
||||||
|
for (uint8_t i = 0; i < 20; i++)
|
||||||
|
source_id += state->dpmr_caller_id[i]; //convert to sum value to make a distinct enough src value
|
||||||
|
|
||||||
|
//need a strncmp here for 8 spaces in this field first so we don't blip a blank into the event history
|
||||||
|
if (strncmp(state->dpmr_caller_id, " ", 6) == 0)
|
||||||
|
source_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->lastsynctype == 14 || state->lastsynctype == 15 || state->lastsynctype == 37 || state->lastsynctype == 38) //EDACS Calls
|
||||||
|
{
|
||||||
|
source_id = 0;
|
||||||
|
if (opts->p25_is_tuned == 1)
|
||||||
|
source_id = state->lastsrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//system type string (P25, DMR, etc)
|
||||||
|
char * sys_string = SyncTypes[state->lastsynctype];
|
||||||
|
|
||||||
|
//date and time strings
|
||||||
|
char * timestr = getTimeN(time(NULL));
|
||||||
|
char * datestr = getDateN(time(NULL));
|
||||||
|
|
||||||
|
if (source_id != 0)
|
||||||
|
{
|
||||||
|
event_struct->Event_History_Items[0].write = 1; //TODO: Write a 1 here after written to a log
|
||||||
|
if (state->lastsynctype != -1)
|
||||||
|
event_struct->Event_History_Items[0].systype = state->lastsynctype;
|
||||||
|
else event_struct->Event_History_Items[0].systype = 39; //generic digital call
|
||||||
|
event_struct->Event_History_Items[0].subtype = subtype; //voice
|
||||||
|
event_struct->Event_History_Items[0].gi = state->gi[slot]; //need this add this to link control messages
|
||||||
|
event_struct->Event_History_Items[0].enc = enc;
|
||||||
|
event_struct->Event_History_Items[0].enc_alg = alg_id;
|
||||||
|
event_struct->Event_History_Items[0].enc_key = key_id;
|
||||||
|
event_struct->Event_History_Items[0].mi = mi;
|
||||||
|
event_struct->Event_History_Items[0].svc = svc_opts;
|
||||||
|
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 = 0; //need to add this to trunking messages, if tuned from call grant
|
||||||
|
event_struct->Event_History_Items[0].event_time = time(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Craft an event string for ncurses event history, and a more complex string for logging
|
||||||
|
char event_string[200]; memset(event_string, 0, sizeof(event_string));
|
||||||
|
|
||||||
|
//WIP: Seperate Voice Call Event Strings when SRC/TGT values are numerical,
|
||||||
|
//and a seperate one for when they are string values (M17, YSF, DSTAR, and dPMR, or use special formatting)
|
||||||
|
if (state->lastsynctype == 30 || state->lastsynctype == 30) //YSF Fusion (may need to use uplink instead of src, unsure for this)
|
||||||
|
{
|
||||||
|
//TODO: See if we can add some decoded data as well in the future to an event string
|
||||||
|
sprintf (event_string, "%s %s %s Voice TGT: %s SRC: %s ", datestr, timestr, sys_string, state->ysf_tgt, state->ysf_src);
|
||||||
|
}
|
||||||
|
else if (state->lastsynctype == 16 || state->lastsynctype == 17) //M17
|
||||||
|
{
|
||||||
|
//TODO: See if we can add some decoded data as well in the future to an event string
|
||||||
|
sprintf (event_string, "%s %s %s Voice TGT: %s SRC: %s ", datestr, timestr, sys_string, state->m17_dst_str, state->m17_src_str);
|
||||||
|
}
|
||||||
|
else if (state->lastsynctype == 6 || state->lastsynctype == 7 || state->lastsynctype == 18 || state->lastsynctype == 19) //DSTAR
|
||||||
|
{
|
||||||
|
//TODO: See if we can add some decoded data as well in the future to an event string
|
||||||
|
sprintf (event_string, "%s %s %s Voice TGT: %s SRC: %s ", datestr, timestr, sys_string, state->dstar_dst, state->dstar_src);
|
||||||
|
}
|
||||||
|
else if (state->lastsynctype == 16 || state->lastsynctype == 17 || state->lastsynctype == 20 || state->lastsynctype == 24 || state->lastsynctype == 21 || state->lastsynctype == 25 || state->lastsynctype == 22 || state->lastsynctype == 26 || state->lastsynctype == 23 || state->lastsynctype == 27) //dPMR
|
||||||
|
{
|
||||||
|
//TODO: See if we can add some decoded data as well in the future to an event string
|
||||||
|
sprintf (event_string, "%s %s %s Voice TGT: %s SRC: %s ", datestr, timestr, sys_string, state->dpmr_target_id, state->dpmr_caller_id);
|
||||||
|
}
|
||||||
|
//TODO: Find out why EDACS is also placing items into Slot 2 Event History with valid src, but invalid tg (not a problem, just odd)
|
||||||
|
else if (state->lastsynctype == 14 || state->lastsynctype == 15 || state->lastsynctype == 37 || state->lastsynctype == 38) //EDACS Calls
|
||||||
|
{
|
||||||
|
//is this AFS format, or EA format, also, need to re-add Ilya's other decoded call elements into this somehow
|
||||||
|
if (state->ea_mode == 1)
|
||||||
|
{
|
||||||
|
sprintf (event_string, "%s %s %s Voice TGT: %05d; SRC: %05d; ", datestr, timestr, sys_string, target_id, source_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//TODO: Have EDACS decoder write a nicer string for us to use in this instance
|
||||||
|
// Compute AFS for display purposes only
|
||||||
|
int a = (state->tg_hold >> state->edacs_a_shift) & state->edacs_a_mask;
|
||||||
|
int f = (state->tg_hold >> state->edacs_f_shift) & state->edacs_f_mask;
|
||||||
|
int s = state->tg_hold & state->edacs_s_mask;
|
||||||
|
char afs_str[8];
|
||||||
|
getAfsString(state, afs_str, a, f, s);
|
||||||
|
sprintf (event_string, "%s %s %s Voice AFS: %s ", datestr, timestr, sys_string, afs_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else //any numerical based src and tgt values
|
||||||
|
{
|
||||||
|
sprintf (event_string, "%s %s %s Voice TGT: %08d; SRC: %08d; ", datestr, timestr, sys_string, target_id, source_id);
|
||||||
|
if (enc)
|
||||||
|
strcat(event_string, "ENC; ");
|
||||||
|
if (alg_id != 0 && alg_id != 0x80)
|
||||||
|
{
|
||||||
|
char ess_str[30];
|
||||||
|
sprintf (ess_str, "ALG: %02X; KID: %04X;", alg_id, key_id); //KID overflow?
|
||||||
|
strcat(event_string, ess_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf (event_struct->Event_History_Items[0].event_string, "%s", event_string);
|
||||||
|
|
||||||
|
if (timestr != NULL)
|
||||||
|
{
|
||||||
|
free (timestr);
|
||||||
|
timestr = NULL;
|
||||||
|
}
|
||||||
|
if (datestr != NULL)
|
||||||
|
{
|
||||||
|
free (datestr);
|
||||||
|
datestr = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void watchdog_event_datacall (dsd_opts * opts, dsd_state * state, uint32_t src, uint32_t dst, char * data_string, uint8_t slot)
|
||||||
|
{
|
||||||
|
UNUSED(opts);
|
||||||
|
state->event_history_s[slot].Event_History_Items[0].write = 1; //TODO: Write a 1 here when written to a log
|
||||||
|
state->event_history_s[slot].Event_History_Items[0].systype = state->lastsynctype;
|
||||||
|
state->event_history_s[slot].Event_History_Items[0].subtype = 6; //data
|
||||||
|
state->event_history_s[slot].Event_History_Items[0].gi = state->gi[slot];
|
||||||
|
state->event_history_s[slot].Event_History_Items[0].enc = 0;
|
||||||
|
state->event_history_s[slot].Event_History_Items[0].enc_alg = 0;
|
||||||
|
state->event_history_s[slot].Event_History_Items[0].enc_key = 0;
|
||||||
|
state->event_history_s[slot].Event_History_Items[0].mi = 0;
|
||||||
|
state->event_history_s[slot].Event_History_Items[0].svc = 0;
|
||||||
|
state->event_history_s[slot].Event_History_Items[0].source_id = src;
|
||||||
|
state->event_history_s[slot].Event_History_Items[0].target_id = dst;
|
||||||
|
state->event_history_s[slot].Event_History_Items[0].channel = 0;
|
||||||
|
state->event_history_s[slot].Event_History_Items[0].event_time = time(NULL);
|
||||||
|
|
||||||
|
//date and time strings //getTimeN(time(NULL)); //getDateN(time(NULL));
|
||||||
|
char * timestr = getTimeN(time(NULL));
|
||||||
|
char * datestr = getDateN(time(NULL));
|
||||||
|
|
||||||
|
char event_string[2000]; memset (event_string, 0, sizeof(event_string));
|
||||||
|
sprintf (event_string, "%s %s ", datestr, timestr);
|
||||||
|
strcat (event_string, data_string); //may need to check for potential overflow of this
|
||||||
|
sprintf (state->event_history_s[slot].Event_History_Items[0].event_string, "%s", event_string); //could change this to a strncpy to prevent potential overflow
|
||||||
|
|
||||||
|
if (timestr != NULL)
|
||||||
|
{
|
||||||
|
free (timestr);
|
||||||
|
timestr = NULL;
|
||||||
|
}
|
||||||
|
if (datestr != NULL)
|
||||||
|
{
|
||||||
|
free (datestr);
|
||||||
|
datestr = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -503,6 +503,8 @@ void return_to_cc (dsd_opts * opts, dsd_state * state)
|
|||||||
state->lasttgR = 0;
|
state->lasttgR = 0;
|
||||||
state->lastsrc = 0;
|
state->lastsrc = 0;
|
||||||
state->lastsrcR = 0;
|
state->lastsrcR = 0;
|
||||||
|
state->gi[0] = 0;
|
||||||
|
state->gi[1] = 0;
|
||||||
state->payload_algid = 0;
|
state->payload_algid = 0;
|
||||||
state->payload_algidR = 0;
|
state->payload_algidR = 0;
|
||||||
state->payload_keyid = 0;
|
state->payload_keyid = 0;
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ void processDSTAR(dsd_opts * opts, dsd_state * state)
|
|||||||
if (opts->use_ncurses_terminal == 1)
|
if (opts->use_ncurses_terminal == 1)
|
||||||
ncursesPrinter(opts, state);
|
ncursesPrinter(opts, state);
|
||||||
|
|
||||||
|
//slot 1
|
||||||
|
watchdog_event_history(opts, state, 0);
|
||||||
|
watchdog_event_current(opts, state, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
|
|||||||
@@ -374,6 +374,10 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn
|
|||||||
if (opts->use_ncurses_terminal == 1)
|
if (opts->use_ncurses_terminal == 1)
|
||||||
ncursesPrinter(opts, state);
|
ncursesPrinter(opts, state);
|
||||||
|
|
||||||
|
//slot 1
|
||||||
|
watchdog_event_history(opts, state, 0);
|
||||||
|
watchdog_event_current(opts, state, 0);
|
||||||
|
|
||||||
//write to wav file if opened
|
//write to wav file if opened
|
||||||
if (opts->wav_out_f != NULL)
|
if (opts->wav_out_f != NULL)
|
||||||
{
|
{
|
||||||
@@ -455,6 +459,11 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||||||
edacs_bit[i] = getDibit (opts, state); //getDibit returns binary 0 or 1 on GFSK signal (Edacs and PV)
|
edacs_bit[i] = getDibit (opts, state); //getDibit returns binary 0 or 1 on GFSK signal (Edacs and PV)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if we have executed a tune to a channel, then we will forego decoding any more edacs until we return from the voice channel
|
||||||
|
//this is a simple quick and dirty solution to fix setting the lastsrc value to something that we don't want in event history
|
||||||
|
if (opts->p25_is_tuned == 1)
|
||||||
|
goto EDACS_END;
|
||||||
|
|
||||||
//Each EDACS outbound frame consists of two 40-bit (28-bit data, 12-bit BCH) messages. Each message is sent three
|
//Each EDACS outbound frame consists of two 40-bit (28-bit data, 12-bit BCH) messages. Each message is sent three
|
||||||
//times, with the middle message bitwise-inverted. We use unsigned long long int here to be safe in 32-bit cygwin (not
|
//times, with the middle message bitwise-inverted. We use unsigned long long int here to be safe in 32-bit cygwin (not
|
||||||
//sure if this was actually an issue).
|
//sure if this was actually an issue).
|
||||||
@@ -2135,6 +2144,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EDACS_END:
|
||||||
|
|
||||||
if (timestr != NULL)
|
if (timestr != NULL)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2466,6 +2466,10 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state)
|
|||||||
if (opts->use_ncurses_terminal == 1)
|
if (opts->use_ncurses_terminal == 1)
|
||||||
ncursesPrinter(opts, state);
|
ncursesPrinter(opts, state);
|
||||||
|
|
||||||
|
//slot 1
|
||||||
|
watchdog_event_history(opts, state, 0);
|
||||||
|
watchdog_event_current(opts, state, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//SEND EOTX to reflector
|
//SEND EOTX to reflector
|
||||||
@@ -3826,6 +3830,10 @@ void processM17IPF(dsd_opts * opts, dsd_state * state)
|
|||||||
if (opts->use_ncurses_terminal == 1)
|
if (opts->use_ncurses_terminal == 1)
|
||||||
ncursesPrinter(opts, state);
|
ncursesPrinter(opts, state);
|
||||||
|
|
||||||
|
//slot 1
|
||||||
|
watchdog_event_history(opts, state, 0);
|
||||||
|
watchdog_event_current(opts, state, 0);
|
||||||
|
|
||||||
//clear frame
|
//clear frame
|
||||||
memset (ip_frame, 0, sizeof(ip_frame));
|
memset (ip_frame, 0, sizeof(ip_frame));
|
||||||
|
|
||||||
|
|||||||
@@ -1075,10 +1075,10 @@ void process_P2_DUID (dsd_opts * opts, dsd_state * state)
|
|||||||
state->payload_keyid = 0;
|
state->payload_keyid = 0;
|
||||||
state->payload_algidR = 0;
|
state->payload_algidR = 0;
|
||||||
state->payload_keyidR = 0;
|
state->payload_keyidR = 0;
|
||||||
state->lastsrc = 0;
|
// state->lastsrc = 0; //disable?
|
||||||
state->lastsrcR = 0;
|
// state->lastsrcR = 0; //disable?
|
||||||
state->lasttg = 0;
|
// state->lasttg = 0; //disable?
|
||||||
state->lasttgR = 0;
|
// state->lasttgR = 0; //disable?
|
||||||
state->p2_is_lcch = 0;
|
state->p2_is_lcch = 0;
|
||||||
state->fourv_counter[0] = 0;
|
state->fourv_counter[0] = 0;
|
||||||
state->fourv_counter[1] = 0;
|
state->fourv_counter[1] = 0;
|
||||||
@@ -1092,6 +1092,15 @@ void process_P2_DUID (dsd_opts * opts, dsd_state * state)
|
|||||||
{
|
{
|
||||||
ncursesPrinter(opts, state);
|
ncursesPrinter(opts, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//slot 1
|
||||||
|
watchdog_event_history(opts, state, 0);
|
||||||
|
watchdog_event_current(opts, state, 0);
|
||||||
|
|
||||||
|
//slot 2 for TDMA systems
|
||||||
|
watchdog_event_history(opts, state, 1);
|
||||||
|
watchdog_event_current(opts, state, 1);
|
||||||
|
|
||||||
//add 360 bits to each counter
|
//add 360 bits to each counter
|
||||||
vc_counter = vc_counter + 360;
|
vc_counter = vc_counter + 360;
|
||||||
|
|
||||||
|
|||||||
@@ -127,12 +127,15 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
|
|||||||
|
|
||||||
state->dmrburstL = 20;
|
state->dmrburstL = 20;
|
||||||
fprintf (stderr, "\n VCH 0 - ");
|
fprintf (stderr, "\n VCH 0 - ");
|
||||||
|
//check that src is not zero first, some harris and other patch systems may do this,
|
||||||
state->lastsrc = (SMAC[13] << 16) | (SMAC[14] << 8) | SMAC[15];
|
//but that also causes an issue in the new event logger if the active channel has a src, but mac_ptt has 0
|
||||||
|
uint32_t src = (SMAC[13] << 16) | (SMAC[14] << 8) | SMAC[15];
|
||||||
|
if (src != 0)
|
||||||
|
state->lastsrc = (SMAC[13] << 16) | (SMAC[14] << 8) | SMAC[15];
|
||||||
state->lasttg = (SMAC[16] << 8) | SMAC[17];
|
state->lasttg = (SMAC[16] << 8) | SMAC[17];
|
||||||
|
|
||||||
fprintf (stderr, "TG %d ", state->lasttg);
|
fprintf (stderr, "TG %d ", state->lasttg);
|
||||||
fprintf (stderr, "SRC %d ", state->lastsrc);
|
fprintf (stderr, "SRC %d ", src);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
When the talker radio is initiating an individual call (unit to unit or telephone interconnect), the reserved group ID of zero
|
When the talker radio is initiating an individual call (unit to unit or telephone interconnect), the reserved group ID of zero
|
||||||
@@ -195,12 +198,15 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
|
|||||||
|
|
||||||
state->dmrburstR = 20;
|
state->dmrburstR = 20;
|
||||||
fprintf (stderr, "\n VCH 1 - ");
|
fprintf (stderr, "\n VCH 1 - ");
|
||||||
|
//check that src is not zero first, some harris and other patch systems may do this,
|
||||||
state->lastsrcR = (SMAC[13] << 16) | (SMAC[14] << 8) | SMAC[15];
|
//but that also causes an issue in the new event logger if the active channel has a src, but mac_ptt has 0
|
||||||
|
uint32_t src = (SMAC[13] << 16) | (SMAC[14] << 8) | SMAC[15];
|
||||||
|
if (src != 0)
|
||||||
|
state->lastsrcR = (SMAC[13] << 16) | (SMAC[14] << 8) | SMAC[15];
|
||||||
state->lasttgR = (SMAC[16] << 8) | SMAC[17];
|
state->lasttgR = (SMAC[16] << 8) | SMAC[17];
|
||||||
|
|
||||||
fprintf (stderr, "TG %d ", state->lasttgR);
|
fprintf (stderr, "TG %d ", state->lasttgR);
|
||||||
fprintf (stderr, "SRC %d ", state->lastsrcR);
|
fprintf (stderr, "SRC %d ", src);
|
||||||
|
|
||||||
// if (state->lastsrcR == 0) fprintf (stderr, "External ");
|
// if (state->lastsrcR == 0) fprintf (stderr, "External ");
|
||||||
|
|
||||||
@@ -576,12 +582,15 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156]
|
|||||||
|
|
||||||
state->dmrburstL = 20;
|
state->dmrburstL = 20;
|
||||||
fprintf (stderr, "\n VCH 0 - ");
|
fprintf (stderr, "\n VCH 0 - ");
|
||||||
|
//check that src is not zero first, some harris and other patch systems may do this,
|
||||||
state->lastsrc = (FMAC[13] << 16) | (FMAC[14] << 8) | FMAC[15];
|
//but that also causes an issue in the new event logger if the active channel has a src, but mac_ptt has 0
|
||||||
|
uint32_t src = (FMAC[13] << 16) | (FMAC[14] << 8) | FMAC[15];
|
||||||
|
if (src != 0)
|
||||||
|
state->lastsrc = (FMAC[13] << 16) | (FMAC[14] << 8) | FMAC[15];
|
||||||
state->lasttg = (FMAC[16] << 8) | FMAC[17];
|
state->lasttg = (FMAC[16] << 8) | FMAC[17];
|
||||||
|
|
||||||
fprintf (stderr, "TG %d ", state->lasttg);
|
fprintf (stderr, "TG %d ", state->lasttg);
|
||||||
fprintf (stderr, "SRC %d ", state->lastsrc);
|
fprintf (stderr, "SRC %d ", src);
|
||||||
|
|
||||||
// if (state->lastsrc == 0) fprintf (stderr, "External ");
|
// if (state->lastsrc == 0) fprintf (stderr, "External ");
|
||||||
|
|
||||||
@@ -634,12 +643,15 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156]
|
|||||||
|
|
||||||
state->dmrburstR = 20;
|
state->dmrburstR = 20;
|
||||||
fprintf (stderr, "\n VCH 1 - ");
|
fprintf (stderr, "\n VCH 1 - ");
|
||||||
|
//check that src is not zero first, some harris and other patch systems may do this,
|
||||||
state->lastsrcR = (FMAC[13] << 16) | (FMAC[14] << 8) | FMAC[15];
|
//but that also causes an issue in the new event logger if the active channel has a src, but mac_ptt has 0
|
||||||
|
uint32_t src = (FMAC[13] << 16) | (FMAC[14] << 8) | FMAC[15];
|
||||||
|
if (src != 0)
|
||||||
|
state->lastsrcR = (FMAC[13] << 16) | (FMAC[14] << 8) | FMAC[15];
|
||||||
state->lasttgR = (FMAC[16] << 8) | FMAC[17];
|
state->lasttgR = (FMAC[16] << 8) | FMAC[17];
|
||||||
|
|
||||||
fprintf (stderr, "TG %d ", state->lasttgR);
|
fprintf (stderr, "TG %d ", state->lasttgR);
|
||||||
fprintf (stderr, "SRC %d ", state->lastsrcR);
|
fprintf (stderr, "SRC %d ", src);
|
||||||
|
|
||||||
// if (state->lastsrcR == 0) fprintf (stderr, "External ");
|
// if (state->lastsrcR == 0) fprintf (stderr, "External ");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user