diff --git a/include/dsd.h b/include/dsd.h index 2f1bea1..f207e9f 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -88,6 +88,34 @@ 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 typedef struct { float coef[2]; @@ -280,6 +308,7 @@ typedef struct char wav_out_file_raw[1024]; char symbol_out_file[1024]; char lrrp_out_file[1024]; + char event_out_file[1024]; 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_outR; //flag for mbe out, don't attempt fclose more than once @@ -546,6 +575,8 @@ typedef struct int lasttgR; int lastsrc; int lastsrcR; + uint8_t gi[2]; //group, or private call, per slot + uint8_t eh_index; int nac; int errs; int errs2; @@ -688,8 +719,8 @@ typedef struct uint8_t dmr_alias_format[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_embedded_gps[2][200]; //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_embedded_gps[2][600]; //2 slots by 99 char string for string embedded 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 call_string[2][200]; //string for call information char active_channel[31][200]; //string for storing and displaying active trunking channels @@ -699,6 +730,9 @@ typedef struct dPMRVoiceFS2Frame_t dPMRVoiceFS2Frame; + //event history itemized per slot + Event_History_I event_history_s[2]; + //new audio filter structs LPFilter RCFilter; HPFilter HRCFilter; @@ -1354,6 +1388,14 @@ char * getDateH(); char * getDateS(); 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 void dmr_alg_reset (dsd_opts * opts, dsd_state * state); void dmr_alg_refresh (dsd_opts * opts, dsd_state * state); diff --git a/src/dmr_block.c b/src/dmr_block.c index 9320527..f646fbc 100644 --- a/src/dmr_block.c +++ b/src/dmr_block.c @@ -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 { 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); + + 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) { @@ -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 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); } } diff --git a/src/dmr_bs.c b/src/dmr_bs.c index 69bd827..cf956a9 100644 --- a/src/dmr_bs.c +++ b/src/dmr_bs.c @@ -584,6 +584,14 @@ void dmrBS (dsd_opts * opts, dsd_state * 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) { diff --git a/src/dmr_flco.c b/src/dmr_flco.c index 9824cac..23d273f 100644 --- a/src/dmr_flco.c +++ b/src/dmr_flco.c @@ -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_so = 0; - // state->lasttg = 0; - // state->lastsrc = 0; + state->lasttg = 0; + state->lastsrc = 0; state->payload_algid = 0; state->payload_mi = 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_soR = 0; - // state->lasttgR = 0; - // state->lastsrcR = 0; + state->lasttgR = 0; + state->lastsrcR = 0; state->payload_algidR = 0; state->payload_miR = 0; state->payload_keyidR = 0; diff --git a/src/dmr_ms.c b/src/dmr_ms.c index 16e011f..2bd82ca 100644 --- a/src/dmr_ms.c +++ b/src/dmr_ms.c @@ -310,6 +310,10 @@ void dmrMS (dsd_opts * opts, dsd_state * state) ncursesPrinter(opts, state); } + //slot 1 + watchdog_event_history(opts, state, 0); + watchdog_event_current(opts, state, 0); + } // end loop END: diff --git a/src/dmr_pdu.c b/src/dmr_pdu.c index 338efdb..c8140a1 100644 --- a/src/dmr_pdu.c +++ b/src/dmr_pdu.c @@ -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) { 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: "); uint16_t ch16 = 0; 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 //in the ASCII Range (should be alright for a quick visual) 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); + //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 @@ -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 } + //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 @@ -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;"); + 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 @@ -459,7 +478,7 @@ void decode_ip_pdu (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t * } 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;"); // if (len > 28) //default catch all (debug only) // 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 { - 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); // if (len > 28) //default catch all (debug only) // utf8_to_text(state, 0, len-28, 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 @@ -745,6 +766,7 @@ void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint16_t len, uint32_t source sprintf (velstr, "%s", ""); sprintf (degstr, "%s", ""); 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 (deg_set) sprintf (degstr, " %d%s ", degrees, deg_glyph); sprintf (state->dmr_lrrp_gps[slot], "%s%s%s", lrrpstr, velstr, degstr); diff --git a/src/dsd_frame_sync.c b/src/dsd_frame_sync.c index a7623a1..40f77a7 100644 --- a/src/dsd_frame_sync.c +++ b/src/dsd_frame_sync.c @@ -230,6 +230,14 @@ getFrameSync (dsd_opts * opts, dsd_state * 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)) { //fprintf (stderr,"\nSymbol Timing:\n"); diff --git a/src/dsd_main.c b/src/dsd_main.c index 9b961ab..e48be31 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -265,6 +265,8 @@ noCarrier (dsd_opts * opts, dsd_state * state) state->lastsrc = 0; state->lasttgR = 0; state->lastsrcR = 0; + state->gi[0] = 0; + state->gi[1] = 0; //zero out vc frequencies? state->p25_vc_freq[0] = 0; @@ -301,6 +303,8 @@ noCarrier (dsd_opts * opts, dsd_state * state) state->lastsrc = 0; state->lasttgR = 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->symbol_out_file[0] = 0; opts->lrrp_out_file[0] = 0; + opts->event_out_file[0] = 0; //csv import filenames opts->group_in_file[0] = 0; opts->lcn_in_file[0] = 0; @@ -942,6 +947,9 @@ initState (dsd_state * state) state->lastsrc = 0; state->lasttgR = 0; state->lastsrcR = 0; + state->gi[0] = 0; + state->gi[1] = 0; + state->eh_index = 0; state->nac = 0; state->errs = 0; state->errs2 = 0; @@ -1313,6 +1321,10 @@ initState (dsd_state * state) 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 void @@ -1779,7 +1791,7 @@ main (int argc, char **argv) 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) @@ -2142,6 +2154,12 @@ main (int argc, char **argv) fprintf (stderr,"Writing + Appending LRRP data to file %s\n", opts.lrrp_out_file); 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 strncpy(opts.wav_out_dir, optarg, 511); opts.wav_out_dir[511] = '\0'; diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c index 721884d..fdc7777 100644 --- a/src/dsd_ncurses.c +++ b/src/dsd_ncurses.c @@ -31,6 +31,8 @@ struct stat st_wav = {0}; static char alias_ch[10][50]; 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 tgR; @@ -59,24 +61,24 @@ char * FM_bannerN[9] = { }; char * SyncTypes[44] = { - "P25P1", - "P25P1", + "P25p1", + "P25p1", "X2TDMA DATA", "X2TDMA DATA", "X2TDMA VOICE", "X2TDMA VOICE", "DSTAR", //voice "DSTAR", //voice - "NXDN VOICE", - "NXDN VOICE", + "M17", + "M17", "DMR", //10 "DMR", "DMR", "DMR", "EDACS/PV", "EDACS/PV", - "NXDN VOICE", //DATA - "NXDN VOICE", //DATA + "M17 STR", //M17 Voice Stream + "M17 STR", //M17 Voice Stream "DSTAR", //header "DSTAR", //header "dPMR", //20 @@ -94,12 +96,12 @@ char * SyncTypes[44] = { "DMR", "DMR", "DMR", - "P25P2", - "P25P2", + "P25p2", + "P25p2", "EDACS/PV", //37 "EDACS/PV", //38 - "", - "" + "ANALOG", //39 Generic Sync Types + "DIGITAL" //40 Generic Sync Types }; char * DMRBusrtTypes[32] = { @@ -3823,7 +3825,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) } 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 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) { attron(COLOR_PAIR(4)); //cyan for history - printw ("--Call History----------------------------------------------------------------\n"); - for (short int j = 0; j < 10; j++) + printw ("--Latest Event History ([|])---Slot %d (\\)-------------------------------------\n", eh_slot+1); + 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 - 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) // + char text_string[2000]; + 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]); - char * datestrCH = getDateN(call_matrix[9-j][5]); - - 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"); + memcpy(text_string, state->event_history_s[slot].Event_History_Items[i].event_string, 71*sizeof(char)); + text_string[71] = 0; //terminate string + printw ("| #%02d %s \n", i, text_string); } - - //EDACS and ProVoice, outside of timestamp loop - if (call_matrix[j][0] == 14 || call_matrix[j][0] == 15 || call_matrix[j][0] == 37 || call_matrix[j][0] == 38 ) - { - 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 + sprintf (text_string, "%s", "BUMBLEBEETUNA"); + if (strncmp(text_string, state->event_history_s[slot].Event_History_Items[i].text_message, 13) != 0) + printw ("| %s \n", state->event_history_s[slot].Event_History_Items[i].text_message); + } printw ("------------------------------------------------------------------------------\n"); attroff(COLOR_PAIR(4)); //cyan for history } @@ -4798,6 +4590,28 @@ ncursesPrinter (dsd_opts * opts, dsd_state * 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 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 //needing an entry box, then stop all of those - - - //allocated memory pointer needs to be free'd if (timestr != NULL) { @@ -5084,3 +4895,402 @@ void ncursesClose () 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; + } +} diff --git a/src/dsd_rigctl.c b/src/dsd_rigctl.c index 810a440..e2efb8a 100644 --- a/src/dsd_rigctl.c +++ b/src/dsd_rigctl.c @@ -503,6 +503,8 @@ void return_to_cc (dsd_opts * opts, dsd_state * state) state->lasttgR = 0; state->lastsrc = 0; state->lastsrcR = 0; + state->gi[0] = 0; + state->gi[1] = 0; state->payload_algid = 0; state->payload_algidR = 0; state->payload_keyid = 0; diff --git a/src/dstar.c b/src/dstar.c index 1d4fdf2..3eb0941 100644 --- a/src/dstar.c +++ b/src/dstar.c @@ -49,6 +49,10 @@ void processDSTAR(dsd_opts * opts, dsd_state * state) if (opts->use_ncurses_terminal == 1) ncursesPrinter(opts, state); + //slot 1 + watchdog_event_history(opts, state, 0); + watchdog_event_current(opts, state, 0); + } fprintf (stderr, "\n"); diff --git a/src/edacs-fme.c b/src/edacs-fme.c index bb6c007..2a28bd6 100644 --- a/src/edacs-fme.c +++ b/src/edacs-fme.c @@ -374,6 +374,10 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn if (opts->use_ncurses_terminal == 1) ncursesPrinter(opts, state); + //slot 1 + watchdog_event_history(opts, state, 0); + watchdog_event_current(opts, state, 0); + //write to wav file if opened 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) } + //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 //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). @@ -2135,6 +2144,7 @@ void edacs(dsd_opts * opts, dsd_state * state) } + EDACS_END: if (timestr != NULL) { diff --git a/src/m17.c b/src/m17.c index 544eec2..013ad67 100644 --- a/src/m17.c +++ b/src/m17.c @@ -2466,6 +2466,10 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) if (opts->use_ncurses_terminal == 1) ncursesPrinter(opts, state); + //slot 1 + watchdog_event_history(opts, state, 0); + watchdog_event_current(opts, state, 0); + } //SEND EOTX to reflector @@ -3826,6 +3830,10 @@ void processM17IPF(dsd_opts * opts, dsd_state * state) if (opts->use_ncurses_terminal == 1) ncursesPrinter(opts, state); + //slot 1 + watchdog_event_history(opts, state, 0); + watchdog_event_current(opts, state, 0); + //clear frame memset (ip_frame, 0, sizeof(ip_frame)); diff --git a/src/p25p2_frame.c b/src/p25p2_frame.c index ad5ba34..5a9c7f2 100644 --- a/src/p25p2_frame.c +++ b/src/p25p2_frame.c @@ -1075,10 +1075,10 @@ void process_P2_DUID (dsd_opts * opts, dsd_state * state) state->payload_keyid = 0; state->payload_algidR = 0; state->payload_keyidR = 0; - state->lastsrc = 0; - state->lastsrcR = 0; - state->lasttg = 0; - state->lasttgR = 0; + // state->lastsrc = 0; //disable? + // state->lastsrcR = 0; //disable? + // state->lasttg = 0; //disable? + // state->lasttgR = 0; //disable? state->p2_is_lcch = 0; state->fourv_counter[0] = 0; state->fourv_counter[1] = 0; @@ -1092,6 +1092,15 @@ void process_P2_DUID (dsd_opts * opts, dsd_state * 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 vc_counter = vc_counter + 360; diff --git a/src/p25p2_xcch.c b/src/p25p2_xcch.c index 06a052d..ff9cabb 100644 --- a/src/p25p2_xcch.c +++ b/src/p25p2_xcch.c @@ -127,12 +127,15 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180] state->dmrburstL = 20; fprintf (stderr, "\n VCH 0 - "); - - state->lastsrc = (SMAC[13] << 16) | (SMAC[14] << 8) | SMAC[15]; + //check that src is not zero first, some harris and other patch systems may do this, + //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]; 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 @@ -195,12 +198,15 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180] state->dmrburstR = 20; fprintf (stderr, "\n VCH 1 - "); - - state->lastsrcR = (SMAC[13] << 16) | (SMAC[14] << 8) | SMAC[15]; + //check that src is not zero first, some harris and other patch systems may do this, + //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]; fprintf (stderr, "TG %d ", state->lasttgR); - fprintf (stderr, "SRC %d ", state->lastsrcR); + fprintf (stderr, "SRC %d ", src); // 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; fprintf (stderr, "\n VCH 0 - "); - - state->lastsrc = (FMAC[13] << 16) | (FMAC[14] << 8) | FMAC[15]; + //check that src is not zero first, some harris and other patch systems may do this, + //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]; fprintf (stderr, "TG %d ", state->lasttg); - fprintf (stderr, "SRC %d ", state->lastsrc); + fprintf (stderr, "SRC %d ", src); // 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; fprintf (stderr, "\n VCH 1 - "); - - state->lastsrcR = (FMAC[13] << 16) | (FMAC[14] << 8) | FMAC[15]; + //check that src is not zero first, some harris and other patch systems may do this, + //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]; fprintf (stderr, "TG %d ", state->lasttgR); - fprintf (stderr, "SRC %d ", state->lastsrcR); + fprintf (stderr, "SRC %d ", src); // if (state->lastsrcR == 0) fprintf (stderr, "External ");