From 114e305e254e640acc21fdb6c754ec0f3e20f99f Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Sat, 26 Apr 2025 23:34:15 -0400 Subject: [PATCH] New Event History Setup and Logging to a Log File, part 3; #287 Add Extra Call Information to Event History and Display to Ncurses and Write to Event Log; Add P25 Known Talker Alias Formats to Event History and Display to Ncurses and Write to Event Log; Remake the DMR Talker Alias Decoder for 7, 8, and 16 bit chars and go to Event History and Display and to Ncurses and Write to Event Log; Add Some Embeddded and Misc (Non Data Call) GPS Formats to Event History and Display to Ncurses and Write to Event Log; Add DMR UDT Data Calls to Event History; Make Misc Tweaks to Event Item Strings; --- include/dsd.h | 14 ++-- src/dmr_block.c | 54 +++++++++++- src/dmr_dburst.c | 3 - src/dmr_flco.c | 132 ++++++++---------------------- src/dmr_pdu.c | 2 +- src/dsd_alias.c | 199 ++++++++++++++++++++++++++++++++++++++++++++- src/dsd_gps.c | 42 ++++++++-- src/dsd_main.c | 18 ++-- src/dsd_ncurses.c | 161 +++++++++++++++++------------------- src/dsd_rigctl.c | 4 +- src/nxdn_element.c | 8 +- src/p25_lcw.c | 7 ++ src/p25p1_ldu1.c | 4 +- src/p25p1_ldu2.c | 6 +- src/p25p2_vpdu.c | 4 + 15 files changed, 436 insertions(+), 222 deletions(-) diff --git a/include/dsd.h b/include/dsd.h index ae126d9..7e531c6 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -98,7 +98,7 @@ typedef struct { uint32_t sys_id3; //conventional may only use NAC, RAN, or Color Codes uint32_t sys_id4; // uint32_t sys_id5; // - uint8_t gi; //group or individual + int8_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) @@ -581,7 +581,7 @@ typedef struct int lasttgR; int lastsrc; int lastsrcR; - uint8_t gi[2]; //group, or private call, per slot + int8_t gi[2]; //group, or private call, per slot uint8_t eh_index; int nac; int errs; @@ -724,7 +724,8 @@ typedef struct //dmr talker alias new/fixed stuff uint8_t dmr_alias_format[2]; //per slot - uint8_t dmr_alias_len[2]; //per slot + uint8_t dmr_alias_block_len[2]; //per slot + uint8_t dmr_alias_char_size[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][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 @@ -1337,15 +1338,16 @@ void beeper (dsd_opts * opts, dsd_state * state, int lr); //the tone beeper func void dmr_gateway_identifier (uint32_t source, uint32_t target); //translate special addresses //Embedded Alias and GPS reports -void dmr_embedded_alias_header (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[]); -void dmr_embedded_alias_blocks (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[]); +void dmr_talker_alias_lc_header (dsd_opts * opts, dsd_state * state, uint8_t slot, uint8_t * lc_bits); +void dmr_talker_alias_lc_blocks (dsd_opts * opts, dsd_state * state, uint8_t slot, uint8_t block_num, uint8_t * lc_bits); +void dmr_talker_alias_lc_decode (dsd_opts * opts, dsd_state * state, uint8_t slot, uint8_t block_num, uint8_t char_size, uint16_t end); void apx_embedded_alias_test_phase1 (dsd_opts * opts, dsd_state * state); void apx_embedded_alias_header_phase1 (dsd_opts * opts, dsd_state * state, uint8_t slot, uint8_t * lc_bits); void apx_embedded_alias_header_phase2 (dsd_opts * opts, dsd_state * state, uint8_t slot, uint8_t * lc_bits); void apx_embedded_alias_blocks_phase1 (dsd_opts * opts, dsd_state * state, uint8_t slot, uint8_t * lc_bits); void apx_embedded_alias_blocks_phase2 (dsd_opts * opts, dsd_state * state, uint8_t slot, uint8_t * lc_bits); void apx_embedded_alias_decode (dsd_opts * opts, dsd_state * state, uint8_t slot, int16_t num_bits, uint8_t * input); -void apx_embedded_alias_dump (dsd_opts * opts, dsd_state * state, uint16_t num_bytes, uint8_t * input, uint8_t * decoded); +void apx_embedded_alias_dump (dsd_opts * opts, dsd_state * state, uint8_t slot, uint16_t num_bytes, uint8_t * input, uint8_t * decoded); void l3h_embedded_alias_blocks_phase1 (dsd_opts * opts, dsd_state * state, uint8_t slot, uint8_t * lc_bits); void l3h_embedded_alias_decode (dsd_opts * opts, dsd_state * state, uint8_t slot, int16_t len, uint8_t * input); void tait_iso7_embedded_alias_decode (dsd_opts * opts, dsd_state * state, uint8_t slot, int16_t len, uint8_t * input); diff --git a/src/dmr_block.c b/src/dmr_block.c index 9fab993..91bde0d 100644 --- a/src/dmr_block.c +++ b/src/dmr_block.c @@ -553,6 +553,10 @@ void dmr_udt_decoder (dsd_opts * opts, dsd_state * state, uint8_t * block_bytes, //LIP Debug Testing (need real world samples) // udt_format2 = 0x0B; + //WIP: Add this to event history //TODO: Double check len values on Text Messages + char udt_string[500]; memset (udt_string, 0, sizeof(udt_string)); + sprintf (udt_string, "UDT SRC: %d; TGT: %d; ", udt_source, udt_target); + //initial linebreak fprintf (stderr, "%s", KCYN); fprintf (stderr, "\n "); @@ -561,10 +565,12 @@ void dmr_udt_decoder (dsd_opts * opts, dsd_state * state, uint8_t * block_bytes, if (udt_format2 == 0x00) { fprintf (stderr, "Binary Data;"); + strcat (udt_string, "Binary Data; "); } else if (udt_format2 == 0x01) //appended addresses { fprintf (stderr, "Appended Addressing;\n "); + strcat (udt_string, "Appended Addressing; "); if (udt_uab == 1) end = 3; if (udt_uab == 2) end = 7; if (udt_uab == 3) end = 11; @@ -586,6 +592,7 @@ void dmr_udt_decoder (dsd_opts * opts, dsd_state * state, uint8_t * block_bytes, end -= udt_padnib; //subtract padnib since its also 4 bits fprintf (stderr, "Dialer BCD: "); + strcat (udt_string, "Dialer Digits: "); for (i = 0; i < end; i++) { //dialer digits 7.2.9 @@ -595,6 +602,20 @@ void dmr_udt_decoder (dsd_opts * opts, dsd_state * state, uint8_t * block_bytes, else if (digit == 11) fprintf (stderr, "#"); //pound/hash else if (digit == 15) fprintf (stderr, " "); //null character else fprintf (stderr, "R:%X", digit); //reserved values on 12,13, and 14 + + char dc[2]; dc[1] = 0; + if (digit < 10) + dc[0] = digit + 0x30; + else if (digit == 10) + dc[0] = 0x2A; + else if (digit == 11) + dc[0] = 0x23; + else if (digit == 15) + dc[0] = 0x20; + else //if 12, 13, 14, convert to its HEX letter representative C, D, or E + dc[0] = digit + 0x38; + + strcat (udt_string, dc); } } else if (udt_format2 == 0x03) //ISO7 format @@ -605,17 +626,23 @@ void dmr_udt_decoder (dsd_opts * opts, dsd_state * state, uint8_t * block_bytes, if (udt_uab == 4) end = 52; end -= udt_padnib/7; //is this correct? fprintf (stderr, "ISO7 Text: " ); + strcat (udt_string, "ISO7 Text: "); for (i = 0; i < end; i++) //max 368/7 = 52 character max? { iso7c = (uint8_t)ConvertBitIntoBytes(&cs_bits[(i*7)+96], 7); + char i7c[2]; i7c[0] = iso7c; i7c[1] = 0; if (iso7c >= 0x20 && iso7c <= 0x7E) //Standard ASCII Set + { fprintf (stderr, "%c", iso7c); + strcat (udt_string, i7c); + } else fprintf (stderr, " "); } } else if (udt_format2 == 0x04) //ISO8 format { fprintf (stderr, "ISO8 Text: " ); + strcat (udt_string, "ISO8 Text: "); if (udt_uab == 1) end = 10; if (udt_uab == 2) end = 22; if (udt_uab == 3) end = 34; @@ -624,8 +651,13 @@ void dmr_udt_decoder (dsd_opts * opts, dsd_state * state, uint8_t * block_bytes, for (i = 0; i < end; i++) { iso8c = (uint8_t)ConvertBitIntoBytes(&cs_bits[(i*8)+96], 8); + char i8c[2]; i8c[0] = iso8c; i8c[1] = 0; if (iso8c >= 0x20 && iso8c <= 0x7E) //Standard ASCII Set + { fprintf (stderr, "%c", iso8c); + strcat (udt_string, i8c); + } + // else if (iso8c >= 0x81 && iso8c <= 0xFE) //Extended ASCII Set // fprintf (stderr, "%c", iso8c); else fprintf (stderr, " "); @@ -639,11 +671,17 @@ void dmr_udt_decoder (dsd_opts * opts, dsd_state * state, uint8_t * block_bytes, if (udt_uab == 4) end = 23; end -= udt_padnib/4; //example, 4 blocks sets 23 - (20nibs/4bits) = 18 chars, may need to check this again fprintf (stderr, "UTF16 Text: " ); + strcat (udt_string, "UTF16 Text: "); for (i = 0; i < end; i++) //368/16 = 23 character max? { utf16c = (uint16_t)ConvertBitIntoBytes(&cs_bits[(i*16)+96], 16); + char u16[2]; u16[0] = utf16c & 0xFF; u16[1] = 0; if (utf16c >= 0x20 && utf16c != 0x7F) //avoid control chars + { fprintf (stderr, "%lc", utf16c); //will using lc work here? May depend on console locale settings? + strcat (udt_string, u16); + } + else fprintf (stderr, " "); } } @@ -656,6 +694,7 @@ void dmr_udt_decoder (dsd_opts * opts, dsd_state * state, uint8_t * block_bytes, fprintf (stderr, "%d.",(uint8_t)ConvertBitIntoBytes(&cs_bits[96+8], 8)); fprintf (stderr, "%d.",(uint8_t)ConvertBitIntoBytes(&cs_bits[96+16], 8)); fprintf (stderr, "%d", (uint8_t)ConvertBitIntoBytes(&cs_bits[96+24], 8)); + strcat (udt_string, "IP4; "); } else //IP6 { @@ -668,6 +707,7 @@ void dmr_udt_decoder (dsd_opts * opts, dsd_state * state, uint8_t * block_bytes, fprintf (stderr, "%04X:",(uint16_t)ConvertBitIntoBytes(&cs_bits[96+72], 16)); fprintf (stderr, "%04X:",(uint16_t)ConvertBitIntoBytes(&cs_bits[96+88], 16)); fprintf (stderr, "%04X", (uint16_t)ConvertBitIntoBytes(&cs_bits[96+104], 16)); + strcat (udt_string, "IP6; "); } } else if (udt_format2 == 0x0A) //Mixed Address/UTF-16BE @@ -679,11 +719,17 @@ void dmr_udt_decoder (dsd_opts * opts, dsd_state * state, uint8_t * block_bytes, end -= udt_padnib/4; //is this correct? fprintf (stderr, "Address: %d", (uint32_t)ConvertBitIntoBytes(&cs_bits[96+8], 24)); fprintf (stderr, "Text: " ); + strcat (udt_string, "UTF16 Text: "); for (i = 0; i < end; i++) //368/16 = 21 character max { utf16c = (uint16_t)ConvertBitIntoBytes(&cs_bits[(i*16)+96], 16); + char u16[2]; u16[0] = utf16c & 0xFF; u16[1] = 0; if (utf16c >= 0x20 && utf16c != 0x7F) //avoid control chars + { fprintf (stderr, "%lc", utf16c); + strcat (udt_string, u16); + } + else fprintf (stderr, " "); } } @@ -691,6 +737,7 @@ void dmr_udt_decoder (dsd_opts * opts, dsd_state * state, uint8_t * block_bytes, { //Would be nice to be able to test these all out to make sure the conditions are okay, etc fprintf (stderr, "NMEA" ); + // strcat (udt_string, "NMEA; "); if (cs_bits[96] == 1) //check if its encrypted first fprintf (stderr, " Encrypted Format :(" ); //sad face else if (udt_uab == 1) @@ -710,19 +757,24 @@ void dmr_udt_decoder (dsd_opts * opts, dsd_state * state, uint8_t * block_bytes, //type bit to be read and then to decode accordingly, this assumes its the modified Short PDU that USBD uses fprintf (stderr, "\n"); lip_protocol_decoder (opts, state, cs_bits+96); //start on first appended block, and not header + // strcat (udt_string, "LIP; "); } else if (udt_format2 == 0x08 || udt_format2 == 0x09) { fprintf (stderr, "MFID SPEC %02X: ", udt_format2); //use -Z to expose this + strcat (udt_string, "MFID Specific; "); } else { fprintf (stderr, "Reserved %02X: ", udt_format2); + strcat (udt_string, "Reserved; "); //use -Z to expose this } fprintf (stderr, "%s", KNRM); + + watchdog_event_datacall (opts, state, udt_source, udt_target, udt_string, slot); } //assemble the blocks as they come in, shuffle them into the unified dmr_pdu_sf @@ -1378,7 +1430,7 @@ void dmr_block_assembler (dsd_opts * opts, dsd_state * state, uint8_t block_byte void dmr_reset_blocks (dsd_opts * opts, dsd_state * state) { UNUSED(opts); - + memset (state->gi, -1, sizeof(state->gi)); memset (state->data_p_head, 0, sizeof(state->data_p_head)); memset (state->data_conf_data, 0, sizeof(state->data_conf_data)); memset (state->dmr_pdu_sf, 0, sizeof(state->dmr_pdu_sf)); diff --git a/src/dmr_dburst.c b/src/dmr_dburst.c index 6ab3151..ac78c10 100644 --- a/src/dmr_dburst.c +++ b/src/dmr_dburst.c @@ -11,9 +11,6 @@ //TODO: Test USBD LIP Decoder with Real World Samples (if/when available) //TODO: Test UDT NMEA and LIP Decoders with Real World Samples (if/when available) -//WIP: Move all extra decoders for location, etc, to a new file and add prototypes to dsd.h -//DONE: Test CRC9/CRC32 on Rate 1 Data with Real World Samples (if/when available) -//TODO: Address areas that require reading of ISO7, ISO8, and UTF-16 string formats #include "dsd.h" diff --git a/src/dmr_flco.c b/src/dmr_flco.c index 23d273f..2eee74d 100644 --- a/src/dmr_flco.c +++ b/src/dmr_flco.c @@ -103,14 +103,15 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C //Embedded Talker Alias Header Only (format and len storage) if ( (fid == 0 || fid == 0x68) && type == 3 && flco == 0x04) { - dmr_embedded_alias_header(opts, state, lc_bits); + is_alias = 1; + dmr_talker_alias_lc_header(opts, state, slot, lc_bits); } //Embedded Talker Alias Header (continuation) and Blocks - if ( (fid == 0 || fid == 0x68) && type == 3 && flco > 0x03 && flco < 0x08) + if ( (fid == 0 || fid == 0x68) && type == 3 && flco > 0x04 && flco < 0x08) { is_alias = 1; - dmr_embedded_alias_blocks(opts, state, lc_bits); + dmr_talker_alias_lc_blocks(opts, state, slot, flco-5, lc_bits); } //Embedded GPS @@ -127,6 +128,9 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C capsite = (uint8_t)ConvertBitIntoBytes(&lc_bits[48], 4); //don't believe so restchannel = (int)ConvertBitIntoBytes(&lc_bits[52], 4); // source = (uint32_t)ConvertBitIntoBytes(&lc_bits[56], 16); + if (flco == 0x07) + state->gi[slot] = 1; + else state->gi[slot] = 0; } //Unknown CapMax/Moto Things @@ -410,6 +414,13 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C //reset gain if (opts->floating_point == 1) state->aout_gain = opts->audio_gain; + + state->dmr_alias_block_len[0] = 0; + state->dmr_alias_char_size[0] = 0; + state->dmr_alias_format[0] = 0; + sprintf (state->generic_talker_alias[0], "%s", ""); + // sprintf (state->event_history_s[0].Event_History_Items[0].alias, "%s", "BUMBLEBEETUNA"); + memset (state->dmr_pdu_sf[0], 0, sizeof(state->dmr_pdu_sf[0])); } if (state->currentslot == 1) { @@ -423,6 +434,13 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C //reset gain if (opts->floating_point == 1) state->aout_gainR = opts->audio_gain; + + state->dmr_alias_block_len[1] = 0; + state->dmr_alias_char_size[1] = 0; + state->dmr_alias_format[1] = 0; + sprintf (state->generic_talker_alias[1], "%s", ""); + // sprintf (state->event_history_s[1].Event_History_Items[0].alias, "%s", "BUMBLEBEETUNA"); + memset (state->dmr_pdu_sf[1], 0, sizeof(state->dmr_pdu_sf[1])); } } @@ -468,23 +486,27 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C // strcat (state->call_string[slot], " Grp"); sprintf (state->call_string[slot], " Group "); fprintf (stderr, "Group "); + state->gi[slot] = 0; } else { // strcat (state->call_string[slot], " Pri"); sprintf (state->call_string[slot], " Private "); fprintf (stderr, "Private "); + state->gi[slot] = 1; } } else if (flco == 0x3) //UU_V_Ch_Usr { sprintf (state->call_string[slot], " Private "); fprintf (stderr, "Private "); + state->gi[slot] = 1; } else //Grp_V_Ch_Usr -- still valid on hytera VLC { sprintf (state->call_string[slot], " Group "); fprintf (stderr, "Group "); + state->gi[slot] = 0; } if(so & 0x80) @@ -604,8 +626,16 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C //should rework this back into the upper portion if (fid == 0x68) fprintf (stderr, "Hytera "); if (is_xpt) fprintf (stderr, "XPT "); - if (fid == 0x68 && flco == 0x00) fprintf (stderr, "Group "); - if (fid == 0x68 && flco == 0x03) fprintf (stderr, "Private "); + if (fid == 0x68 && flco == 0x00) + { + fprintf (stderr, "Group "); + state->gi[slot] = 0; + } + if (fid == 0x68 && flco == 0x03) + { + fprintf (stderr, "Private "); + state->gi[slot] = 1; + } fprintf(stderr, "Call "); @@ -1244,95 +1274,3 @@ void dmr_slco (dsd_opts * opts, dsd_state * state, uint8_t slco_bits[]) fprintf (stderr, "%s", KNRM); } - -//externalize embedded alias to keep the flco function relatively clean -void dmr_embedded_alias_header (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[]) -{ - UNUSED(opts); - - uint8_t slot = state->currentslot; - uint8_t format = (uint8_t)ConvertBitIntoBytes(&lc_bits[16], 2); - uint8_t len; - - //this len seems to pertain to number of blocks? not bit len. - //len = (uint8_t)ConvertBitIntoBytes(&lc_bits[18], 5); - - if (format == 0) len = 7; - else if (format == 1 || format == 2) len = 8; - else len = 16; - - state->dmr_alias_format[slot] = format; - state->dmr_alias_len[slot] = len; - - //fprintf (stderr, "F: %d L: %d - ", format, len); - -} - -void dmr_embedded_alias_blocks (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[]) -{ - UNUSED(opts); - - fprintf (stderr, "%s", KYEL); - fprintf (stderr, " Embedded Alias: "); - uint8_t slot = state->currentslot; - uint8_t block = (uint8_t)ConvertBitIntoBytes(&lc_bits[2], 6); //FLCO equals block number - uint8_t format = state->dmr_alias_format[slot]; //0=7-bit; 1=ISO8; 2=UTF-8; 3=UTF16BE - uint8_t len = state->dmr_alias_len[slot]; - uint8_t start; //starting position depends on context of block and format - UNUSED(format); - - //Cap Max Variation - uint8_t fid = (uint8_t)ConvertBitIntoBytes(&lc_bits[8], 8); - if (fid == 0x10) block = block - 0x10; //CapMax adds 0x10 to its FLCO (block num) in its Embedded Aliasing - - //there is some issue with the next three lines of code that prevent proper assignments, not sure what. - //if (block > 4) start = 16; - //else if (block == 4 && format > 0) start = 23; //8-bit and 16-bit chars - //else start = 24; - - //forcing start to 16 make it work on 8-bit alias, len seems okay when set off of format - start = 16; - len = 8; - - // fprintf (stderr, "block: %d start: %d len: %d ", block, start, len); - - //all may not be used depending on format, len, start. - uint16_t A0, A1, A2, A3, A4, A5, A6; - - //sanity check - if (block > 7) block = 4; //prevent oob array (although we should never get here) - - if (len > 6) //if not greater than zero, then the header hasn't arrived yet - { - A0 = 0; A1 = 0; A2 = 0; A3 = 0; A4 = 0; A5 = 0; A6 = 0; //NULL ASCII Characters - A0 = (uint16_t)ConvertBitIntoBytes(&lc_bits[start+len*0], len); - A1 = (uint16_t)ConvertBitIntoBytes(&lc_bits[start+len*1], len); - A2 = (uint16_t)ConvertBitIntoBytes(&lc_bits[start+len*2], len); - A3 = (uint16_t)ConvertBitIntoBytes(&lc_bits[start+len*3], len); - A4 = (uint16_t)ConvertBitIntoBytes(&lc_bits[start+len*4], len); - A5 = (uint16_t)ConvertBitIntoBytes(&lc_bits[start+len*5], len); - A6 = (uint16_t)ConvertBitIntoBytes(&lc_bits[start+len*6], len); - - //just going to assign the usual ascii set here to prevent 'naughty' characters, sans diacriticals - if (A0 > 0x19 && A0 < 0x7F) sprintf (state->dmr_alias_block_segment[slot][block-4][0], "%c", A0); - if (A1 > 0x19 && A1 < 0x7F) sprintf (state->dmr_alias_block_segment[slot][block-4][1], "%c", A1); - if (A2 > 0x19 && A2 < 0x7F) sprintf (state->dmr_alias_block_segment[slot][block-4][2], "%c", A2); - if (A3 > 0x19 && A3 < 0x7F) sprintf (state->dmr_alias_block_segment[slot][block-4][3], "%c", A3); - if (A4 > 0x19 && A4 < 0x7F) sprintf (state->dmr_alias_block_segment[slot][block-4][4], "%c", A4); - if (A5 > 0x19 && A5 < 0x7F) sprintf (state->dmr_alias_block_segment[slot][block-4][5], "%c", A5); - if (A6 > 0x19 && A6 < 0x7F) sprintf (state->dmr_alias_block_segment[slot][block-4][6], "%c", A6); - - for (int i = 0; i < 4; i++) - { - for (int j = 0; j < 7; j++) - { - fprintf (stderr, "%s", state->dmr_alias_block_segment[slot][i][j]); - } - } - - - } - else fprintf (stderr, "Missing Header Block Format and Len Data"); - fprintf (stderr, "%s", KNRM); - -} diff --git a/src/dmr_pdu.c b/src/dmr_pdu.c index 57b7a40..545dc1b 100644 --- a/src/dmr_pdu.c +++ b/src/dmr_pdu.c @@ -248,7 +248,7 @@ void dmr_udp_comp_pdu (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t 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]); + sprintf (comp_string, "IPC: %d; OP: %d; SRC: %d:%d (%s):(%s); DST: %d:%d (%s):(%s); ", ipid, opcode, said, spid, addrstring[0], portstring[0], daid, dpid, addrstring[1], portstring[1]); watchdog_event_datacall (opts, state, said, daid, comp_string, slot); } diff --git a/src/dsd_alias.c b/src/dsd_alias.c index 6138b17..8275375 100644 --- a/src/dsd_alias.c +++ b/src/dsd_alias.c @@ -398,16 +398,17 @@ void apx_embedded_alias_decode (dsd_opts * opts, dsd_state * state, uint8_t slot for (int16_t i = 0; i < num_bytes/2; i++) fprintf (stderr, "%lc", ((decoded[(i*2)+0])<<8) | ((decoded[(i*2)+1])<<0) ); - apx_embedded_alias_dump (opts, state, num_bytes, input, decoded); + apx_embedded_alias_dump (opts, state, slot, num_bytes, input, decoded); } } -void apx_embedded_alias_dump (dsd_opts * opts, dsd_state * state, uint16_t num_bytes, uint8_t * input, uint8_t * decoded) +void apx_embedded_alias_dump (dsd_opts * opts, dsd_state * state, uint8_t slot, uint16_t num_bytes, uint8_t * input, uint8_t * decoded) { char str[50]; memset(str, 0, sizeof(str)); + char fqs[50]; memset(fqs, 0, sizeof(fqs)); //check num_bytes, if greter than 100, then set to 100 if (num_bytes >= 98) num_bytes = 98; @@ -429,6 +430,13 @@ void apx_embedded_alias_dump (dsd_opts * opts, dsd_state * state, uint16_t num_b uint32_t sys = (uint32_t)ConvertBitIntoBytes(&input[92], 12); uint32_t rid = (uint32_t)ConvertBitIntoBytes(&input[104], 24); + sprintf (fqs, " FQ-SUID: %05X:%03X.%06X (%d);", wacn, sys, rid, rid); + if (rid != 0 && state->event_history_s[slot].Event_History_Items[0].source_id == rid) + { + sprintf (state->event_history_s[slot].Event_History_Items[0].alias, "%s; ", str); + strcat (state->event_history_s[slot].Event_History_Items[0].alias, fqs); + } + for (int16_t i = 0; i < state->group_tally; i++) { if (state->group_array[i].groupNumber == rid) @@ -516,6 +524,9 @@ void l3h_embedded_alias_decode (dsd_opts * opts, dsd_state * state, uint8_t slot //assign completed talker to a more useful string instead snprintf (str, ptr+1, "%s", ttemp); + if (state->event_history_s[slot].Event_History_Items[0].source_id == tsrc) + sprintf (state->event_history_s[slot].Event_History_Items[0].alias, "%s", str); + //The Duke Energy system may relay two src values, may be a good idea to pick one and stick with it if (tsrc != 0) { @@ -578,6 +589,9 @@ void tait_iso7_embedded_alias_decode (dsd_opts * opts, dsd_state * state, uint8_ uint32_t rid = state->lastsrc; uint16_t nac = state->nac; + if (state->event_history_s[slot].Event_History_Items[0].source_id == rid) + sprintf (state->event_history_s[slot].Event_History_Items[0].alias, "%s", alias); + if (rid != 0) { for (int16_t i = 0; i < state->group_tally; i++) @@ -612,4 +626,185 @@ void tait_iso7_embedded_alias_decode (dsd_opts * opts, dsd_state * state, uint8_ } } +} + +void dmr_talker_alias_lc_header (dsd_opts * opts, dsd_state * state, uint8_t slot, uint8_t * lc_bits) +{ + uint8_t format = (uint8_t)ConvertBitIntoBytes(&lc_bits[16], 2); + uint8_t block_len = (uint8_t)ConvertBitIntoBytes(&lc_bits[18], 5); + uint8_t char_size = 0; + + if (format == 0) char_size = 7; + else if (format == 1 || format == 2) char_size = 8; + else char_size = 16; + + state->dmr_alias_format[slot] = format; + state->dmr_alias_block_len[slot] = block_len; //data len, see below + state->dmr_alias_char_size[slot] = char_size; + + //load into dmr_pdu_sf as bit wise values for this since iso7 has 49 bits in this header, otherwise, load with 48? + if (char_size == 7) + memcpy(state->dmr_pdu_sf[slot], lc_bits+23, 49*sizeof(uint8_t)); + else if (char_size == 8) + memcpy(state->dmr_pdu_sf[slot], lc_bits+24, 48*sizeof(uint8_t)); + else if (char_size == 16) + memcpy(state->dmr_pdu_sf[slot], lc_bits+24, 48*sizeof(uint8_t)); + + //TEST: The Block Len (Data Lan) value is, according to my interpretation, the number of encoded + //character units in the alias, test to verify, but fall back to the ptr index if necessary + //this is referenced in 5.4.3 ETSI TS 102 361-2 V2.5.1 (2023-05) 7.2.19 Talker Alias Data Length + + fprintf (stderr, " Slot %d - Talker Alias LC Header; Format %d; Char Len: %d; Char Size: %d;", slot, format, block_len, char_size); + + //Decode the header's alias portion + fprintf (stderr, "\n"); + dmr_talker_alias_lc_decode(opts, state, slot, 0, char_size, block_len); +} + +void dmr_talker_alias_lc_blocks (dsd_opts * opts, dsd_state * state, uint8_t slot, uint8_t block_num, uint8_t * lc_bits) +{ + UNUSED(opts); //delete if we don't use this, but may want it if we dump alias to a file later on + uint8_t block_len = state->dmr_alias_block_len[slot]; + uint8_t char_size = state->dmr_alias_char_size[slot]; + uint16_t ptr = 0; + uint16_t end = block_len; + + //Note: The Joann sample only carries block 5, and no header on block 4 + //another radio on that ham setup also has a broken alias similar, but + //the other talkers have the 04 and the sample has a good decode otherwise + //debug broken aliasing on ham radio + + // if (char_size == 0) //Enable this is you need to check alias even with missing header (set 7, 8, or 16) + // char_size = 8; + + /* + 22:54:51 Sync: +DMR slot1 [SLOT2] | Color Code=01 | VC6 + Slot 1 - Talker Alias Block Num: 1; Valid Block; Talker Alias: Joann + DMR PDU Payload [05][00][4A][6F][61][6E][6E][00][FF] + */ + + //set the pointer to the current index of the dmr_pdu_sf + if (char_size == 16) + ptr = 48 + (block_num * 48); + else if (char_size == 8) + ptr = 48 + (block_num * 48); + else if (char_size == 7) + ptr = 49 + (block_num * 56); + + if (char_size == 0) //unset, no header received + fprintf (stderr, " Slot %d - Talker Alias Block Num: %d; Invalid Header;", slot, block_num+1); + + else if (block_num > 3) //invalid block (data error) + fprintf (stderr, " Slot %d - Talker Alias Block Num: %d; Invalid Block;", slot, block_num+1); + + else //valid header present, continue + { + if (char_size == 7) + { + memcpy(state->dmr_pdu_sf[slot]+ptr, lc_bits+16, 56*sizeof(uint8_t)); + ptr += 56; + if (block_len == 0) + end = ptr / 7; + else end = block_len; + } + else if (char_size == 8) + { + memcpy(state->dmr_pdu_sf[slot]+ptr, lc_bits+16, 56*sizeof(uint8_t)); + ptr += 56; + if (block_len == 0) + end = ptr / 8; + else end = block_len; + } + else if (char_size == 16) + { + memcpy(state->dmr_pdu_sf[slot]+ptr, lc_bits+16, 48*sizeof(uint8_t)); + ptr += 48; + if (block_len == 0) + end = ptr / 16; + else end = block_len; + } + + dmr_talker_alias_lc_decode (opts, state, slot, block_num, char_size, end); + } +} + +//Deocde partial or comppleted alias +void dmr_talker_alias_lc_decode (dsd_opts * opts, dsd_state * state, uint8_t slot, uint8_t block_num, uint8_t char_size, uint16_t end) +{ + UNUSED(opts); + uint16_t i = 0; + fprintf (stderr, " Slot %d - Talker Alias Block Num: %d; Valid Block;", slot, block_num+1); + fprintf (stderr, " Talker Alias: "); + + char alias_string[500]; memset (alias_string, 0, sizeof(alias_string)); + sprintf (alias_string, ""); + + if (char_size == 7) + { + for (i = 0; i < end; i++) + { + uint8_t character = (uint8_t)ConvertBitIntoBytes(&state->dmr_pdu_sf[slot][(i*7)], 7); + char ch[2]; ch[0] = character; ch[1] = 0; + if (character >= 0x20 && character <= 0x7E) //Standard ASCII Set + { + fprintf (stderr, "%c", character); + strcat (alias_string, ch); + } + else + { + strcat (alias_string, " "); + fprintf (stderr, " "); + } + } + } + else if (char_size == 8) + { + for (i = 0; i < end; i++) + { + uint8_t character = (uint8_t)ConvertBitIntoBytes(&state->dmr_pdu_sf[slot][(i*8)], 8); + char ch[2]; ch[0] = character; ch[1] = 0; + if (character >= 0x20 && character <= 0x7E) //Standard ASCII Set + { + fprintf (stderr, "%c", character); + strcat (alias_string, ch); + } + else + { + strcat (alias_string, " "); + fprintf (stderr, " "); + } + } + } + else if (char_size == 16) + { + for (i = 0; i < end; i++) + { + uint16_t character = (uint16_t)ConvertBitIntoBytes(&state->dmr_pdu_sf[slot][(i*16)], 16); + char ch[2]; ch[0] = character & 0xFF; ch[1] = 0; + if (character >= 0x20 && character <= 0x7E) //Standard ASCII Set //may see what happens if this is disabled + { + fprintf (stderr, "%lc", character); + strcat (alias_string, ch); + } + else + { + strcat (alias_string, " "); + fprintf (stderr, " "); + } + + //debug + // fprintf (stderr, " %04X, ", character); + } + } + + //assign to string for event history and ncurses display + uint32_t source = 0; + if (slot == 0) + source = state->lastsrc; + else source = state->lastsrcR; + + if (state->event_history_s[slot].Event_History_Items[0].source_id == source) + sprintf (state->event_history_s[slot].Event_History_Items[0].alias, "%s; ", alias_string); + sprintf (state->generic_talker_alias[slot], "Talker Alias: %s; ", alias_string); + } \ No newline at end of file diff --git a/src/dsd_gps.c b/src/dsd_gps.c index 8b28ca5..9ece08b 100644 --- a/src/dsd_gps.c +++ b/src/dsd_gps.c @@ -15,6 +15,12 @@ void lip_protocol_decoder (dsd_opts * opts, dsd_state * state, uint8_t * input) int slot = state->currentslot; + //May need to set this in the UDT header, or pass it into this function to be sure + uint32_t src = 0; + if (slot == 0) + src = state->lastsrc; + else src = state->lastsrcR; + //NOTE: This format is pretty much the same as DMR EMB GPS, but has a few extra elements, //so I got lazy and just lifted most of the code from there, also assuming same lat/lon calcs //since those have been tested to work in DMR EMB GPS and units are same in LIP @@ -115,6 +121,10 @@ void lip_protocol_decoder (dsd_opts * opts, dsd_state * state, uint8_t * input) } else sprintf (state->dmr_embedded_gps[slot], "%03d; LIP: %.5lf%s%s %.5lf%s%s Unknown Pos Err; Spd: %d km/h; Dir %d%s", add_hash, latitude, deg_glyph, latstr, longitude, deg_glyph, lonstr, vt, dt, deg_glyph); + //save to event history string + if (state->event_history_s[slot].Event_History_Items[0].source_id == src) + sprintf (state->event_history_s[slot].Event_History_Items[0].gps_s, "%s", state->dmr_embedded_gps[slot]); + //save to LRRP report for mapping/logging FILE * pFile; //file pointer if (opts->lrrp_file_output == 1) @@ -230,6 +240,10 @@ void nmea_iec_61162_1 (dsd_opts * opts, dsd_state * state, uint8_t * input, uint //save to ncurses string sprintf (state->dmr_embedded_gps[slot], "GPS: (%f%s, %f%s)", latitude, deg_glyph, longitude, deg_glyph); + //save to event history string + if (state->event_history_s[slot].Event_History_Items[0].source_id == src) + sprintf (state->event_history_s[slot].Event_History_Items[0].gps_s, "%s", state->dmr_embedded_gps[slot]); + //save to LRRP report for mapping/logging FILE * pFile; //file pointer if (opts->lrrp_file_output == 1) @@ -371,6 +385,10 @@ void nmea_harris (dsd_opts * opts, dsd_state * state, uint8_t * input, uint32_t //save to ncurses string sprintf (state->dmr_embedded_gps[slot], "GPS: (%f%s, %f%s)", latitude, deg_glyph, longitude, deg_glyph); + //save to event history string + if (state->event_history_s[slot].Event_History_Items[0].source_id == src) + sprintf (state->event_history_s[slot].Event_History_Items[0].gps_s, "%s", state->dmr_embedded_gps[slot]); + //save to LRRP report for mapping/logging FILE * pFile; //file pointer if (opts->lrrp_file_output == 1) @@ -625,6 +643,14 @@ void dmr_embedded_gps (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[]) } else sprintf (state->dmr_embedded_gps[slot], "GPS: %.5lf%s%s %.5lf%s%s Unknown Pos Err", latitude, deg_glyph, latstr, longitude, deg_glyph, lonstr); + uint32_t src = 0; + if (slot == 0) src = state->lasttg; + if (slot == 1) src = state->lasttgR; + + //save to event history string + if (state->event_history_s[slot].Event_History_Items[0].source_id == src) + sprintf (state->event_history_s[slot].Event_History_Items[0].gps_s, "%s", state->dmr_embedded_gps[slot]); + //save to LRRP report for mapping/logging FILE * pFile; //file pointer if (opts->lrrp_file_output == 1) @@ -633,10 +659,6 @@ void dmr_embedded_gps (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[]) char * datestr = getDate(); char * timestr = getTime(); - int src = 0; - if (slot == 0) src = state->lasttg; - if (slot == 1) src = state->lasttgR; - //open file by name that is supplied in the ncurses terminal, or cli pFile = fopen (opts->lrrp_out_file, "a"); fprintf (pFile, "%s\t", datestr ); @@ -727,17 +749,21 @@ void apx_embedded_gps (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[]) if (res_b) fprintf (stderr, "RES_B: %02X; ", res_b); + uint32_t src = 0; + if (slot == 0) src = state->lastsrc; + if (slot == 1) src = state->lastsrcR; + //save to array for ncurses sprintf (state->dmr_embedded_gps[slot], "GPS: %lf%s%s %lf%s%s (%lf, %lf) %s", latitude, deg_glyph, latstr, longitude, deg_glyph, lonstr, latitude, longitude, valid); + //save to event history string + if (state->event_history_s[slot].Event_History_Items[0].source_id == src) + sprintf (state->event_history_s[slot].Event_History_Items[0].gps_s, "%s", state->dmr_embedded_gps[slot]); + //save to LRRP report for mapping/logging FILE * pFile; //file pointer if (opts->lrrp_file_output == 1) { - int src = 0; - if (slot == 0) src = state->lastsrc; - if (slot == 1) src = state->lastsrcR; - char * datestr = getDate(); char * timestr = getTime(); diff --git a/src/dsd_main.c b/src/dsd_main.c index 2de8b76..a529287 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -259,8 +259,8 @@ state->lastsrc = 0; state->lasttgR = 0; state->lastsrcR = 0; - state->gi[0] = 0; - state->gi[1] = 0; + state->gi[0] = -1; + state->gi[1] = -1; //zero out vc frequencies? state->p25_vc_freq[0] = 0; @@ -297,8 +297,8 @@ state->lastsrc = 0; state->lasttgR = 0; state->lastsrcR = 0; - state->gi[0] = 0; - state->gi[1] = 0; + state->gi[0] = -1; + state->gi[1] = -1; } @@ -466,7 +466,8 @@ //dmr talker alias new/fixed stuff memset(state->dmr_alias_format, 0, sizeof(state->dmr_alias_format)); - memset(state->dmr_alias_len, 0, sizeof(state->dmr_alias_len)); + memset(state->dmr_alias_block_len, 0, sizeof(state->dmr_alias_block_len)); + memset(state->dmr_alias_char_size, 0, sizeof(state->dmr_alias_char_size)); memset(state->dmr_alias_block_segment, 0, sizeof(state->dmr_alias_block_segment)); memset(state->dmr_embedded_gps, 0, sizeof(state->dmr_embedded_gps)); memset(state->dmr_lrrp_gps, 0, sizeof(state->dmr_lrrp_gps)); @@ -941,8 +942,8 @@ state->lastsrc = 0; state->lasttgR = 0; state->lastsrcR = 0; - state->gi[0] = 0; - state->gi[1] = 0; + state->gi[0] = -1; + state->gi[1] = -1; state->eh_index = 0; state->nac = 0; state->errs = 0; @@ -1229,7 +1230,8 @@ //dmr talker alias new/fixed stuff memset(state->dmr_alias_format, 0, sizeof(state->dmr_alias_format)); - memset(state->dmr_alias_len, 0, sizeof(state->dmr_alias_len)); + memset(state->dmr_alias_block_len, 0, sizeof(state->dmr_alias_block_len)); + memset(state->dmr_alias_char_size, 0, sizeof(state->dmr_alias_char_size)); memset(state->dmr_alias_block_segment, 0, sizeof(state->dmr_alias_block_segment)); memset(state->dmr_embedded_gps, 0, sizeof(state->dmr_embedded_gps)); memset(state->dmr_lrrp_gps, 0, sizeof(state->dmr_lrrp_gps)); diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c index 5738dfc..c8167b5 100644 --- a/src/dsd_ncurses.c +++ b/src/dsd_ncurses.c @@ -77,8 +77,8 @@ char * SyncTypes[44] = { "DMR", "EDACS/PV", "EDACS/PV", - "M17 STR", //M17 Voice Stream - "M17 STR", //M17 Voice Stream + "M17", //M17 Voice Stream + "M17", //M17 Voice Stream "DSTAR", //header "DSTAR", //header "dPMR", //20 @@ -3342,31 +3342,6 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) attron(COLOR_PAIR(3)); } - //Not always correct, or correct at all, depends on context - //this is already in the call_string anyways - - // if(state->dmrburstL == 16 && state->dmr_so == 0x40 && state->R == 0) //0100 0000 - // { - // attron(COLOR_PAIR(2)); - // printw (" **ENC** "); - // attroff(COLOR_PAIR(2)); - // attron(COLOR_PAIR(3)); - // } - // if(state->dmrburstL == 16 && state->dmr_so == 0x80) - // { - // attron(COLOR_PAIR(2)); - // printw (" **Emergency** "); - // attroff(COLOR_PAIR(2)); - // attron(COLOR_PAIR(3)); - // } - // if(state->dmrburstL == 16 && state->dmr_so == 0x30) //0010 0000 - // { - // attron(COLOR_PAIR(2)); - // printw (" **Private Call** "); - // attroff(COLOR_PAIR(2)); - // attron(COLOR_PAIR(3)); - // } - printw ("\n"); //printw ("| | "); //10 spaces @@ -3382,16 +3357,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) //Embedded GPS (not LRRP) printw ("%s ", state->dmr_embedded_gps[0]); - //Embedded Talker Alias Blocks - for (int i = 0; i < 4; i++) - { - for (int j = 0; j < 7; j++) - { - printw ("%s", state->dmr_alias_block_segment[0][i][j]); - } - } - - //Generic Talker Alias String + //Embedded Talker Alias String printw ("%s", state->generic_talker_alias[0]); attroff(COLOR_PAIR(5)); @@ -3551,31 +3517,6 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) attron(COLOR_PAIR(3)); } - //Not always correct, or correct at all, depends on context - //this is already in the call_string anyways - - // if(state->dmrburstR == 16 && state->dmr_soR == 0x40 && state->R == 0) //0100 0000 - // { - // attron(COLOR_PAIR(2)); - // printw (" **ENC** "); - // attroff(COLOR_PAIR(2)); - // attron(COLOR_PAIR(3)); - // } - // if(state->dmrburstR == 16 && state->dmr_soR == 0x80) - // { - // attron(COLOR_PAIR(2)); - // printw (" **Emergency** "); - // attroff(COLOR_PAIR(2)); - // attron(COLOR_PAIR(3)); - // } - // if(state->dmrburstR == 16 && state->dmr_soR == 0x30) //0010 0000 - // { - // attron(COLOR_PAIR(2)); - // printw (" **Private Call** "); - // attroff(COLOR_PAIR(2)); - // attron(COLOR_PAIR(3)); - // } - printw ("\n"); //printw ("| | "); @@ -3590,16 +3531,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) attron(COLOR_PAIR(4)); printw ("%s ", state->dmr_embedded_gps[1]); - //Embedded Talker Alias Blocks - for (int i = 0; i < 4; i++) - { - for (int j = 0; j < 7; j++) - { - printw ("%s", state->dmr_alias_block_segment[1][i][j]); - } - } - - //Generic Talker Alias String + //Embedded Talker Alias String printw ("%s", state->generic_talker_alias[1]); attroff(COLOR_PAIR(5)); @@ -3914,9 +3846,17 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) if (strncmp(text_string, state->event_history_s[slot].Event_History_Items[i%255].text_message, 13) != 0) printw ("| %s \n", state->event_history_s[slot].Event_History_Items[i%255].text_message); + sprintf (text_string, "%s", "BUMBLEBEETUNA"); + if (strncmp(text_string, state->event_history_s[slot].Event_History_Items[i%255].alias, 13) != 0) + printw ("| Alias: %s \n", state->event_history_s[slot].Event_History_Items[i%255].alias); + + sprintf (text_string, "%s", "BUMBLEBEETUNA"); + if (strncmp(text_string, state->event_history_s[slot].Event_History_Items[i%255].gps_s, 13) != 0) + printw ("| GPS: %s \n", state->event_history_s[slot].Event_History_Items[i%255].gps_s); + } - printw ("------------------------------------------------------------------------------\n"); - attroff(COLOR_PAIR(4)); //cyan for history + printw ("------------------------------------------------------------------------------\n"); + attroff(COLOR_PAIR(4)); //cyan for history } refresh(); @@ -4851,11 +4791,8 @@ void push_event_history (Event_History_I * event_struct) 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); - + //open log file FILE * event_log_file; - event_log_file = fopen(opts->event_out_file, "a"); fprintf (event_log_file, "%s \n", event_string); @@ -4863,7 +4800,12 @@ void write_event_to_log_file (dsd_opts * opts, dsd_state * state, char * event_s 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); + if (strncmp(text_string, state->event_history_s[slot].Event_History_Items[0].alias, 13) != 0) + fprintf (event_log_file, " Talker Alias: %s \n", state->event_history_s[slot].Event_History_Items[0].alias); + if (strncmp(text_string, state->event_history_s[slot].Event_History_Items[0].gps_s, 13) != 0) + fprintf (event_log_file, " Embedded GPS: %s \n", state->event_history_s[slot].Event_History_Items[0].gps_s); + //flush and close log file fflush (event_log_file); fclose (event_log_file); } @@ -4960,6 +4902,7 @@ void watchdog_event_history (dsd_opts * opts, dsd_state * state, uint8_t slot) memset(state->ysf_txt, 0, sizeof(state->ysf_txt)); memset(state->dstar_gps, 0, sizeof(state->dstar_gps)); memset(state->dstar_txt, 0, sizeof(state->dstar_txt)); + state->gi[slot] = -1; //return to an unset value } } @@ -4978,7 +4921,7 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot) uint32_t target_id = 0; uint16_t svc_opts = 0; uint8_t subtype = 0; - + uint8_t mfid = 0; uint32_t sys_id1 = 0; uint32_t sys_id2 = 0; uint32_t sys_id3 = 0; @@ -5001,6 +4944,7 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot) target_id = state->lasttg; subtype = state->dmrburstL; + mfid = state->dmr_fid; svc_opts = state->dmr_so; enc = (svc_opts >> 6) & 1; @@ -5013,7 +4957,9 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot) { source_id = state->lastsrcR; target_id = state->lasttgR; + subtype = state->dmrburstR; + mfid = state->dmr_fidR; svc_opts = state->dmr_soR; enc = (svc_opts >> 6) & 1; @@ -5057,6 +5003,7 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot) if (state->nxdn_cipher_type != 0) enc = 1; alg_id = state->nxdn_cipher_type; + key_id = state->nxdn_key; sys_id1 = state->nxdn_location_site_code; sys_id2 = state->nxdn_location_sys_code; @@ -5259,46 +5206,84 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot) state->lastsynctype == 32 || state->lastsynctype == 33 || state->lastsynctype == 34 ) //DMR { if (sys_id1) - sprintf (event_string, "%s %s %s Voice TGT: %08d; SRC: %08d; CC: %02d; SYS: %X; ", datestr, timestr, sys_string, target_id, source_id, sys_id2, sys_id1); + sprintf (event_string, "%s %s %s TGT: %08d; SRC: %08d; CC: %02d; SYS: %X; ", datestr, timestr, sys_string, target_id, source_id, sys_id2, sys_id1); else - sprintf (event_string, "%s %s %s Voice TGT: %08d; SRC: %08d; CC: %02d; ", datestr, timestr, sys_string, target_id, source_id, sys_id2); + sprintf (event_string, "%s %s %s TGT: %08d; SRC: %08d; CC: %02d; ", datestr, timestr, sys_string, target_id, source_id, sys_id2); if (enc) strcat(event_string, "ENC; "); if (alg_id != 0) { char ess_str[30]; - sprintf (ess_str, "ALG: %02X; KID: %02X;", alg_id, key_id); + sprintf (ess_str, "ALG: %02X; KID: %02X; ", alg_id, key_id); strcat(event_string, ess_str); } + + //monitor for misc link control that may set a SO without having SO inside of it, + //those could cause misc issues here, will need to observe and make adjustments + if (svc_opts & 0x80) + strcat (event_string, "Emergency; "); + + if (svc_opts & 0x08) + strcat (event_string, "Broadcast; "); + + if (svc_opts & 0x04) + strcat (event_string, "OVCM; "); + + if (state->gi[slot] == 0) + strcat (event_string, "Group; "); + else if (state->gi[slot] == 1) + strcat (event_string, "Private; "); + + if (mfid == 0x10) + { + if (svc_opts & 0x20) + strcat (event_string, "TXI; "); + else if (svc_opts & 0x10) + strcat (event_string, "TXI; "); //this is the svc opt bit that tells you when the next VC6 will be pre-empted, but not helpful here + + if (svc_opts & 0x03) + strcat (event_string, "PRIORITY; "); //need to break this apart into each one, but need to double check the decoded value is accurate + } + } else if (state->lastsynctype == 0 || state->lastsynctype == 1 || state->lastsynctype == 35 || state->lastsynctype == 36) { if (sys_id1) - sprintf (event_string, "%s %s %s Voice TGT: %08d; SRC: %08d; NAC: %03X; SYS: %05X:%03X:%d.%d; ", datestr, timestr, sys_string, target_id, source_id, sys_id3, sys_id1, sys_id2, sys_id4, sys_id5); + sprintf (event_string, "%s %s %s TGT: %08d; SRC: %08d; NAC: %03X; SYS: %05X:%03X:%d.%d; ", datestr, timestr, sys_string, target_id, source_id, sys_id3, sys_id1, sys_id2, sys_id4, sys_id5); else - sprintf (event_string, "%s %s %s Voice TGT: %08d; SRC: %08d; NAC: %03X; ", datestr, timestr, sys_string, target_id, source_id, sys_id3); + sprintf (event_string, "%s %s %s TGT: %08d; SRC: %08d; NAC: %03X; ", datestr, timestr, sys_string, target_id, source_id, sys_id3); if (alg_id != 0 && alg_id != 0x80) { char ess_str[30]; - sprintf (ess_str, "ENC; ALG: %02X; KID: %04X;", alg_id, key_id); + sprintf (ess_str, "ENC; ALG: %02X; KID: %04X; ", alg_id, key_id); strcat(event_string, ess_str); } + if (svc_opts & 0x80) + strcat (event_string, "Emergency; "); + if (state->gi[slot] == 0) + strcat (event_string, "Group; "); + else if (state->gi[slot] == 1) + strcat (event_string, "Private; "); } else if (state->lastsynctype == 28 || state->lastsynctype == 29) { if (sys_id1) - sprintf (event_string, "%s %s %s Voice TGT: %08d; SRC: %08d; RAN: %02d; SYS: %d.%d; ", datestr, timestr, sys_string, target_id, source_id, sys_id3, sys_id1, sys_id2); + sprintf (event_string, "%s %s %s TGT: %08d; SRC: %08d; RAN: %02d; SYS: %d.%d; ", datestr, timestr, sys_string, target_id, source_id, sys_id3, sys_id1, sys_id2); else - sprintf (event_string, "%s %s %s Voice TGT: %08d; SRC: %08d; RAN: %02d; ", datestr, timestr, sys_string, target_id, source_id, sys_id3); + sprintf (event_string, "%s %s %s TGT: %08d; SRC: %08d; RAN: %02d; ", datestr, timestr, sys_string, target_id, source_id, sys_id3); if (enc) strcat(event_string, "ENC; "); if (alg_id != 0) { char ess_str[30]; - sprintf (ess_str, "ALG: %d; KID: %02X;", alg_id, key_id); + sprintf (ess_str, "ALG: %d; KID: %02X; ", alg_id, key_id); strcat(event_string, ess_str); } + if (state->gi[slot] == 0) + strcat (event_string, "Group; "); + else if (state->gi[slot] == 1) + strcat (event_string, "Private; "); } sprintf (event_struct->Event_History_Items[0].event_string, "%s", event_string); diff --git a/src/dsd_rigctl.c b/src/dsd_rigctl.c index e2efb8a..d80e789 100644 --- a/src/dsd_rigctl.c +++ b/src/dsd_rigctl.c @@ -503,8 +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->gi[0] = -1; + state->gi[1] = -1; state->payload_algid = 0; state->payload_algidR = 0; state->payload_keyid = 0; diff --git a/src/nxdn_element.c b/src/nxdn_element.c index b610c87..740fd4f 100644 --- a/src/nxdn_element.c +++ b/src/nxdn_element.c @@ -1310,16 +1310,22 @@ void NXDN_decode_VCALL(dsd_opts * opts, dsd_state * state, uint8_t * Message) if(MessageType == 0x1) { //only assign rid if not spare and not reserved (happens on private calls, unsure of its significance) - if ( (VoiceCallOption & 0xF) < 4) //ideally, only want 0, 2, or 3 + if ( (VoiceCallOption & 0xF) < 4) //ideally, only want 0, 1, 2, 3, or 4 (or 6, 7 on telephone calls) state->nxdn_last_rid = SourceUnitID; state->nxdn_last_tg = DestinationID; state->nxdn_key = KeyID; + if (CallType == 0 || CallType == 1) //broadcast and group + state->gi[0] = 0; + else if (CallType == 4) //private + state->gi[0] = 1; + else state->gi[0] = -1; //unassigned on any other values state->nxdn_cipher_type = CipherType; } else { state->nxdn_last_rid = 0; state->nxdn_last_tg = 0; + state->gi[0] = -1; sprintf (state->str50a, "%s", ""); memset (state->nxdn_alias_block_segment, 0, sizeof(state->nxdn_alias_block_segment)); } diff --git a/src/p25_lcw.c b/src/p25_lcw.c index dc41319..f605901 100644 --- a/src/p25_lcw.c +++ b/src/p25_lcw.c @@ -64,6 +64,8 @@ void p25_lcw (dsd_opts * opts, dsd_state * state, uint8_t LCW_bits[], uint8_t ir uint32_t source = (uint32_t)ConvertBitIntoBytes(&LCW_bits[48], 24); fprintf (stderr, " - Group %d Source %d", group, source); UNUSED2(res, explicit); + state->gi[0] = 0; + state->dmr_so = lc_svcopt; //test to make sure no random issues //don't set this when zero, annoying blink occurs in ncurses if (group != 0) state->lasttg = group; @@ -85,6 +87,8 @@ void p25_lcw (dsd_opts * opts, dsd_state * state, uint8_t LCW_bits[], uint8_t ir //don't set this when zero, annoying blink occurs in ncurses if (target != 0) state->lasttg = target; if (source != 0) state->lastsrc = source; + state->gi[0] = 0; + state->dmr_so = lc_svcopt; sprintf (state->call_string[0], " Private "); if (lc_svcopt & 0x80) strcat (state->call_string[0], " Emergency "); @@ -160,6 +164,7 @@ void p25_lcw (dsd_opts * opts, dsd_state * state, uint8_t LCW_bits[], uint8_t ir uint32_t target = (uint32_t)ConvertBitIntoBytes(&LCW_bits[16], 24); uint32_t src = (uint32_t)ConvertBitIntoBytes(&LCW_bits[40], 24); fprintf (stderr, "TGT: %d; SRC: %d; ", target, src); + state->gi[0] = 1; } else if (lc_format == 0x50) @@ -432,6 +437,7 @@ void p25_lcw (dsd_opts * opts, dsd_state * state, uint8_t LCW_bits[], uint8_t ir if (LCW_bits[31] == 1) fprintf (stderr, " EXT;"); //Full SUID next LC (external) (octet 3) state->lasttg = sg; state->lastsrc = src; + state->gi[0] = 0; } else if (lc_mfid == 0x90 && lc_opcode == 0x1) @@ -442,6 +448,7 @@ void p25_lcw (dsd_opts * opts, dsd_state * state, uint8_t LCW_bits[], uint8_t ir fprintf (stderr, " SG: %d; CH: %04X;", sg, ch); if (LCW_bits[16] == 1) fprintf (stderr, " Res;"); //res bit (octet 2) if (LCW_bits[17] == 1) fprintf (stderr, " ENC;"); //P-bit (octet 2) + state->gi[0] = 0; } else if (lc_mfid == 0x90 && lc_opcode == 0x3) diff --git a/src/p25p1_ldu1.c b/src/p25p1_ldu1.c index a950478..d1abd63 100644 --- a/src/p25p1_ldu1.c +++ b/src/p25p1_ldu1.c @@ -513,11 +513,11 @@ processLDU1 (dsd_opts* opts, dsd_state* state) { state->dmr_alias_format[0] = 0x02; if (lsd_hex2 > 8) lsd_hex2 = 8; //sanity check - state->dmr_alias_len[0] = lsd_hex2; + state->dmr_alias_block_len[0] = lsd_hex2; state->data_block_counter[0] = 0; } - if ( (k >= state->dmr_alias_len[0]) && (state->dmr_alias_format[0] == 0x02) ) + if ( (k >= state->dmr_alias_block_len[0]) && (state->dmr_alias_format[0] == 0x02) ) { //storage for completed string char str[16]; int wr = 0; int tsrc = state->lastsrc; int z = 0; k = 0; diff --git a/src/p25p1_ldu2.c b/src/p25p1_ldu2.c index c879571..3e4fa8a 100644 --- a/src/p25p1_ldu2.c +++ b/src/p25p1_ldu2.c @@ -574,11 +574,11 @@ processLDU2 (dsd_opts * opts, dsd_state * state) { state->dmr_alias_format[0] = 0x02; if (lsd_hex2 > 8) lsd_hex2 = 8; //sanity check - state->dmr_alias_len[0] = lsd_hex2; + state->dmr_alias_block_len[0] = lsd_hex2; state->data_block_counter[0] = 0; } - if ( (k >= state->dmr_alias_len[0]) && (state->dmr_alias_format[0] == 0x02) ) + if ( (k >= state->dmr_alias_block_len[0]) && (state->dmr_alias_format[0] == 0x02) ) { //storage for completed string char str[16]; int wr = 0; int tsrc = state->lastsrc; int z = 0; k = 0; @@ -643,7 +643,7 @@ processLDU2 (dsd_opts * opts, dsd_state * state) //reset values state->dmr_alias_format[0] = 0; state->data_block_counter[0] = 0; - state->dmr_alias_len[0] = 0; + state->dmr_alias_block_len[0] = 0; // memset (state->dmr_alias_block_segment, 0, sizeof(state->dmr_alias_block_segment)); } #else diff --git a/src/p25p2_vpdu.c b/src/p25p2_vpdu.c index fd2fef5..a042d1c 100644 --- a/src/p25p2_vpdu.c +++ b/src/p25p2_vpdu.c @@ -2044,6 +2044,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon int src = (MAC[6+len_a] << 16) | (MAC[7+len_a] << 8) | MAC[8+len_a]; fprintf (stderr, "\n VCH %d - Super Group %d SRC %d ", slot, gr, src); fprintf (stderr, "MFID90 Group Regroup Voice"); + state->gi[slot] = 0; if (slot == 0) { @@ -2064,6 +2065,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon int src = (MAC[7+len_a] << 16) | (MAC[8+len_a] << 8) | MAC[9+len_a]; fprintf (stderr, "\n VCH %d - Super Group %d SRC %d ", slot, gr, src); fprintf (stderr, "MFID90 Group Regroup Voice"); + state->gi[slot] = 0; if (slot == 0) { @@ -2274,6 +2276,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon } fprintf (stderr, " Group Voice"); + state->gi[slot] = 0; sprintf (state->call_string[slot], " Group "); if (svc & 0x80) strcat (state->call_string[slot], " Emergency "); @@ -2328,6 +2331,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon } fprintf (stderr, " Unit to Unit Voice"); + state->gi[slot] = 1; sprintf (state->call_string[slot], " Private "); if (svc & 0x80) strcat (state->call_string[slot], " Emergency ");