diff --git a/src/bptc.c b/src/bptc.c index 74ac0e2..a8b82a4 100644 --- a/src/bptc.c +++ b/src/bptc.c @@ -199,18 +199,10 @@ uint32_t BPTC_196x96_Extract_Data(uint8_t InputDeInteleavedData[196], uint8_t DM } } - /* R(0) to R(2) may be used to transport some - * Restricted Access System (RAS) information, - * So save these three bytes before reset all of them - * See patent US 2013/0288643 A1 */ - R[0] = DataMatrix[0][2]; /* Save R(0) */ - R[1] = DataMatrix[0][1]; /* Save R(1) */ - R[2] = DataMatrix[0][0]; /* Save R(2) */ - /* Set to 0 R(0) to R(2) - See DMR standard chapter B1.1 BPTC (196,96) */ - DataMatrix[0][0] = 0; /* R(2) */ - DataMatrix[0][1] = 0; /* R(1) */ - DataMatrix[0][2] = 0; /* R(0) */ + // DataMatrix[0][0] = 0; /* R(2) */ + // DataMatrix[0][1] = 0; /* R(1) */ + // DataMatrix[0][2] = 0; /* R(0) */ /* Init the Hamming (15,11,3) library * Not needed because it has already been done @@ -363,6 +355,14 @@ uint32_t BPTC_196x96_Extract_Data(uint8_t InputDeInteleavedData[196], uint8_t DM } } + /* R(0) to R(2) may be used to transport some + * Restricted Access System (RAS) information, + * So save these three bits after hamming correction + * See patent US 2013/0288643 A1 */ + R[0] = DataMatrix[0][2]; /* Save R(0) */ + R[1] = DataMatrix[0][1]; /* Save R(1) */ + R[2] = DataMatrix[0][0]; /* Save R(2) */ + /* Return the number of irrecoverable Hamming errors */ return HammingIrrecoverableErrorNb; } /* End BPTC_196x96_Extract_Data() */ diff --git a/src/dmr_block.c b/src/dmr_block.c index b3b386a..8207864 100644 --- a/src/dmr_block.c +++ b/src/dmr_block.c @@ -81,7 +81,7 @@ void dmr_dheader (dsd_opts * opts, dsd_state * state, uint8_t dheader[], uint32_ fprintf (stderr, "%s ", KNRM); //end collecting data header info - fprintf (stderr, "%s ", KMAG); + fprintf (stderr, "%s ", KYEL); if (state->data_header_sap[slot] == 0x4 && state->data_p_head[slot] == 0) { @@ -247,11 +247,11 @@ void dmr_dheader (dsd_opts * opts, dsd_state * state, uint8_t dheader[], uint32_ fprintf (stderr, "%s ", KNRM); //let user know the data header may have errors - fprintf (stderr, "%s", KRED); - if (CRCCorrect == 1) ; //CRCCorrect 1 is good, else is bad CRC; no print on good - else if(IrrecoverableErrors == 0) fprintf(stderr, " (FEC OK)"); - else fprintf(stderr, " (FEC/CRC ERR)"); - fprintf (stderr, "%s", KNRM); + // fprintf (stderr, "%s", KRED); + // if (CRCCorrect == 1) ; //CRCCorrect 1 is good, else is bad CRC; no print on good + // else if(IrrecoverableErrors == 0) fprintf(stderr, " (FEC OK)"); + // else fprintf(stderr, " (FEC/CRC ERR)"); + // fprintf (stderr, "%s", KNRM); } @@ -387,6 +387,12 @@ void dmr_block_assembler (dsd_opts * opts, dsd_state * state, uint8_t block_byte CRCCorrect = 1; IrrecoverableErrors = 0; } + else + { + fprintf (stderr, "%s", KRED); + fprintf(stderr, " (CRC ERR)"); + fprintf (stderr, "%s", KNRM); + } //cspdu will only act on any fid/opcodes if good CRC to prevent falsing on control signalling dmr_cspdu (opts, state, dmr_pdu_sf_bits, state->dmr_pdu_sf[slot], CRCCorrect, IrrecoverableErrors); diff --git a/src/dmr_bs.c b/src/dmr_bs.c index 21a2046..5387a5e 100644 --- a/src/dmr_bs.c +++ b/src/dmr_bs.c @@ -740,7 +740,7 @@ void dmrBSBootstrap (dsd_opts * opts, dsd_state * state) fprintf (stderr,"%s ", getTime()); fprintf (stderr,"Sync: DMR "); fprintf (stderr, "%s", KRED); - fprintf (stderr, "| VOICE TACT/SYNC ERR"); + fprintf (stderr, "| VOICE CACH/SYNC ERR"); fprintf (stderr, "%s", KNRM); //run LFSR if either slot had an active MI in it. if (state->payload_algid >= 0x21) diff --git a/src/dmr_data.c b/src/dmr_data.c index 0c35c7e..d4b16ff 100644 --- a/src/dmr_data.c +++ b/src/dmr_data.c @@ -300,7 +300,8 @@ dmr_data_sync (dsd_opts * opts, dsd_state * state) info[(2*i) + 99] = (1 & dibit); // bit 0 } - dmr_data_burst_handler(opts, state, (uint8_t *)info, burst); + //don't run on MS Reverse Channel Data + if (state->dmr_ms_rc == 0) dmr_data_burst_handler(opts, state, (uint8_t *)info, burst); //don't run cach on simplex or mono if (state->dmr_ms_mode == 0 || opts->dmr_mono == 0) diff --git a/src/dmr_dburst.c b/src/dmr_dburst.c index c1c583e..b0f4d84 100644 --- a/src/dmr_dburst.c +++ b/src/dmr_dburst.c @@ -46,6 +46,7 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196 uint8_t R[3]; uint8_t BPTCReservedBits = 0; uint8_t is_ras = 0; + uint8_t crc_original_validity = 0; uint32_t crcmask = 0; uint8_t crclen = 0; @@ -156,6 +157,7 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196 break; //special types (not real data 'sync' bursts) case 0xEB: //Embedded Signalling + crclen = 5; is_emb = 1; pdu_len = 9; break; @@ -252,15 +254,19 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196 else CRCCorrect = 0; } - //set the 'RAS Flag', if no irrecoverable errors but bad crc - if (CRCCorrect == 0 && IrrecoverableErrors == 0 && BPTCReservedBits == 4) is_ras = 1; //!=0, or == 0x4, or just R[2] == 1 + //set the 'RAS Flag', if no irrecoverable errors but bad crc, only when enabled by user (to prevent a lot of bad data CSBKs) + if (opts->aggressive_framesync == 0 && CRCCorrect == 0 && IrrecoverableErrors == 0 && BPTCReservedBits == 4) is_ras = 1; //!=0, or == 0x4, or just R[2] == 1 //make sure the system type isn't Hytera, but could just be bad decodes on bad sample if (BPTCDmrDataByte[1] == 0x68) is_ras = 0; //if this is a RAS system, set the CRC to okay if irrecoverable errors is okay //if we don't do this, then we can't view some data (CSBKs on RAS enabled systems) - if (is_ras == 1) CRCCorrect = 1; + if (is_ras == 1) + { + crc_original_validity = CRCCorrect; + CRCCorrect = 1; + } if (databurst == 0x04 || databurst == 0x06) //MBC Header, Data Header { @@ -330,11 +336,7 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196 IrrecoverableErrors = BPTC_128x77_Extract_Data(BptcDataMatrix, LC_DataBit); /* Reconstitute the 5 bit CRC */ - CRCExtracted = (LC_DataBit[72] & 1) << 4; - CRCExtracted |= (LC_DataBit[73] & 1) << 3; - CRCExtracted |= (LC_DataBit[74] & 1) << 2; - CRCExtracted |= (LC_DataBit[75] & 1) << 1; - CRCExtracted |= (LC_DataBit[76] & 1) << 0; + CRCExtracted = (uint32_t)ConvertBitIntoBytes(&LC_DataBit[72], 5); /* Compute the 5 bit CRC */ CRCComputed = ComputeCrc5Bit(LC_DataBit); @@ -451,15 +453,43 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196 } if (databurst == 0x05) dmr_block_assembler (opts, state, DMR_PDU, pdu_len, databurst, 2); + //set the original CRCCorrect back to its original value if the RAS flag was tripped + if (is_ras == 1) CRCCorrect = crc_original_validity; + + //start printing relevant fec/crc/ras messages, don't print on idle or MBC continuation blocks (handled in dmr_block.c) + if (CRCCorrect == 1 && databurst != 0x09 && databurst != 0x05) ; //fprintf(stderr, "(CRC OK)"); + + if (IrrecoverableErrors == 0 && CRCCorrect == 0 && databurst != 0x09 && databurst != 0x05) + { + fprintf (stderr, "%s", KYEL); + fprintf(stderr, " (FEC OK)"); + fprintf (stderr, "%s", KNRM); + + } + + if (IrrecoverableErrors != 0 && databurst != 0x09 && databurst != 0x05) + { + fprintf (stderr, "%s", KRED); + fprintf(stderr, " (FEC ERR)"); + fprintf (stderr, "%s", KNRM); + } + //print whether or not the 'RAS Field' bits are set to indicate RAS enabled (to be verified) if (is_ras == 1) { fprintf (stderr, "%s", KRED); - fprintf (stderr, " CRC/RAS "); + fprintf (stderr, " -RAS "); //the value of this field seems to always, or usually, be 4, or just R[2] bit is set if (opts->payload == 1) fprintf (stderr, "%X ", BPTCReservedBits); fprintf (stderr, "%s", KNRM); } + + if (CRCCorrect == 0 && databurst != 0x09 && databurst != 0x05) + { + fprintf (stderr, "%s", KRED); + fprintf (stderr, " (CRC ERR) "); + fprintf (stderr, "%s", KNRM); + } //print the unified PDU format here, if not slot idle if (opts->payload == 1 && databurst != 0x09) diff --git a/src/dmr_flco.c b/src/dmr_flco.c index 8a8689b..52137cd 100644 --- a/src/dmr_flco.c +++ b/src/dmr_flco.c @@ -42,18 +42,18 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C source = (uint32_t)ConvertBitIntoBytes(&lc_bits[48], 24); //look for Cap+ on VLC header, then set source and/or rest channel appropriately - if (type == 1 && fid == 0x10 && (flco == 0x04 || flco == 0x07) ) //0x07 appears to be a cap+ txi private call + if (IrrecoverableErrors == 0 && type == 1 && fid == 0x10 && (flco == 0x04 || flco == 0x07) ) //0x07 appears to be a cap+ txi private call { is_cap_plus = 1; capsite = (uint8_t)ConvertBitIntoBytes(&lc_bits[48], 4); //can't verify, just speculating restchannel = (int)ConvertBitIntoBytes(&lc_bits[52], 4); //was 48,8 source = (uint32_t)ConvertBitIntoBytes(&lc_bits[56], 16); - sprintf (state->dmr_branding, "%s", "Motorola"); - sprintf (state->dmr_branding_sub, "%s", "Cap+ "); + // sprintf (state->dmr_branding, "%s", "Motorola"); + // sprintf (state->dmr_branding_sub, "%s", "Cap+ "); } - if (IrrecoverableErrors == 0 && CRCCorrect == 1) + if (IrrecoverableErrors == 0) { //Embedded Talker Alias Header Only (format and len storage) if (type == 3 && flco == 0x04) @@ -90,7 +90,7 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C //will want to continue to observe for different flco and fid combinations to find out their meaning //Standard Addressing/Cap+ Addressing (trying to avoid embedded alias and gps, etc) - if(IrrecoverableErrors == 0 && is_alias == 0 && is_gps == 0 && CRCCorrect == 1) + if(IrrecoverableErrors == 0 && is_alias == 0 && is_gps == 0) { //set overarching manufacturer in use when non-standard feature id set is up //may not want to set moto 0x10 here either, lots of radios use that set as well @@ -273,10 +273,10 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C fprintf(stderr, "Call "); - fprintf (stderr, "%s", KRED); - if (CRCCorrect == 1) ; //CRCCorrect 1 is good, else is bad CRC; no print on good - else if(IrrecoverableErrors == 0) ; //fprintf(stderr, "(FEC OK)"); - else fprintf(stderr, "(FEC/CRC ERR) "); + // fprintf (stderr, "%s", KRED); + // if (CRCCorrect == 1) ; //fprintf(stderr, "(CRC OK)"); //CRCCorrect 1 is good, else is bad CRC; no print on good + // else if(IrrecoverableErrors == 0) ; //fprintf(stderr, "(FEC OK)"); + // else fprintf(stderr, "(FEC ERR) "); //check Cap+ rest channel info if available and good fec if (is_cap_plus == 1) @@ -321,6 +321,16 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C } + if(IrrecoverableErrors != 0) + { + if (type != 3) fprintf (stderr, "\n"); + fprintf (stderr, "%s", KRED); + fprintf (stderr, " SLOT %d", state->currentslot+1); + fprintf (stderr, " FLCO FEC ERR "); + fprintf (stderr, "%s", KNRM); + } + + } //externalized dmr cach - tact and slco fragment handling @@ -626,18 +636,20 @@ void dmr_slco (dsd_opts * opts, dsd_state * state, uint8_t slco_bits[]) fprintf (stderr, " SLCO Activity Update TS1: %X Hash: %02X TS2: %X Hash: %02X", ts1_act, ts1_hash, ts2_act, ts2_hash); //102 361-2 7.1.3.2 else if (slco == 0x9) { - state->dmr_mfid = 0x10; - sprintf (state->dmr_branding, "%s", "Motorola"); - sprintf (state->dmr_branding_sub, "%s", "Con+ "); + //remove all setting of branding/sub from SLCO, can cause false positives even with seeming good CRC + + // state->dmr_mfid = 0x10; + // sprintf (state->dmr_branding, "%s", "Motorola"); + // sprintf (state->dmr_branding_sub, "%s", "Con+ "); fprintf (stderr, " SLCO Connect Plus Voice Channel - Net ID: %d Site ID: %d", con_netid, con_siteid); sprintf (state->dmr_site_parms, "%d-%d ", con_netid, con_siteid); } else if (slco == 0xA) { - state->dmr_mfid = 0x10; - sprintf (state->dmr_branding, "%s", "Motorola"); - sprintf (state->dmr_branding_sub, "%s", "Con+ "); + // state->dmr_mfid = 0x10; + // sprintf (state->dmr_branding, "%s", "Motorola"); + // sprintf (state->dmr_branding_sub, "%s", "Con+ "); fprintf (stderr, " SLCO Connect Plus Control Channel - Net ID: %d Site ID: %d", con_netid, con_siteid); sprintf (state->dmr_site_parms, "%d-%d ", con_netid, con_siteid); @@ -651,11 +663,11 @@ void dmr_slco (dsd_opts * opts, dsd_state * state, uint8_t slco_bits[]) else if (slco == 0xF) { - state->dmr_mfid = 0x10; - sprintf (state->dmr_branding, "%s", "Motorola"); - sprintf (state->dmr_branding_sub, "%s", "Cap+ "); + // state->dmr_mfid = 0x10; + // sprintf (state->dmr_branding, "%s", "Motorola"); + // sprintf (state->dmr_branding_sub, "%s", "Cap+ "); fprintf (stderr, " SLCO Capacity Plus Site: %d - Rest Channel %d - RS: %02X", capsite+1, restchannel, cap_reserved); - state->dmr_rest_channel = restchannel; + // state->dmr_rest_channel = restchannel; //test without, may work better //assign to cc freq if available if (state->trunk_chan_map[restchannel] != 0) { @@ -663,7 +675,7 @@ void dmr_slco (dsd_opts * opts, dsd_state * state, uint8_t slco_bits[]) } //nullify any previous TIII data (bugfix for bad assignments or system type switching) - sprintf(state->dmr_site_parms, "%s", ""); + // sprintf(state->dmr_site_parms, "%s", ""); } else fprintf (stderr, " SLCO Unknown - %d ", slco); diff --git a/src/dmr_le.c b/src/dmr_le.c index 2954730..210d9c6 100644 --- a/src/dmr_le.c +++ b/src/dmr_le.c @@ -180,7 +180,6 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power) crc_extracted = crc_extracted ^ 0x7A; crc_computed = crc7((uint8_t *) sbrc_return, 11); if (crc_extracted == crc_computed) crc_okay = 1; - if (opts->payload == 1) fprintf (stderr, " CRC EXT %02X, CRC CMP %02X", crc_extracted, crc_computed); } else crc_okay = 1; //SB @@ -203,6 +202,7 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power) fprintf (stderr, "%s", KRED); fprintf (stderr, " (CRC ERR)"); fprintf (stderr, "%s", KNRM); + if (opts->payload == 1) fprintf (stderr, " CRC EXT %02X, CRC CMP %02X", crc_extracted, crc_computed); } } diff --git a/src/dmr_ms.c b/src/dmr_ms.c index b815a05..435095f 100644 --- a/src/dmr_ms.c +++ b/src/dmr_ms.c @@ -186,6 +186,22 @@ void dmrMS (dsd_opts * opts, dsd_state * state) sync[24] = 0; + //test for RC sync pattern in MS sourced audio + if ( strcmp (sync, DMR_RC_DATA_SYNC) == 0) + { + state->dmr_ms_rc = 1; + fprintf (stderr, "%s ", getTime()); + if (opts->inverted_dmr == 0) + { + fprintf (stderr,"Sync: +DMR MS/DM MODE/MONO "); + } + else fprintf (stderr,"Sync: -DMR MS/DM MODE/MONO "); + + fprintf (stderr, "| RC "); + fprintf (stderr, "\n"); + + } + for(i = 0; i < 8; i++) EmbeddedSignalling[i] = syncdata[i]; for(i = 0; i < 8; i++) EmbeddedSignalling[i + 8] = syncdata[i + 40]; @@ -264,19 +280,22 @@ void dmrMS (dsd_opts * opts, dsd_state * state) memcpy (m2, ambe_fr2, sizeof(m2)); memcpy (m3, ambe_fr3, sizeof(m3)); - if (state->directmode == 0) + if (state->dmr_ms_rc == 0) { - processMbeFrame (opts, state, NULL, ambe_fr, NULL); - processMbeFrame (opts, state, NULL, ambe_fr2, NULL); - processMbeFrame (opts, state, NULL, ambe_fr3, NULL); + if (state->directmode == 0) + { + processMbeFrame (opts, state, NULL, ambe_fr, NULL); + processMbeFrame (opts, state, NULL, ambe_fr2, NULL); + processMbeFrame (opts, state, NULL, ambe_fr3, NULL); + } + else + { + processMbeFrame (opts, state, NULL, ambe_fr4, NULL); //play duplicate of 2 here to smooth audio on tdma direct + processMbeFrame (opts, state, NULL, ambe_fr2, NULL); + processMbeFrame (opts, state, NULL, ambe_fr3, NULL); + } } - else - { - processMbeFrame (opts, state, NULL, ambe_fr4, NULL); //play duplicate of 2 here to smooth audio on tdma direct - processMbeFrame (opts, state, NULL, ambe_fr2, NULL); - processMbeFrame (opts, state, NULL, ambe_fr3, NULL); - } - + if (vc == 6) { dmr_data_burst_handler(opts, state, (uint8_t *)dummy_bits, 0xEB); diff --git a/src/dsd_main.c b/src/dsd_main.c index fcfe490..e0ef1e4 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -956,9 +956,8 @@ usage () //printf (" (4 Level, not 8 Level LSM) (this is honestly unknown since I can't verify what local systems are using)\n"); printf (" -F Relax P25 Phase 2 MAC_SIGNAL CRC Checksum Pass/Fail\n"); printf (" Use this feature to allow MAC_SIGNAL even if CRC errors.\n"); - printf (" -F Relax DMR CACH/Burst FEC Pass/Fail - Passive Frame Sync\n"); - printf (" Use if skipping occurs, but may cause wonky audio due to loss of good sync\n"); - + printf (" -F Relax DMR CACH/Burst FEC or RAS/CRC CSBK Pass/Fail\n"); + printf (" Enabling on some systems could lead to bad voice/data decoding if bad or marginal signal\n"); printf ("\n"); printf (" -K Manually Enter Basic Privacy Key (Decimal Value of Key Number)\n"); printf ("\n"); @@ -1514,8 +1513,8 @@ main (int argc, char **argv) opts.aggressive_framesync = 0; fprintf (stderr, "%s", KYEL); //fprintf (stderr,"DMR Stereo Aggressive Resync Disabled!\n"); - fprintf (stderr, "Relax P25 Phase 2 MAC_SIGNAL CRC Checksum Pass/Fail\n"); - fprintf (stderr, "Relax DMR CACH/Burst FEC Pass/Fail\n"); + fprintf (stderr, "Relax P25 Phase 2 MAC_SIGNAL CRC Pass/Fail\n"); + fprintf (stderr, "Relax DMR CACH/Burst FEC or RAS/CRC CSBK Pass/Fail\n"); fprintf (stderr, "%s", KNRM); break; diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c index fb45d40..103fa39 100644 --- a/src/dsd_ncurses.c +++ b/src/dsd_ncurses.c @@ -3222,6 +3222,38 @@ if (opts->p25_trunk == 1 && c == 103) //'g' key, toggle tune group calls else opts->trunk_tune_group_calls = 1; } +if (c == 70) //'F' key - toggle agressive sync/crc failure/ras +{ + if (opts->aggressive_framesync == 0) opts->aggressive_framesync = 1; + else opts->aggressive_framesync = 0; +} + +if (c == 68) //'D' key - Reset DMR Site Parms/Call Strings, etc. +{ + //dmr trunking/ncurses stuff + state->dmr_rest_channel = -1; //init on -1 + state->dmr_mfid = -1; // + + //dmr mfid branding and site parms + sprintf(state->dmr_branding_sub, "%s", ""); + sprintf(state->dmr_branding, "%s", ""); + sprintf (state->dmr_site_parms, "%s", ""); + + //DMR Location Area - DMRLA B***S*** + opts->dmr_dmrla_is_set = 0; + opts->dmr_dmrla_n = 0; + +} + +//Debug/Troubleshooting Option +if (c == 90) //'Z' key - Simulate NoCarrier/No VC/CC sync to zero out more stuff (capital Z) +{ + // opts->p25_is_tuned = 0; + state->last_cc_sync_time = 0; + state->last_vc_sync_time = 0; + noCarrier(opts, state); +} + //anything with an entry box will need the inputs and outputs stopped first //so probably just write a function to handle c input, and when c = certain values //needing an entry box, then stop all of those