mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-09 15:27:22 -05:00
NXDN: Add Event History entries for the GPS report, undecoded, and still encrypted Data Calls;
P25p1: Add / Fix Several TSBKs including Station ID and Extended Function Command; Add UDP Port Decode for EFJ Atlas Data Registration Server;
This commit is contained in:
@@ -521,6 +521,12 @@ void decode_ip_pdu (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t *
|
||||
lip_protocol_decoder(opts, state, bits);
|
||||
}
|
||||
//known P25 Ports
|
||||
else if (port1 == 9361 && port2 == 9361)
|
||||
{
|
||||
sprintf (state->dmr_lrrp_gps[slot], "P25 Atlas SRC(IP): %d.%d.%d.%d; DST(IP): %d.%d.%d.%d; ",
|
||||
input[12], input[13], input[14], input[15], input[16], input[17], input[18], input[19]);
|
||||
fprintf (stderr, "Atlas Data Registration Server;"); //EF Johnson Atlas
|
||||
}
|
||||
else if (port1 == 49198 && port2 == 49198)
|
||||
{
|
||||
sprintf (state->dmr_lrrp_gps[slot], "P25 Tier 2 LOCN SRC(IP): %d.%d.%d.%d; DST(IP): %d.%d.%d.%d; ",
|
||||
|
||||
@@ -724,12 +724,10 @@ void decode_ars(dsd_opts * opts, dsd_state * state, uint8_t * input, int len)
|
||||
void nxdn_gps_report(dsd_opts * opts, dsd_state * state, uint8_t * input, uint32_t src)
|
||||
{
|
||||
|
||||
// Basic fields
|
||||
// uint8_t quality = (uint8_t)convert_bits_into_output(input+8, 4); //can't seem to work these first two out correctly
|
||||
// uint8_t num_sat = (uint8_t)convert_bits_into_output(input+12, 4); //can't seem to work these first two out correctly
|
||||
//Elevation
|
||||
int16_t elevation = (int16_t)convert_bits_into_output(input+56, 16);
|
||||
|
||||
// Speed & Heading (in tenths)
|
||||
//Speed & Heading (in tenths)
|
||||
uint16_t speed_raw = (uint16_t)convert_bits_into_output(input+74, 14);
|
||||
uint16_t heading_raw = (uint16_t)convert_bits_into_output(input+92, 12);
|
||||
double speed = speed_raw / 10.0; //knots or k/h
|
||||
@@ -740,7 +738,7 @@ void nxdn_gps_report(dsd_opts * opts, dsd_state * state, uint8_t * input, uint32
|
||||
uint8_t month = (uint8_t) convert_bits_into_output(input+143,4);
|
||||
uint8_t day = (uint8_t)(convert_bits_into_output(input+147,5) + 1);
|
||||
|
||||
// Longitude (DDMM.mmmm format)
|
||||
//Longitude (DDMM.mmmm format)
|
||||
uint16_t lon_degmin = (uint16_t)convert_bits_into_output(input+152, 16);
|
||||
uint16_t lon_frac = (uint16_t)convert_bits_into_output(input+16, 15);
|
||||
uint8_t lon_hem = (uint8_t) convert_bits_into_output(input+183, 1);
|
||||
@@ -748,7 +746,7 @@ void nxdn_gps_report(dsd_opts * opts, dsd_state * state, uint8_t * input, uint32
|
||||
double lon_decimal = (lon_degmin / 100) + (lon_minutes / 60.0);
|
||||
double longitude = (lon_hem == 0) ? lon_decimal : -lon_decimal;
|
||||
|
||||
// Latitude (DDMM.mmmm format)
|
||||
//Latitude (DDMM.mmmm format)
|
||||
uint16_t lat_degmin = (uint16_t)convert_bits_into_output(input+184,16);
|
||||
uint16_t lat_frac = (uint16_t)convert_bits_into_output(input+200,15);
|
||||
uint8_t lat_hem = (uint8_t) convert_bits_into_output(input+215,1);
|
||||
@@ -757,9 +755,8 @@ void nxdn_gps_report(dsd_opts * opts, dsd_state * state, uint8_t * input, uint32
|
||||
double latitude = (lat_hem == 0) ? lat_decimal : -lat_decimal;
|
||||
|
||||
//Time
|
||||
// uint8_t hour = (uint8_t) convert_bits_into_output(input+247,5);
|
||||
// uint8_t minute = (uint8_t) convert_bits_into_output(input+252,6);
|
||||
// uint8_t second = (uint8_t) convert_bits_into_output(input+258,6); //this seems to be zero, recheck time
|
||||
uint8_t hour = (uint8_t) convert_bits_into_output(input+247,5);
|
||||
uint8_t minute = (uint8_t) convert_bits_into_output(input+252,6);
|
||||
|
||||
char deg_glyph[4];
|
||||
sprintf (deg_glyph, "%s", "°");
|
||||
@@ -769,12 +766,19 @@ void nxdn_gps_report(dsd_opts * opts, dsd_state * state, uint8_t * input, uint32
|
||||
fprintf (stderr, "Speed: %lf k/h; ", speed);
|
||||
fprintf (stderr, "COG: %lf; ", heading);
|
||||
fprintf (stderr, "Elevation: %i; ", elevation);
|
||||
// fprintf (stderr, "Quality: %d / %d; ", quality, num_sat);
|
||||
fprintf (stderr, "Date: %04d/%02d/%02d ", year, month, day);
|
||||
// fprintf (stderr, "Time: %02d:%02d:%02d ", hour, minute, second);
|
||||
fprintf (stderr, "Time: %02d:%02d ", hour, minute);
|
||||
|
||||
//dump to event history
|
||||
sprintf (state->event_history_s[0].Event_History_Items[0].gps_s, "(%f%s, %f%s)", latitude, deg_glyph, longitude, deg_glyph);
|
||||
uint32_t source = state->dmr_lrrp_source[0];
|
||||
uint32_t target = state->dmr_lrrp_target[0];
|
||||
char comp_string[500]; memset (comp_string, 0, sizeof(comp_string));
|
||||
sprintf (comp_string, "GPS SRC: %d; TGT: %d;", source, target);
|
||||
watchdog_event_datacall (opts, state, source, target, comp_string, 0);
|
||||
|
||||
//save to LRRP report for mapping/logging
|
||||
if (opts->lrrp_file_output == 1 && src != 0) //&& quality?
|
||||
if (opts->lrrp_file_output == 1 && src != 0)
|
||||
{
|
||||
|
||||
char * datestr = getDateS();
|
||||
|
||||
@@ -2964,15 +2964,39 @@ int nxdn_dcall_data(dsd_opts * opts, dsd_state * state, int type, uint8_t * Mess
|
||||
nxdn_gps_report(opts, state, reverse_byte_bits+16, state->dmr_lrrp_source[0]);
|
||||
|
||||
}
|
||||
// else if (0 == 1) //future case
|
||||
// {
|
||||
// uint8_t bytes[total_bytes];
|
||||
// memset(bytes, 0, sizeof(bytes));
|
||||
// for (int i = 0; i < total_bytes-4; i++)
|
||||
// bytes[i] = (uint8_t)ConvertBitIntoBytes(state->dmr_pdu_sf[0]+(i*8), 8);
|
||||
// }
|
||||
else
|
||||
{
|
||||
//Anything else?
|
||||
//dump to event history as generic data call with no decode
|
||||
sprintf (state->event_history_s[0].Event_History_Items[0].text_message, "Unknown Data Call Format: %04X;", (uint16_t)ConvertBitIntoBytes(state->dmr_pdu_sf[0], 16));
|
||||
uint32_t source = state->dmr_lrrp_source[0];
|
||||
uint32_t target = state->dmr_lrrp_target[0];
|
||||
char comp_string[500]; memset (comp_string, 0, sizeof(comp_string));
|
||||
sprintf (comp_string, "DATA CALL SRC: %d; TGT: %d;", source, target);
|
||||
watchdog_event_datacall (opts, state, source, target, comp_string, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, " CRC: %08X / %08X;", crc_ext, crc_chk);
|
||||
fprintf (stderr, " (CRC ERR) ");
|
||||
|
||||
//dump to event history as generic data call with no decode, if still encrypted, yielding bad CRC32
|
||||
if (state->payload_algid != 0)
|
||||
{
|
||||
sprintf (state->event_history_s[0].Event_History_Items[0].text_message, "Encrypted PDU; Cipher: %d; KID: %02X;", state->payload_algid, state->payload_keyid);
|
||||
uint32_t source = state->dmr_lrrp_source[0];
|
||||
uint32_t target = state->dmr_lrrp_target[0];
|
||||
char comp_string[500]; memset (comp_string, 0, sizeof(comp_string));
|
||||
sprintf (comp_string, "DATA CALL SRC: %d; TGT: %d;", source, target);
|
||||
watchdog_event_datacall (opts, state, source, target, comp_string, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//clear storage
|
||||
|
||||
@@ -489,11 +489,53 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
fprintf (stderr, "\n");
|
||||
fprintf (stderr, "%s",KYEL);
|
||||
fprintf (stderr, " MFID 90 (Moto) Acknoledge Response: ");
|
||||
fprintf (stderr, " MFID 90 (Moto) Acknowledge Response: ");
|
||||
for (i = 2; i < 10; i++)
|
||||
fprintf (stderr, "%02X", tsbk_byte[i]);
|
||||
}
|
||||
|
||||
else if ( (tsbk_byte[0] & 0x3F) == 0x09 )
|
||||
{
|
||||
fprintf (stderr, "\n");
|
||||
fprintf (stderr, " MFID 90 (Moto) Scan Marker: ");
|
||||
for (i = 2; i < 10; i++)
|
||||
fprintf (stderr, "%02X", tsbk_byte[i]);
|
||||
}
|
||||
|
||||
else if ( (tsbk_byte[0] & 0x3F) == 0x0B )
|
||||
{
|
||||
|
||||
uint16_t channel = (tsbk_byte[8] << 8) | tsbk_byte[9];
|
||||
fprintf (stderr, "\n");
|
||||
fprintf (stderr, " MFID 90 (Moto) ID Channel: %04X;", channel);
|
||||
char sid_string[10];
|
||||
memset(sid_string, 0, sizeof(sid_string));
|
||||
int k = 0;
|
||||
|
||||
if (tsbk_byte[2] != 0)
|
||||
{
|
||||
fprintf (stderr, " Station ID: ");
|
||||
uint8_t sid_bits[42];
|
||||
memset(sid_bits, 0, sizeof(sid_bits));
|
||||
unpack_byte_array_into_bit_array(tsbk_byte+2, sid_bits, 6);
|
||||
for (i = 0; i < 42; i+=6)
|
||||
{
|
||||
uint8_t bsi_char = convert_bits_into_output(sid_bits+i, 6) + 43;
|
||||
if (bsi_char > 0x1F && bsi_char < 0x7F)
|
||||
{
|
||||
fprintf (stderr, "%c", bsi_char);
|
||||
sid_string[k++] = bsi_char;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
}
|
||||
|
||||
//debug, may assign this string to something else later on
|
||||
// fprintf (stderr, " - Str: %s;", sid_string);
|
||||
|
||||
process_channel_to_freq(opts, state, channel);
|
||||
}
|
||||
|
||||
|
||||
//Some of these Opcodes that aren't found in any TIA manual come from SDRTrunk (or other sources),
|
||||
//but can't verify the accuracy of their meaning/context
|
||||
@@ -505,22 +547,6 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
|
||||
// fprintf (stderr, "%02X", tsbk_byte[i]);
|
||||
// }
|
||||
|
||||
// else if ( (tsbk_byte[0] & 0x3F) == 0x09 )
|
||||
// {
|
||||
// fprintf (stderr, "\n");
|
||||
// fprintf (stderr, " MFID 90 (Moto) Channel Loading: "); //don't understand the context for this one, waiting on units to arrive on channel?
|
||||
// for (i = 2; i < 10; i++)
|
||||
// fprintf (stderr, "%02X", tsbk_byte[i]);
|
||||
// }
|
||||
|
||||
// else if ( (tsbk_byte[0] & 0x3F) == 0x0B )
|
||||
// {
|
||||
// fprintf (stderr, "\n");
|
||||
// fprintf (stderr, " MFID 90 (Moto) Control Channel: "); //this appears to echo the 16-bit channel number for the main control channel/RFSS
|
||||
// for (i = 2; i < 10; i++)
|
||||
// fprintf (stderr, "%02X", tsbk_byte[i]);
|
||||
// }
|
||||
|
||||
// else if ( (tsbk_byte[0] & 0x3F) == 0x0E )
|
||||
// {
|
||||
// fprintf (stderr, "\n");
|
||||
@@ -537,14 +563,6 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
|
||||
// fprintf (stderr, "%02X", tsbk_byte[i]);
|
||||
// }
|
||||
|
||||
// else if ( (tsbk_byte[0] & 0x3F) == 0x15 ) //noted on RR, but not observed as of yet, this may actualy be a LCW and not a TSBK?
|
||||
// {
|
||||
// fprintf (stderr, "\n");
|
||||
// fprintf (stderr, " MFID 90 (Moto) Talker Alias: ");
|
||||
// for (i = 2; i < 10; i++)
|
||||
// fprintf (stderr, "%02X", tsbk_byte[i]);
|
||||
// }
|
||||
|
||||
// else if ( (tsbk_byte[0] & 0x3F) == 0x16 )
|
||||
// {
|
||||
// fprintf (stderr, "\n");
|
||||
|
||||
@@ -1628,6 +1628,31 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
||||
|
||||
}
|
||||
|
||||
//Extended Function Command - Abbreviated (Generic non MFID variant)
|
||||
if (MAC[1+len_a] == 0x64)
|
||||
{
|
||||
|
||||
uint8_t class = MAC[2+len_a];
|
||||
uint8_t operand = MAC[3+len_a];
|
||||
uint32_t argument = (MAC[4+len_a] << 16) | (MAC[5+len_a] << 8) | MAC[6+len_a];
|
||||
uint32_t target = (MAC[7+len_a] << 16) | (MAC[8+len_a] << 8) | MAC[9+len_a];
|
||||
fprintf (stderr, "\n Extended Function Command: Class: %02X; Operand: %02X; Arg/Src: %06X; Target: %d; ", class, operand, argument, target);
|
||||
//WIP: Further Decode
|
||||
if (class == 0)
|
||||
{
|
||||
if ((operand & 0x7F) == 0x00) fprintf (stderr, "Radio Check; ");
|
||||
else if ((operand & 0x7F) == 0x7D) fprintf (stderr, "Radio Detach; ");
|
||||
else if ((operand & 0x7F) == 0x7E) fprintf (stderr, "Radio Uninhibit; ");
|
||||
else if ((operand & 0x7F) == 0x7F) fprintf (stderr, "Radio Inhibit; ");
|
||||
else fprintf (stderr, "Reserved; ");
|
||||
|
||||
//MSB is an ack of the above command
|
||||
if ((operand >> 7) == 1) fprintf (stderr, "Ack; ");
|
||||
}
|
||||
else fprintf (stderr, "Other Command; ");
|
||||
|
||||
}
|
||||
|
||||
//MFID90 Group Regroup Add Command
|
||||
if (MAC[1+len_a] == 0x81 && MAC[2+len_a] == 0x90)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user