From f92c64c4d36ce39b21c3b86f980f5f879a0dbc6c Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Fri, 28 Feb 2025 11:33:23 -0500 Subject: [PATCH] DMR: Fix Data Assembly on Moto Ext Header; Make appropriate adjustments based on above; Additional Tweaks for some LRRP Tokens; --- src/dmr_block.c | 21 +++++++++------------ src/dmr_pdu.c | 34 ++++++++++++++++------------------ 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/src/dmr_block.c b/src/dmr_block.c index f166d6b..29bf452 100644 --- a/src/dmr_block.c +++ b/src/dmr_block.c @@ -363,15 +363,15 @@ 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) has been observed as the first block of LRRP data on a Moto system but doesn't pass the CRC for some reason (included or not included) + //p_sap 1 on mfid 10 (moto) has been observed as the first block of LRRP data (unique fixed format?) if (p_mfid == 0x10 && p_sap == 1) { - //add the header to the first 12 bytes of the storage - for (uint8_t i = 0; i < 12; i++) - state->dmr_pdu_sf[slot][i] = dheader[i]; + //add the header to the first 10 bytes of the storage (sans this header's CRC) + int8_t start = 0; + int8_t len = 10-start; + memcpy(state->dmr_pdu_sf[slot], dheader+start, len*sizeof(uint8_t)); state->data_block_counter[slot]++; - state->data_byte_ctr[slot] += 12; //set current byte ptr to 12 - + state->data_byte_ctr[slot] = len; state->data_p_head[slot] = 1; } @@ -856,7 +856,7 @@ void dmr_block_assembler (dsd_opts * opts, dsd_state * state, uint8_t block_byte } //confirmed working now! - CRCComputed = (uint32_t)ComputeCrc32Bit(dmr_pdu_sf_bits, ( block_num * block_len * 8) - 32); + CRCComputed = (uint32_t)ComputeCrc32Bit(dmr_pdu_sf_bits, (ctr * 8) - 32); //if the CRC32 is correct, I think its fair to assume we don't need to worry about if the //individual CRC9s are correct on confirmed data blocks (but we can confirm now that they are all good) @@ -1022,13 +1022,10 @@ void dmr_block_assembler (dsd_opts * opts, dsd_state * state, uint8_t block_byte } 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) { - //new len calc + //len calc uint16_t ctr = state->data_byte_ctr[slot]; uint8_t poc = state->data_block_poc[slot]; - uint16_t len = len = ctr-poc-4-7; - - //old calc - // uint16_t len = ((blocks+1)*block_len)-4-7; + uint16_t len = len = ctr-poc-4-7-3; //sanity check if (len > 150) diff --git a/src/dmr_pdu.c b/src/dmr_pdu.c index 3ca353b..60e3dcc 100644 --- a/src/dmr_pdu.c +++ b/src/dmr_pdu.c @@ -232,7 +232,7 @@ void dmr_ip_pdu (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t * DMR uint16_t udp_len = (DMR_PDU[24] << 8) | DMR_PDU[25]; //This UDP Length information element is the length in bytes of this user datagram including this header and the application data uint16_t udp_chk = (DMR_PDU[26] << 8) | DMR_PDU[27]; if (opts->payload == 1) - fprintf (stderr, "\n UDP Header Len: %d(%02X); UDP Checksum: %04X; ", udp_len, udp_len, udp_chk); + fprintf (stderr, "\n UDP Datagram Len: %d(%02X); UDP Checksum: %04X; ", udp_len, udp_len, udp_chk); //Are IP DMR PDU types only dictated by Port Number? Or is this just the defaults when programmed? if (port1 == 231 && port2 == 231) @@ -335,46 +335,44 @@ void dmr_lrrp (dsd_opts * opts, dsd_state * state, uint16_t len, uint32_t source sprintf (deg_glyph, "%s", "°"); //debug passed LRRP message - fprintf (stderr, "\n LRRP (Debug): "); - for (uint16_t i = 0; i < len; i++) - fprintf (stderr, "%02X ", DMR_PDU[i]); + // 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 = 0; i < len; i++) { - - switch(DMR_PDU[i]){ + uint8_t token = DMR_PDU[i]; + switch(token){ case 0x0D: //message len indicator - if (i == 0 && message_len == 0) //see if this is the first octet, otherwise, can't verify this is going to work + if (i == 0) //see if this is the first octet, otherwise, can't verify this is going to work { message_len = DMR_PDU[i+1]; - i += 1; + i += 3; //next byte is len, then next two are usually 0x22 0xXX or 0x23 0xXX lrrp_confidence++; } 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 - //see if we can figure out how to intepret this - i += 1; //should this be 2, or 1? - break; - //answer and report tokens + + //tokens case 0x51: //circle-2d case 0x54: //circle-3d case 0x55: //circle-3d if (message_len > 0 && lat == 0) { + //debug + // fprintf (stderr, "\n I: %d; Token: %02X; ", i, token); //must be a bad sample + 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]; i += 10; - if (lat > 0 && lon > 0) lrrp_confidence++; //would be better to set by absolute boundary (180 and 90?) + if (lat > 0 && lon > 0) lrrp_confidence++; else lat = 0; } break; - case 0x34: //Time Interval Periodic Trigger (timestamp) - case 0x35: //Time Interval Periodic Trigger (timestamp) + case 0x34: //Time + case 0x35: //Time if (message_len > 0 && year == 0) { year = (DMR_PDU[i+1] << 6) + (DMR_PDU[i+2] >> 2);