P25 - R34 MPDU Format WIP2;

This commit is contained in:
lwvmobile
2023-11-24 15:52:54 -05:00
parent 5d26333676
commit 0ecc9765dd
2 changed files with 224 additions and 152 deletions

View File

@@ -3,53 +3,64 @@
* P25p1 Multi Block PDU and Multi Block Trunking
*
* LWVMOBILE
* 2023-03 DSD-FME Florida Man Edition
* 2023-12 DSD-FME Florida Man Edition
*-----------------------------------------------------------------------------*/
#include "dsd.h"
void processSAP(uint8_t SAP)
void processRSP(uint8_t C, uint8_t T, uint8_t S, char * rsp_string)
{
if (SAP == 0) fprintf (stderr, " User Data;");
else if (SAP == 1) fprintf (stderr, " Encrypted User Data;");
else if (SAP == 2) fprintf (stderr, " Circuit Data;");
else if (SAP == 3) fprintf (stderr, " Circuit Data Control;");
else if (SAP == 4) fprintf (stderr, " Packet Data;");
else if (SAP == 5) fprintf (stderr, " Address Resolution Protocol;");
else if (SAP == 6) fprintf (stderr, " SNDCP Packet Data Control;");
else if (SAP == 31) fprintf (stderr, " Extended Address;");
else if (SAP == 32) fprintf (stderr, " Registration and Authorization;");
else if (SAP == 33) fprintf (stderr, " Channel Reassignment;");
else if (SAP == 34) fprintf (stderr, " System Configuration;");
else if (SAP == 35) fprintf (stderr, " Mobile Radio Loopback;");
else if (SAP == 36) fprintf (stderr, " Mobile Radio Statistics;");
else if (SAP == 37) fprintf (stderr, " Mobile Radio Out of Service;");
else if (SAP == 38) fprintf (stderr, " Mobile Radio Paging;");
else if (SAP == 39) fprintf (stderr, " Mobile Radio Configuration;");
else if (SAP == 40) fprintf (stderr, " Unencrypted Key Management;");
else if (SAP == 41) fprintf (stderr, " Encrypted Key Management;");
else if (SAP == 61) fprintf (stderr, " Trunking Control;");
else if (SAP == 63) fprintf (stderr, " Encrypted Trunking Control;");
//speculative values below based on observation and guess work
//MPDUs immediately following this seems to be encrypted based on the padding octets being non-zeroes (or could just be a decoder failure)
else if (SAP == 8) fprintf (stderr, " Encrytion Parameters?;");
//observed values, but no idea, they all seem to have the same octet values (address of some sort?)
else if (SAP == 0x9) fprintf (stderr, " Unknown SAP;");
else if (SAP == 0xA) fprintf (stderr, " Unknown SAP;");
else if (SAP == 0xB) fprintf (stderr, " Unknown SAP;");
else if (SAP == 0xC) fprintf (stderr, " Unknown SAP;");
else if (SAP == 0xE) fprintf (stderr, " Unknown SAP;");
else if (SAP == 0x2E) fprintf (stderr, " Unknown SAP;");
if (C == 0) sprintf (rsp_string, " ACK (Success);");
else if (C == 2) sprintf (rsp_string, " SACK (Retry);");
else if (C == 1)
{
if (T == 0) sprintf (rsp_string, " NACK (Illegal Format);");
else if (T == 1) sprintf (rsp_string, " NACK (CRC32 Failure);");
else if (T == 2) sprintf (rsp_string, " NACK (Memory Full);");
else if (T == 3) sprintf (rsp_string, " NACK (FSN Sequence Error);");
else if (T == 4) sprintf (rsp_string, " NACK (Undeliverable);");
else if (T == 5) sprintf (rsp_string, " NACK (NS/VR Sequence Error);"); //depreciated
else if (T == 6) sprintf (rsp_string, " NACK (Invalid User on System);");
}
//catch all for everything else
else fprintf (stderr, " Unknown SAP;");
fprintf (stderr, " Response Packet:%s C: %X; T: %X; S: %X; ", rsp_string, C, T, S);
}
static uint32_t crc32mbf(uint8_t buf[], int len)
void processSAP(uint8_t SAP, char * sap_string)
{
if (SAP == 0) sprintf (sap_string, " User Data;");
else if (SAP == 1) sprintf (sap_string, " Encrypted User Data;");
else if (SAP == 2) sprintf (sap_string, " Circuit Data;");
else if (SAP == 3) sprintf (sap_string, " Circuit Data Control;");
else if (SAP == 4) sprintf (sap_string, " Packet Data;");
else if (SAP == 5) sprintf (sap_string, " Address Resolution Protocol;");
else if (SAP == 6) sprintf (sap_string, " SNDCP Packet Data Control;");
else if (SAP == 31) sprintf (sap_string, " Extended Address;");
else if (SAP == 32) sprintf (sap_string, " Registration and Authorization;");
else if (SAP == 33) sprintf (sap_string, " Channel Reassignment;");
else if (SAP == 34) sprintf (sap_string, " System Configuration;");
else if (SAP == 35) sprintf (sap_string, " Mobile Radio Loopback;");
else if (SAP == 36) sprintf (sap_string, " Mobile Radio Statistics;");
else if (SAP == 37) sprintf (sap_string, " Mobile Radio Out of Service;");
else if (SAP == 38) sprintf (sap_string, " Mobile Radio Paging;");
else if (SAP == 39) sprintf (sap_string, " Mobile Radio Configuration;");
else if (SAP == 40) sprintf (sap_string, " Unencrypted Key Management;");
else if (SAP == 41) sprintf (sap_string, " Encrypted Key Management;");
else if (SAP == 61) sprintf (sap_string, " Trunking Control;");
else if (SAP == 63) sprintf (sap_string, " Encrypted Trunking Control;");
//catch all for everything else
else sprintf (sap_string, " Unknown SAP;");
fprintf (stderr, "SAP: 0x%02X;%s ", SAP, sap_string);
}
// static uint32_t crc32mbf(uint8_t buf[], int len)
static uint32_t crc32mbf(uint8_t * buf, int len)
{
uint32_t g = 0x04c11db7;
uint64_t crc = 0;
@@ -83,6 +94,7 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
memset (tsbk_dibit, 0, sizeof(tsbk_dibit));
int dibit = 0;
int r34 = 0;
uint8_t tsbk_byte[12]; //12 byte return from p25_12
memset (tsbk_byte, 0, sizeof(tsbk_byte));
@@ -90,38 +102,38 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
uint8_t r34byte_b[18];
memset (r34byte_b, 0, sizeof(r34byte_b));
uint8_t r34bytes[18*10]; //18 octets at 10 blocks (unsure of maximum needed, going with 10?)
//TODO: Expand storage to be able to hold 127 blocks + 1 header of data at 144 bits (18 octets
uint8_t r34bytes[18*129]; //18 octets at 129 blocks (a little extra padding)
memset (r34bytes, 0, sizeof(r34bytes));
int r34 = 0;
unsigned long long int PDU[18*129];
memset (PDU, 0, 18*129*sizeof(unsigned long long int));
//these expansions may be overkill, will need to look at them
//and find optimal values for them at a later time
unsigned long long int PDU[24*10];
memset (PDU, 0, sizeof(PDU));
int tsbk_decoded_bits[190*10]; //decoded bits from tsbk_bytes for sending to crc16_lb_bridge
int tsbk_decoded_bits[18*129*8]; //decoded bits from tsbk_bytes for sending to crc16_lb_bridge
memset (tsbk_decoded_bits, 0, sizeof(tsbk_decoded_bits));
uint8_t mpdu_decoded_bits[288*20];
uint8_t mpdu_decoded_bits[18*129*8];
memset (mpdu_decoded_bits, 0, sizeof(mpdu_decoded_bits));
uint8_t mpdu_crc_bits[196*20];
uint8_t mpdu_crc_bits[18*129*8];
memset (mpdu_crc_bits, 0, sizeof(mpdu_crc_bits));
uint8_t mpdu_crc_bytes[24*10];
uint8_t mpdu_crc9_bits[18*129*8];
memset (mpdu_crc9_bits, 0, sizeof(mpdu_crc9_bits));
uint8_t mpdu_crc_bytes[18*129];
memset (mpdu_crc_bytes, 0, sizeof(mpdu_crc_bytes));
int i, j, k, x;
int ec[10]; //error value returned from p25_12 or 34
int err[2]; //error value returned from ccrc16 or crc32
int i, j, k, x, z, l; z = 0; l = 0;
int ec[129]; //error value returned from p25_12 or 34 trellis decoder
int err[2]; //error value returned from crc16 on header and crc32 on full message
memset (ec, -2, sizeof(ec));
memset (err, -2, sizeof(err));
int skipdibit = 14; //initial status dibit will occur at 14, then add 36 each time it occurs
int MFID = 0xFF; //Manufacturer ID
uint8_t mpdu_byte[36];
uint8_t mpdu_byte[18*129];
memset (mpdu_byte, 0, sizeof(mpdu_byte));
uint8_t an = 0;
@@ -131,25 +143,36 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
uint8_t blks = 0;
uint8_t opcode = 0;
uint32_t target1 = 0;
uint32_t target2 = 0; //enchanced addressing value
uint32_t address = 0; //source, or destination address depending on the io bit (outbound is target)
// uint32_t target2 = 0; //enhanced addressing source value found in a second 1/2 rate header
uint8_t fmf = 0;
uint8_t pad = 0;
uint8_t ns = 0;
uint8_t fsnf = 0;
uint8_t offset = 0;
int end = 3; //ending value for data gathering repititions
//response packet
uint8_t class = 0;
uint8_t type = 0;
uint8_t status = 0;
int end = 3; //ending value for data gathering repetitions (default at 3)
//CRC32
uint32_t CRCComputed = 0;
uint32_t CRCExtracted = 0;
int stop = 101;
int start = 0;
//collect x-len reps of 101 dibits (98 valid dibits with status dibits interlaced)
for (j = 0; j < end; j++)
{
k = 0;
for (i = 0; i < 101; i++)
if (j == 3) //may need to do this for multiple alignments, unsure, or change this part to work more...better....still need to triple check this
start = 1; //fixes decoding error past j 2 repitition, since the status dibit is perfectly aligned at the starting value at that point
else start = 0;
for (i = start; i < stop; i++)
{
dibit = getDibit(opts, state);
@@ -164,7 +187,7 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
if (i+(j*101) == skipdibit)
{
skipdibit += 36; //was set to 35, this was the bug
skipdibit += 36;
}
}
@@ -172,15 +195,33 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
//send header to p25_12 and return tsbk_byte
if (j == 0) ec[j] = p25_12 (tsbk_dibit, tsbk_byte);
//look at the header now and determine whether or not to
//decode using 34 or 12 rate decoders
else if (r34)
{
//debug
// fprintf (stderr, " J:%d;", j); //use this with the P_ERR inside of 34 rate decoder to see where the failures occur
ec[j] = dmr_34 (tsbk_dibit, r34byte_b);
//shuffle 34 rate data into array
if (j != 0) //should never happen, but just in case
memcpy (r34bytes+((j-1)*18), r34byte_b, sizeof(r34byte_b));
for (i = 2; i < 18; i++)
{
for (x = 0; x < 8; x++)
mpdu_crc_bits[z++] = ((r34byte_b[i] << x) & 0x80) >> 7;
}
//arrangement for confirmed data crc9 check
//unlike DMR, the first 7 bits of this arrangement are the DBSN, not the last 7 bits
for (x = 0; x < 7; x++)
mpdu_crc9_bits[l++] = ((r34byte_b[0] << x) & 0x80) >> 7;
for (i = 2; i < 18; i++)
{
for (x = 0; x < 8; x++)
mpdu_crc9_bits[l++] = ((r34byte_b[i] << x) & 0x80) >> 7;
}
}
else ec[j] = p25_12 (tsbk_dibit, tsbk_byte);
@@ -216,8 +257,7 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
mpdu_byte[i+(j*12)] = byte; //add to completed MBF format 12 rate bytes
}
//check header data to see if this is a 12 rate trunking setup, or
//34 rate packet data unit
//check header data to see if this is a 12 rate, or 4 rate packet data unit
if (j == 0 && err[0] == 0)
{
an = (mpdu_byte[0] >> 6) & 0x1;
@@ -226,8 +266,7 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
sap = mpdu_byte[1] & 0x3F;
blks = mpdu_byte[6] & 0x7F;
MFID = mpdu_byte[2];
target1 = (mpdu_byte[3] << 16) | (mpdu_byte[4] << 8) | mpdu_byte[5]; //LLID, inbound is the source, outbound is the target
target2 = (mpdu_byte[6] << 16) | (mpdu_byte[7] << 8) | mpdu_byte[8]; //unknown which octets convey the secondary address value
address = (mpdu_byte[3] << 16) | (mpdu_byte[4] << 8) | mpdu_byte[5]; //LLID, inbound is the source, outbound is the target
fmf = (mpdu_byte[6] >> 7) & 0x1;
pad = mpdu_byte[7] & 0x1F;
@@ -235,51 +274,49 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
fsnf = mpdu_byte[8] & 0xF;
offset = mpdu_byte[9] & 0x3F;
//response packet
class = (mpdu_byte[1] >> 6) & 0x3;
type = (mpdu_byte[1] >> 3) & 0x7;
status = (mpdu_byte[1] >> 0) & 0x7;
if (an == 1 && fmt == 0b10110) //confirmed data packet header block
r34 = 1;
//set end value to number of blocks + 1 (block gathering for variable len)
end = blks + 1;
//set end value to number of blocks + 1 header (block gathering for variable len)
if (sap != 61 && sap != 63) //if not a trunking control block, this fixes an annoyance TSBK/TDULC blink in ncurses
end = blks + 1; //(TDU follows any Trunking MPDU, not sure if that's an error in handling, or actual behavior)
//sanity check
if (end > 10) end = 10; //TODO: Increase storage for handling these (unsure of upper limit)
//sanity check -- since blks is only 7 bit anyways, this probably isn't needed now
if (end > 128) end = 128; //Storage for up to 127 blocks plus 1 header
//old method for figuring this out, still unclear in the manual which is considered 12 rate, and which are 34 rate
// if ((sap == 0x3D) && ((fmt == 0x17) || (fmt == 0x15))) ; //MBT format 12 rate
// else r34 = 1; //set flag to decode as 34 rate data PDU (confirmed)
}
}
//group list mode so we can look and see if we need to block tuning any groups, etc
char mode[8]; //allow, block, digital, enc, etc
sprintf (mode, "%s", "");
//if we are using allow/whitelist mode, then write 'B' to mode for block
//comparison below will look for an 'A' to write to mode if it is allowed
if (opts->trunk_use_allow_list == 1) sprintf (mode, "%s", "B");
if (err[0] == 0)
{
fprintf (stderr, "%s",KGRN);
fprintf (stderr, " P25 Data - AN: %d; IO: %d; FMT: %02X; SAP: 0x%02X;", an, io, fmt, sap);
processSAP(sap); //decode SAP to see what kind of data we are dealing with
fprintf (stderr, "\n F: %d; Blocks: %02X; Pad: %d; NS: %d; FSNF: %d; Offset: %d; MFID: %02X;", fmf, blks, pad, ns, fsnf, offset, MFID);
fprintf (stderr, " P25 Data - AN: %d; IO: %d; FMT: %02X; ", an, io, fmt);
char sap_string[40];
char rsp_string[40];
if (fmt != 3) processSAP (sap, sap_string); //decode SAP to see what kind of data we are dealing with
else processRSP (class, type, status, rsp_string); //decode the response type (ack, nack, sack)
if (sap != 61 && sap != 63) //Not too interested in viewing these on trunking control, just data packets mostly
fprintf (stderr, "\n F: %d; Blocks: %02X; Pad: %d; NS: %d; FSNF: %d; Offset: %d; MFID: %02X;", fmf, blks, pad, ns, fsnf, offset, MFID);
if (io == 1 && sap != 61 && sap != 63) //destination address if IO bit set
fprintf (stderr, " Target: %d;", target1);
fprintf (stderr, " Address: %d;", address);
// if (sap == 31) //still unclear on which octets or SAP convey this address, this sap is for extended address (same thing?)
// fprintf (stderr, " Source: %d;", target2); //unsure if this is a source address, manual just says a second address
UNUSED(target2);
//Print to Data Call String for Ncurses Terminal (if not trunking control or response packet)
if (sap != 61 && sap != 63 && fmt != 3)
sprintf (state->dmr_lrrp_gps[0], "Data Call:%s SAP:%02X; Address: %d; ", sap_string, sap, address);
//TODO: Print to Data Call String for Ncurses Terminal
}
else //crc error, so we can't validate information as accurate
{
fprintf (stderr, "%s",KRED);
fprintf (stderr, " P25 Data Header CRC Error");
fprintf (stderr, "%s",KNRM);
sprintf (state->dmr_lrrp_gps[0], "Data Call: Header Error; Unknown Format/SAP;");
end = 1; //go ahead and end after this loop
}
@@ -292,23 +329,20 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
if (fmt == 0x17) opcode = mpdu_byte[7] & 0x3F; //alt MBT
else opcode = mpdu_byte[12] & 0x3F; //unconf MBT
fprintf (stderr, " - OP: %02X", opcode);
//CRC32 is now working!
for (i = 0; i < 196; i++) mpdu_crc_bits[i] = mpdu_decoded_bits[i+96];
for (i = 0; i < 24; i++) mpdu_crc_bytes[i] = mpdu_byte[i+12];
if (blks == 1) //blocks to follow is 1
{
CRCExtracted = (uint32_t)ConvertBitIntoBytes(&mpdu_crc_bits[96-32], 32);
CRCComputed = crc32mbf(mpdu_crc_bytes, 96-32);
if (CRCComputed == CRCExtracted) err[1] = 0;
}
if (blks == 2) //blocks to follow is 2
{
CRCExtracted = (uint32_t)ConvertBitIntoBytes(&mpdu_crc_bits[192-32], 32);
CRCComputed = crc32mbf(mpdu_crc_bytes, 192-32);
if (CRCComputed == CRCExtracted) err[1] = 0;
}
CRCExtracted = (mpdu_byte[(12*(blks+1))-4] << 24) | (mpdu_byte[(12*(blks+1))-3] << 16) | (mpdu_byte[(12*(blks+1))-2] << 8) | (mpdu_byte[(12*(blks+1))-1] << 0);
CRCComputed = crc32mbf(mpdu_byte+12, (96*blks)-32);
if (CRCComputed == CRCExtracted) err[1] = 0;
//group list mode so we can look and see if we need to block tuning any groups, etc
char mode[8]; //allow, block, digital, enc, etc
sprintf (mode, "%s", "");
//if we are using allow/whitelist mode, then write 'B' to mode for block
//comparison below will look for an 'A' to write to mode if it is allowed
if (opts->trunk_use_allow_list == 1) sprintf (mode, "%s", "B");
//just going to do a couple for now -- the extended format will not be vPDU compatible :(
if (err[0] == 0 && err[1] == 0 && io == 1 && fmt == 0x17) //ALT Format
@@ -926,63 +960,67 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
else if (r34 == 1 && err[0] == 0) //start 34 rate dump if good header crc
{
//WIP: CRC32 (skip the CRC9, not really needed when you can just do the completed one)
// for (i = 0; i < 196; i++) mpdu_crc_bits[i] = mpdu_decoded_bits[i+96+16];
// for (i = 0; i < 16; i++) mpdu_crc_bytes[i] = mpdu_byte[i+12+2];
// if (blks == 1) //blocks to follow is 1
// {
// CRCExtracted = (uint32_t)ConvertBitIntoBytes(&mpdu_crc_bits[96-32], 32);
// CRCComputed = crc32mbf(mpdu_crc_bytes, 96-32);
// if (CRCComputed == CRCExtracted) err[1] = 0;
// }
// if (blks == 2) //blocks to follow is 2
// {
// CRCExtracted = (uint32_t)ConvertBitIntoBytes(&mpdu_crc_bits[192-32], 32);
// CRCComputed = crc32mbf(mpdu_crc_bytes, 192-32);
// if (CRCComputed == CRCExtracted) err[1] = 0;
// }
//TODO: Combine both of these into one PDU bit set and run CRC on it, etc
//TODO: Handle the Confirmed Data Aspects of this format (CRC9 and DBSN)
//TOOD: Decode some LRRP and/or Text Message Formats, etc
// if (opts->payload == 1)
// if (opts->payload == 1) //always dump these for now since users are actively choosing to tune to these grants
{
fprintf (stderr, "%s",KCYN);
fprintf (stderr, "\n P25 MPDU Payload \n ");
fprintf (stderr, "\n P25 MPDU 34 Rate Payload \n ");
for (i = 0; i < 12; i++) //header
fprintf (stderr, "[%02X]", mpdu_byte[i]);
fprintf (stderr, " Header \n ");
memset (mpdu_byte, 0, sizeof(mpdu_byte));
for (i = 0; i < 16*10; i++) //16*(blks+1)
mpdu_byte[i] = (uint8_t)ConvertBitIntoBytes(&mpdu_crc_bits[i*8], 8);
CRCExtracted = (uint32_t)ConvertBitIntoBytes(&mpdu_crc_bits[(128*blks)-32], 32);
CRCComputed = crc32mbf(mpdu_byte, (128*blks)-32);
if (CRCComputed == CRCExtracted) err[1] = 0;
int next = 0;
//variable len printing
for (i = 0; i < 18*blks; i++)
for (i = 2; i <= 18*blks; i++) //<= only because we want that final DBSN/CRC9 printed out
{
if (i == 18 || i == 36 || i == 54 || i == 72 || i == 90)
fprintf (stderr, "\n ");
fprintf (stderr, "[%02X]", r34bytes[i]);
{
uint8_t dbsn = r34bytes[i-18] >> 1; //get the previous DBSN at this point
uint16_t crc9_ext = ((r34bytes[i-18] & 1) << 8) | r34bytes[i-17];
uint16_t crc9_cmp = ComputeCrc9Bit(mpdu_crc9_bits+next, 135);
next += 135;
if (crc9_ext == crc9_cmp)
fprintf (stderr, " DBSN: %d;", dbsn+1);
else
{
fprintf (stderr, "%s",KRED);
fprintf (stderr, " CRC ERR;");
fprintf (stderr, "%s",KCYN);
// fprintf (stderr, " EXT: %03X; CMP: %03X", crc9_ext, crc9_cmp);
}
if (i != 18*blks) i += 2; //skip the next DBSN/CRC9
if (i != 18*blks) fprintf (stderr, "\n ");
}
if (i != 18*blks) fprintf (stderr, "[%02X]", r34bytes[i]);
}
// if (err[1] != 0)
// {
// fprintf (stderr, "%s",KRED);
// fprintf (stderr, " (MPDU CRC32 ERR)");
// fprintf (stderr, "%s",KCYN);
// fprintf (stderr, " CRC EXT %08X CMP %08X", CRCExtracted, CRCComputed); //TODO
// }
fprintf (stderr, "\n P25 MPDU ASCII: ");
for (i = 2; i < (18*blks)-4; i++) //skip the first DBSN/CRC9 and Final CRC32
if (err[1] != 0)
{
if (i == 16 || i == 32 || i == 48 || i == 60 || i == 72)
i += 2; // skip the next DBSN/CRC9 values
if (r34bytes[i] <= 0x7E && r34bytes[i] >=0x20)
fprintf (stderr, "%s",KRED);
fprintf (stderr, "\n (MPDU CRC32 ERR)");
fprintf (stderr, "%s",KCYN);
fprintf (stderr, " CRC EXT %08X CMP %08X", CRCExtracted, CRCComputed);
}
else //testing for grins
dmr_pdu (opts, state, blks*16, mpdu_byte);
// if (sap == 0) //user data
{
fprintf (stderr, "%s",KCYN);
fprintf (stderr, "\n P25 MPDU ASCII: ");
for (i = 0; i < (16*blks)-4; i++)
{
fprintf (stderr, "%c", r34bytes[i]);
if (mpdu_byte[i] <= 0x7E && mpdu_byte[i] >=0x20)
fprintf (stderr, "%c", mpdu_byte[i]);
else fprintf (stderr, " ");
}
else fprintf (stderr, " ");
}
fprintf (stderr, "%s ", KNRM);
@@ -990,18 +1028,48 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
}
} //end r34
else if (err[0] == 0)
else if (err[0] == 0) //12 rate unconfirmed data
{
//just print the header
if (blks != 0)
{
CRCExtracted = (mpdu_byte[(12*(blks+1))-4] << 24) | (mpdu_byte[(12*(blks+1))-3] << 16) | (mpdu_byte[(12*(blks+1))-2] << 8) | (mpdu_byte[(12*(blks+1))-1] << 0);
CRCComputed = crc32mbf(mpdu_byte+12, (96*blks)-32);
if (CRCComputed == CRCExtracted) err[1] = 0;
}
else err[1] = 0; //No CRC32 on a lonely header
// if (opts->payload == 1)
{
fprintf (stderr, "%s",KCYN);
fprintf (stderr, "\n P25 MPDU Header: ");
for (i = 0; i < 12; i++) //header
fprintf (stderr, "\n P25 MPDU 12 Rate Payload: \n ");
for (i = 0; i < 12*(blks+1); i++) //header and payload combined
{
if (i == 12) fprintf (stderr, " Header");
if (i == 12 || i == 24 || i == 36 || i == 48 || i == 60 || i == 72 || i == 84 || i == 90)
fprintf (stderr, "\n ");
fprintf (stderr, "[%02X]", mpdu_byte[i]);
fprintf (stderr, "%s",KNRM);
fprintf (stderr, "\n");
}
}
if (err[1] != 0)
{
fprintf (stderr, "%s",KRED);
fprintf (stderr, "\n (MPDU CRC32 ERR)");
fprintf (stderr, "%s",KCYN);
fprintf (stderr, " CRC EXT %08X CMP %08X", CRCExtracted, CRCComputed);
}
else if (blks != 0) //testing for grins
dmr_pdu (opts, state, blks*16, mpdu_byte);
fprintf (stderr, "%s",KNRM);
fprintf (stderr, "\n");
}
else fprintf (stderr, "\n");
else //crc header failure or other
{
fprintf (stderr, "%s",KNRM);
fprintf (stderr, "\n");
}
}

View File

@@ -127,6 +127,10 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
protectbit = (tsbk_byte[0] >> 6) & 0x1;
lb = (tsbk_byte[0] >> 7) & 0x1;
//zero out data calls after returning from a SNDCP data channel
if (err == 0)
sprintf (state->dmr_lrrp_gps[0], "%s", "");
//Don't run NET_STS out of this, or will set wrong NAC/CC
//Note: Running MFID 90 (moto) opcode 9 GRG Delete or Reserve will falsely trigger a telephone interconnect grant
if (MFID < 0x2 && protectbit == 0 && err == 0 && PDU[1] != 0x7B )