mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-12 16:57:23 -05:00
DMR: PDU / LRRP Misc Fixes, Tweaks, and Cleanup;
This commit is contained in:
@@ -1288,13 +1288,12 @@ void dmr_dheader (dsd_opts * opts, dsd_state * state, uint8_t dheader[], uint8_t
|
||||
void dmr_block_assembler (dsd_opts * opts, dsd_state * state, uint8_t block_bytes[], uint8_t block_len, uint8_t databurst, uint8_t type);
|
||||
|
||||
//dmr pdu handling
|
||||
void dmr_pdu (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DMR_PDU[]);
|
||||
void dmr_ip_pdu (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t * DMR_PDU);
|
||||
void dmr_sd_pdu (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t * DMR_PDU);
|
||||
void dmr_udp_comp_pdu (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t * DMR_PDU);
|
||||
void dmr_reset_blocks (dsd_opts * opts, dsd_state * state);
|
||||
void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DMR_PDU[]);
|
||||
void dmr_locn (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DMR_PDU[]);
|
||||
void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint16_t len, uint32_t source, uint32_t dest, uint16_t port_s, uint16_t port_d, uint8_t * DMR_PDU);
|
||||
void dmr_locn (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t * DMR_PDU);
|
||||
|
||||
//Time and Date Functions
|
||||
char * getTime();
|
||||
|
||||
@@ -168,6 +168,8 @@ void dmr_dheader (dsd_opts * opts, dsd_state * state, uint8_t dheader[], uint8_t
|
||||
else if (sap == 5) sprintf (sap_string, "%s", "ARP Prot"); //Address Resoution Protocol (ARP)
|
||||
else if (sap == 9) sprintf (sap_string, "%s", "EXTD HDR"); //Extended Header (Proprietary)
|
||||
else if (sap == 10) sprintf (sap_string, "%s", "Short DT"); //Short Data
|
||||
else if (sap == 1 && p_mfid == 0x10)
|
||||
sprintf (sap_string, "%s", "Moto EXT"); //motorola extended format
|
||||
else sprintf (sap_string, "%s", "Reserved"); //reserved, or err/unk
|
||||
|
||||
//mfid string handling
|
||||
@@ -317,29 +319,32 @@ void dmr_dheader (dsd_opts * opts, dsd_state * state, uint8_t dheader[], uint8_t
|
||||
//The SAP found here is the actual SAP of the message (like a P25 ndary SAP, and can chain together according to ETSI)
|
||||
fprintf (stderr, " - SAP %02d [%s] - MFID %02X [%s]", p_sap, sap_string, p_mfid, mfid_string);
|
||||
|
||||
//p_sap 1 on mfid 10 (moto) is unknown, and the messages don't pass the CRC32
|
||||
//two extra duplicate blocks observed only happens on one sample, could have been radio or repeater errors?
|
||||
// if (p_sap != 1)
|
||||
//p_sap 1 on mfid 10 (moto) has been observed as the first block of LRRP data on a Moto system but doesnt' pass the CRC for some reason (included or not included)
|
||||
if (p_mfid == 0x10 && p_sap == 1)
|
||||
{
|
||||
//this method will include this extended header since its observed to be MOTO LRRP first block
|
||||
//NOTE: This is broken on R34 data (expects only R12U data)
|
||||
//TODO: Redo block assembly at some point (or store this seperately?)
|
||||
int blocks = state->data_header_blocks[slot]-1;
|
||||
if (blocks > 127) blocks = 127;
|
||||
if (blocks < 1) blocks = 4; //fix this at some point
|
||||
for(uint16_t i = 0; i < 12; i++)
|
||||
state->dmr_pdu_sf[slot][i+(blocks*12)] = dheader[i];
|
||||
state->data_block_counter[slot]++;
|
||||
}
|
||||
|
||||
else //if (p_sap != 1) //anything else
|
||||
{
|
||||
//sanity check to prevent segfault (this happened when the regular header was not received beforehand)
|
||||
if (state->data_header_blocks[slot] > 1)
|
||||
state->data_header_blocks[slot]--;
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// //this method will just include the prop_pdu header as a data block and assemble the data blocks as a message, excluding duplicates
|
||||
// int blocks = state->data_header_blocks[slot]-1;
|
||||
// if (blocks > 127) blocks = 127;
|
||||
// if (blocks < 1) blocks = 4;
|
||||
// for(i = 0; i < 12; i++)
|
||||
// state->dmr_pdu_sf[slot][i+(blocks*12)] = dheader[i];
|
||||
// state->data_block_counter[slot]++;
|
||||
// }
|
||||
|
||||
//Start Setting DMR Data Packet Encryption Variables
|
||||
if (p_sap != 1 && p_mfid == 0x10) //p_sap 1 is reserved and doesn't seem to contain ENC header (may be extended address, or other signalling)
|
||||
if (p_sap != 1 && p_mfid == 0x10)
|
||||
{
|
||||
//check ENC bit, assuming this is an ENC bit, or SVC OPT like thing
|
||||
|
||||
//check ENC bit, assuming this is an ENC bit, or SVC OPT like thing (or could be an opcode for the rest of the extended header)
|
||||
if ((uint8_t)ConvertBitIntoBytes(&dheader_bits[20], 4) == 1)
|
||||
{
|
||||
//set to 0x100 so it won't trigger any weird flags, but still has a non-zero value to be checked later
|
||||
@@ -376,18 +381,13 @@ void dmr_dheader (dsd_opts * opts, dsd_state * state, uint8_t dheader[], uint8_t
|
||||
fprintf (stderr, " MI(32): %08X", (uint32_t)ConvertBitIntoBytes(&dheader_bits[48], 32));
|
||||
|
||||
}
|
||||
else if (p_sap == 1 && p_mfid == 0x10)
|
||||
{
|
||||
//This can be an LRRP packet first block (but slightly different configuration)
|
||||
fprintf (stderr, "\n Motorola Alternate Function Header; ");
|
||||
}
|
||||
else //if (p_mfid == 0x10)
|
||||
{
|
||||
//I wonder if this is like the extended addressing header used on P25p1
|
||||
//(either way, the CRC32 will still fail, maybe its RAS or a MAC?)
|
||||
/*Unknown Extended Header: 1F1002011127E70D20232018
|
||||
Slot 2 - Multi Block PDU Message CRC32 ERR
|
||||
Slot 2 - Multi Block PDU Message
|
||||
1F1002011127E70D20232018 <--fails CRC32 with or without this attached
|
||||
41341F9AAECDE6554616A43C
|
||||
0E2A6335040C872A0009006C
|
||||
007356B370000000458AB84D <--very clearly 32 bits (4 bytes) after padding
|
||||
*/ //End Example
|
||||
fprintf (stderr, "\n Unknown Extended Header: ");
|
||||
for (uint8_t i = 2; i < 10; i++)
|
||||
fprintf (stderr, "%02X", (uint8_t)ConvertBitIntoBytes(&dheader_bits[0+(i*8)], 8));
|
||||
@@ -836,6 +836,29 @@ void dmr_block_assembler (dsd_opts * opts, dsd_state * state, uint8_t block_byte
|
||||
uint16_t len = ((blocks+1)*block_len)-4; //total number of bytes in PDU minus 4 CRC32 bytes
|
||||
dmr_udp_comp_pdu (opts, state, len, state->dmr_pdu_sf[slot]);
|
||||
}
|
||||
else if (state->data_header_sap[slot] == 1 && state->dmr_pdu_sf[slot][1] == 0x10) //test SAP 1 MFID 10 (with -F) as a potential LRRP message (header inclusive)
|
||||
{
|
||||
uint16_t len = ((blocks+1)*block_len)-4;
|
||||
|
||||
//sanity check
|
||||
if (len > 150)
|
||||
len = 150;
|
||||
|
||||
uint8_t PDU[150]; memset (PDU, 0, sizeof(PDU)); //arbitrary size (should be okay)
|
||||
|
||||
//manipulate to match expected format alignment
|
||||
PDU[0] = 0; PDU[1] = state->dmr_pdu_sf[slot][0];
|
||||
|
||||
//speculation: the other 4 bytes are hashed values for dst and src, or something similar
|
||||
|
||||
uint16_t mprt = 0xFFFF;
|
||||
uint32_t msrc = state->dmr_lrrp_source[slot];
|
||||
uint32_t mdst = 0xFFFFFF; //TODO: Get the real DST or TG indicated in the header
|
||||
|
||||
//copy rest, starting at offset 5 of the reserved extended header, to offset 2 to match expected formatting
|
||||
memcpy(PDU+2, state->dmr_pdu_sf[slot]+5, (sizeof(PDU)-5));
|
||||
dmr_lrrp (opts, state, len-4, msrc, mdst, mprt, mprt, PDU);
|
||||
}
|
||||
}
|
||||
|
||||
if (CRCCorrect) ; //print nothing
|
||||
|
||||
162
src/dmr_pdu.c
162
src/dmr_pdu.c
@@ -8,21 +8,6 @@
|
||||
|
||||
#include "dsd.h"
|
||||
|
||||
void dmr_pdu (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DMR_PDU[])
|
||||
{
|
||||
|
||||
uint8_t slot = state->currentslot;
|
||||
|
||||
//check for more available flag info, etc on these prior to running
|
||||
if (DMR_PDU[0] == 0x01) dmr_locn (opts, state, block_len, DMR_PDU);
|
||||
else dmr_lrrp (opts, state, block_len, DMR_PDU);
|
||||
|
||||
//maybe one day we will have more things to do here
|
||||
state->data_conf_data[slot] = 0; //flag off confirmed data after processing it
|
||||
state->data_p_head[slot] = 0; //flag off prop_head data after processing it
|
||||
|
||||
}
|
||||
|
||||
void utf16_to_text (uint16_t len, uint8_t * input)
|
||||
{
|
||||
len -= 36; //offset for starting point + 1
|
||||
@@ -225,7 +210,7 @@ void dmr_ip_pdu (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t * DMR
|
||||
else if (port1 == 4001 && port2 == 4001)
|
||||
{
|
||||
fprintf (stderr, "LRRP;");
|
||||
dmr_lrrp (opts, state, len, DMR_PDU); //will len just work here? (make adjustments if needed)
|
||||
dmr_lrrp (opts, state, len-24-4, add1, add2, port1, port2, DMR_PDU+24);
|
||||
}
|
||||
else if (port1 == 4004 && port2 == 4004)
|
||||
{
|
||||
@@ -272,23 +257,17 @@ void dmr_ip_pdu (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t * DMR
|
||||
|
||||
}
|
||||
|
||||
//The contents of this function are mostly my reversed engineered efforts by observing DSDPlus output and matching data bytes
|
||||
//combined with a few external sources such as OK-DMR for some token values and extra data values (rad and alt)
|
||||
//this is by no means an extensive LRRP list and is prone to error (unless somebody has the manual or something)
|
||||
void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DMR_PDU[])
|
||||
//The contents of this function are mostly trial and error
|
||||
void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint16_t len, uint32_t source, uint32_t dest, uint16_t port_s, uint16_t port_d, uint8_t * DMR_PDU)
|
||||
{
|
||||
int i;
|
||||
|
||||
uint16_t message_len = 0;
|
||||
uint8_t slot = state->currentslot;
|
||||
uint8_t blocks = state->data_header_blocks[slot];
|
||||
uint8_t padding = state->data_header_padding[slot];
|
||||
uint8_t lrrp_confidence = 0; //variable to increment based on number of tokens found, the more, the higher the confidence level
|
||||
|
||||
//source/dest and ports
|
||||
uint32_t source = 0;
|
||||
uint32_t dest = 0;
|
||||
uint16_t port_s = 0;
|
||||
uint16_t port_d = 0;
|
||||
//source/dest and ports (this is grabbed in the IP decoding phase)
|
||||
if (source != 0) lrrp_confidence++;
|
||||
if (dest != 0) lrrp_confidence++;
|
||||
|
||||
//time
|
||||
uint16_t year = 0;
|
||||
@@ -310,7 +289,6 @@ void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DM
|
||||
int lat_sign = 1; //positive 1, or negative 1
|
||||
int lon_sign = 1; //positive 1, or negative 1
|
||||
|
||||
//speed -- NOTE: Velocity is Speed + Direction
|
||||
uint16_t vel = 0;
|
||||
double velocity = 0;
|
||||
uint8_t vel_set = 0;
|
||||
@@ -322,74 +300,36 @@ void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DM
|
||||
|
||||
char deg_glyph[4];
|
||||
sprintf (deg_glyph, "%s", "°");
|
||||
// sprintf (deg_glyph, "%s", "d");
|
||||
|
||||
//triggered information report
|
||||
uint8_t report = 0;
|
||||
uint8_t pot_report = 0; //potential report by finding 0x0D and backtracking a few bytes
|
||||
uint8_t report = DMR_PDU[1];
|
||||
uint16_t unk = (DMR_PDU[2] << 8) | DMR_PDU[3]; //not sure what the following after the report value indicates exactly
|
||||
|
||||
//TODO: Needs more fixing, finding some things like report 0x12 with only partial updates on it
|
||||
|
||||
//start looking for tokens (using my best understanding of the ok-dmr library xml and python files)
|
||||
for (i = 0; i < ( (blocks*block_len) - (padding+4) ); i++)
|
||||
//debug passed LRRP message
|
||||
fprintf (stderr, "\n LRRP (DEBUG): ");
|
||||
for (uint16_t i = 0; i < len; i++)
|
||||
fprintf (stderr, "%02X ", DMR_PDU[i]);
|
||||
|
||||
//start looking for tokens
|
||||
for (uint16_t i = 4; i < len; i++) //starting at 4 offsets the octets before 0D (seen 0D tossed into the other values folliowing report value)
|
||||
{
|
||||
|
||||
switch(DMR_PDU[i]){
|
||||
case 0x0C: //LRRP_TriggeredLocationReport
|
||||
if (source == 0)
|
||||
{
|
||||
source = (DMR_PDU[i+1] << 16 ) + (DMR_PDU[i+2] << 8) + DMR_PDU[i+3];
|
||||
dest = (DMR_PDU[i+5] << 16 ) + (DMR_PDU[i+6] << 8) + DMR_PDU[i+7];
|
||||
port_s = (DMR_PDU[i+8] << 8) + DMR_PDU[i+9];
|
||||
port_d = (DMR_PDU[i+10] << 8) + DMR_PDU[i+11];
|
||||
i += 11;
|
||||
lrrp_confidence++;
|
||||
}
|
||||
break;
|
||||
//may need more 'report' types to trigger various scenarios
|
||||
//disable all but 0x1F if issues or falsing happens often
|
||||
//case 0x1D: //ARRP_TriggeredInformationAnswer_NCDT
|
||||
//case 0x1E: //ARRP_TriggeredInformationReport = FALSE?
|
||||
//case 0x25: //ARRP_UnsolicitedInformationReport_NCDT = (0x25, True, "")
|
||||
//case 0x26: //ARRP_UnsolicitedInformationReport_NCDT
|
||||
//case 0x13: //LRRP_UnsolicitedLocationReport_NCDT
|
||||
//case 0x15: //LRRP_LocationProtocolReport_NCDT
|
||||
//case 0x21: //ARRP_TriggeredInformationStopRequest_NCDT
|
||||
case 0x1F: //ARRP_TriggeredInformationReport_NCDT
|
||||
if (report == 0)
|
||||
{
|
||||
report = DMR_PDU[i];
|
||||
i += 1;
|
||||
lrrp_confidence++;
|
||||
}
|
||||
break;
|
||||
//0x0D always seems to follow 0x1F or other 'report' types two/three bytes later
|
||||
case 0x0D: //message len indicator //LRRP_TriggeredLocationReport_NCDT
|
||||
if (report > 0 && message_len == 0)
|
||||
case 0x0D: //message len indicator
|
||||
if (i == 4 && message_len == 0) //see if this is the first octet, otherwise, can't verify this is going to work //i == 4 &&
|
||||
{
|
||||
message_len = DMR_PDU[i+1];
|
||||
i += 1;
|
||||
lrrp_confidence++;
|
||||
}
|
||||
else if (message_len == 0)
|
||||
{
|
||||
if (i > 3)
|
||||
{
|
||||
if (DMR_PDU[i-3] > 0) pot_report = DMR_PDU[i-3];
|
||||
if (pot_report < 0x27)
|
||||
{
|
||||
report = pot_report;
|
||||
message_len = DMR_PDU[i+1];
|
||||
i += 1;
|
||||
//no lrrp_confidence on speculative reporting, but will print it as such.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
//RESULT TOKEN or Request ID!
|
||||
case 0x22: //same comment as below, observed followed the message len
|
||||
case 0x23: //this value has been seen after the 0x0D message len, appears to be a 2-byte value, was tripping a false on time stamp
|
||||
i += 2;
|
||||
case 0x23: //this value has been seen after the 0x0D message len, appears to be a 2-byte value
|
||||
//see if we can figure out how to intepret this
|
||||
i += 1; //should this be 2, or 1?
|
||||
break;
|
||||
//answer and report tokens
|
||||
case 0x51: //circle-2d
|
||||
@@ -397,8 +337,6 @@ void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DM
|
||||
case 0x55: //circle-3d
|
||||
if (message_len > 0 && lat == 0)
|
||||
{
|
||||
// lat = ( ( ((DMR_PDU[i+1] & 0x7F ) << 24 ) + (DMR_PDU[i+2] << 16) + (DMR_PDU[i+3] << 8) + DMR_PDU[i+4]) * 1 );
|
||||
// lon = ( ( ((DMR_PDU[i+5] & 0x7F ) << 24 ) + (DMR_PDU[i+6] << 16) + (DMR_PDU[i+7] << 8) + DMR_PDU[i+8]) * 1 );
|
||||
lat = ( ( (DMR_PDU[i+1] << 24 ) + (DMR_PDU[i+2] << 16) + (DMR_PDU[i+3] << 8) + DMR_PDU[i+4]) * 1 );
|
||||
lon = ( ( (DMR_PDU[i+5] << 24 ) + (DMR_PDU[i+6] << 16) + (DMR_PDU[i+7] << 8) + DMR_PDU[i+8]) * 1 );
|
||||
rad = (DMR_PDU[i+9] << 8) + DMR_PDU[i+10];
|
||||
@@ -420,7 +358,7 @@ void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DM
|
||||
second = (DMR_PDU[i+5] & 0x3F);
|
||||
i += 5;
|
||||
//sanity check
|
||||
if (year > 2000 && year <= 2025) lrrp_confidence++;
|
||||
if (year > 2000 && year <= 2026) lrrp_confidence++;
|
||||
if (year > 2025 || year < 2000) year = 0; //needs future proofing
|
||||
}
|
||||
break;
|
||||
@@ -428,11 +366,9 @@ void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DM
|
||||
case 0x66: //point-2d
|
||||
if (message_len > 0 && lat == 0)
|
||||
{
|
||||
// lat = ( ( ((DMR_PDU[i+1] & 0x7F ) << 24 ) + (DMR_PDU[i+2] << 16) + (DMR_PDU[i+3] << 8) + DMR_PDU[i+4]) * 1 );
|
||||
// lon = ( ( ((DMR_PDU[i+5] & 0x7F ) << 24 ) + (DMR_PDU[i+6] << 16) + (DMR_PDU[i+7] << 8) + DMR_PDU[i+8]) * 1 );
|
||||
lat = ( ( (DMR_PDU[i+1] << 24 ) + (DMR_PDU[i+2] << 16) + (DMR_PDU[i+3] << 8) + DMR_PDU[i+4]) * 1 );
|
||||
lon = ( ( (DMR_PDU[i+5] << 24 ) + (DMR_PDU[i+6] << 16) + (DMR_PDU[i+7] << 8) + DMR_PDU[i+8]) * 1 );
|
||||
i += 8;
|
||||
i += 8; //+= 9? including current ptr?
|
||||
lrrp_confidence++;
|
||||
}
|
||||
break;
|
||||
@@ -440,8 +376,6 @@ void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DM
|
||||
case 0x6A: //point-3d
|
||||
if (message_len > 0 && lat == 0)
|
||||
{
|
||||
// lat = ( ( ((DMR_PDU[i+1] & 0x7F ) << 24 ) + (DMR_PDU[i+2] << 16) + (DMR_PDU[i+3] << 8) + DMR_PDU[i+4]) * 1 );
|
||||
// lon = ( ( ((DMR_PDU[i+5] & 0x7F ) << 24 ) + (DMR_PDU[i+6] << 16) + (DMR_PDU[i+7] << 8) + DMR_PDU[i+8]) * 1 );
|
||||
lat = ( ( (DMR_PDU[i+1] << 24 ) + (DMR_PDU[i+2] << 16) + (DMR_PDU[i+3] << 8) + DMR_PDU[i+4]) * 1 );
|
||||
lon = ( ( (DMR_PDU[i+5] << 24 ) + (DMR_PDU[i+6] << 16) + (DMR_PDU[i+7] << 8) + DMR_PDU[i+8]) * 1 );
|
||||
alt = DMR_PDU[i+9];
|
||||
@@ -475,12 +409,8 @@ void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DM
|
||||
lrrp_confidence++;
|
||||
}
|
||||
break;
|
||||
//below all unknown
|
||||
case 0x37: //result
|
||||
case 0x38: //result
|
||||
case 0x39: //result 'operations error'? attributes 0x22?
|
||||
case 0x6B: //unknown-uint8
|
||||
case 0x65: //lev-conf
|
||||
|
||||
//unknown tokens
|
||||
default:
|
||||
//do nothing
|
||||
break;
|
||||
@@ -489,7 +419,7 @@ void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DM
|
||||
if (report && message_len > 0)
|
||||
{
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
fprintf (stderr, "\n LRRP Confidence: %d - Message Len: %d Octets", lrrp_confidence, message_len);
|
||||
fprintf (stderr, "\n LRRP Report: %02X; Unk: %04X; Message Len: %d;", report, unk, message_len);
|
||||
if (lrrp_confidence >= 3) //find the sweet magical number
|
||||
{
|
||||
//now we can open our lrrp file and write to it as well
|
||||
@@ -521,25 +451,6 @@ void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DM
|
||||
}
|
||||
}
|
||||
|
||||
if (pot_report)
|
||||
{
|
||||
fprintf (stderr, "\n");
|
||||
fprintf (stderr, " Potential ARRP/LRRP Report (Debug): 0x%02X", report);
|
||||
}
|
||||
if (report)
|
||||
{
|
||||
fprintf (stderr, "\n");
|
||||
fprintf (stderr, " Report: 0x%02X", report);
|
||||
if (report == 0x1F) fprintf (stderr, " ARRP_TriggeredInformationReport_NCDT "); //customize later when more is learned
|
||||
if (report == 0x21) fprintf (stderr, " ARRP_TriggeredInformationStopRequest_NCDT ");
|
||||
if (report == 0x22) fprintf (stderr, " ARRP_TriggeredInformationStopAnswer ");
|
||||
if (report == 0x25) fprintf (stderr, " ARRP_UnsolicitedInformationReport_NCDT ");
|
||||
if (report == 0x26) fprintf (stderr, " ARRP_UnsolicitedInformationReport_NCDT ");
|
||||
if (report == 0x27) fprintf (stderr, " ARRP_InformationProtocolRequest_NCDT ");
|
||||
if (report == 0x13) fprintf (stderr, " LRRP_UnsolicitedLocationReport_NCDT ");
|
||||
if (report == 0x15) fprintf (stderr, " LRRP_UnsolicitedLocationReport_NCDT ");
|
||||
|
||||
}
|
||||
if (source)
|
||||
{
|
||||
fprintf (stderr, "\n");
|
||||
@@ -581,12 +492,6 @@ void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DM
|
||||
fprintf (stderr, " Lon: %.5lf", lon_fin);
|
||||
fprintf (stderr, " (%.5lf, %.5lf)", lat_fin , lon_fin);
|
||||
|
||||
// if (opts->lrrp_file_output == 1)
|
||||
// {
|
||||
// fprintf (pFile, "%.5lf\t", lat_fin);
|
||||
// fprintf (pFile, "%.5lf\t", lon_fin);
|
||||
// }
|
||||
|
||||
}
|
||||
//always print into the lrrp file, even if zeroes, keep alignment correct
|
||||
if (opts->lrrp_file_output == 1)
|
||||
@@ -646,25 +551,16 @@ void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DM
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else if (pot_report)
|
||||
{
|
||||
fprintf (stderr, "\n");
|
||||
fprintf (stderr, " Potential ARRP/LRRP Report (Debug): 0x%02X", report);
|
||||
}
|
||||
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
|
||||
}
|
||||
|
||||
void dmr_locn (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DMR_PDU[])
|
||||
void dmr_locn (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t * DMR_PDU)
|
||||
{
|
||||
UNUSED(opts);
|
||||
|
||||
int i;
|
||||
uint8_t slot = state->currentslot;
|
||||
uint8_t blocks = state->data_header_blocks[slot];
|
||||
uint8_t padding = state->data_header_padding[slot];
|
||||
uint8_t source = state->dmr_lrrp_source[slot];
|
||||
|
||||
//flags if certain data type is present
|
||||
@@ -714,7 +610,7 @@ void dmr_locn (dsd_opts * opts, dsd_state * state, uint8_t block_len, uint8_t DM
|
||||
UNUSED2(lat_sign, lon_sign);
|
||||
|
||||
//start looking for specific bytes corresponding to 'letters' A (time), NSEW (ordinal directions), etc
|
||||
for (i = 0; i < ( (blocks*block_len) - (padding+4) ); i++)
|
||||
for (uint16_t i = 0; i < len; i++)
|
||||
{
|
||||
switch(DMR_PDU[i]){
|
||||
case 0x41: //A -- time and date
|
||||
|
||||
Reference in New Issue
Block a user