diff --git a/src/dsd_dibit.c b/src/dsd_dibit.c index 27bdc84..eb0851f 100644 --- a/src/dsd_dibit.c +++ b/src/dsd_dibit.c @@ -283,12 +283,11 @@ static int digitize (dsd_opts* opts, dsd_state* state, int symbol) valid = 0; - //only run estimate_symbol when we aren't trunking, otherwise noise/gain levels on other rf channels may impact performance severely - //honestly can't say I've seen any improvement when using heuristics, but is detrimental to playing back multiple p25 samples - if (state->synctype == 1 && opts->p25_trunk == 0) + //re-enabling -- heuristics may also work with P2, but cna't see any benefit, need more P2 C4FM samples for testing + if (state->synctype == 1 && opts->p25_trunk == 1) //|| state->synctype == 36 { // Use the P25 heuristics if available - //valid = estimate_symbol(state->rf_mod, &(state->inv_p25_heuristics), state->last_dibit, symbol, &dibit); + valid = estimate_symbol(state->rf_mod, &(state->inv_p25_heuristics), state->last_dibit, symbol, &dibit); } if (valid == 0) @@ -348,12 +347,11 @@ static int digitize (dsd_opts* opts, dsd_state* state, int symbol) valid = 0; - //only run estimate_symbol when we aren't trunking, otherwise noise/gain levels on other rf channels may impact performance severely - //honestly can't say I've seen any improvement when using heuristics, but is detrimental to playing back multiple p25 samples - if (state->synctype == 0 && opts->p25_trunk == 0) + ////re-enabling, but only when trunking (should have uniform volume if not tampered with during setup) + if (state->synctype == 0 && opts->p25_trunk == 1) //|| state->synctype == 35 { // Use the P25 heuristics if available - //valid = estimate_symbol(state->rf_mod, &(state->p25_heuristics), state->last_dibit, symbol, &dibit); + valid = estimate_symbol(state->rf_mod, &(state->p25_heuristics), state->last_dibit, symbol, &dibit); } if (valid == 0) diff --git a/src/p25p1_block.cpp b/src/p25p1_block.cpp index b654cb3..87c17da 100644 --- a/src/p25p1_block.cpp +++ b/src/p25p1_block.cpp @@ -40,7 +40,8 @@ static int find_min(uint8_t list[], int len) { index = i; unique = 1; } else if (list[i] == min) { - unique = 0; + //unique = 0; + ; //do nothing, still can be correct and pass CRC } } /* return -1 if a minimum can't be found */ diff --git a/src/p25p1_tsbk.c b/src/p25p1_tsbk.c index 6d98923..0562419 100644 --- a/src/p25p1_tsbk.c +++ b/src/p25p1_tsbk.c @@ -7,6 +7,73 @@ *-----------------------------------------------------------------------------*/ #include "dsd.h" + +int block_convolution (int payload[196], uint8_t decoded[12]) +{ + int ec = -1; //initialize error value + + uint8_t deinterleaved_bits[196]; + uint8_t trellis_bytes[12]; + uint8_t m_data[14]; + uint8_t temp[210]; //temp bit position buffer for convolution + + //initialize our deinterleaved bits and bytes with zeroes + for (int i = 0; i < 196; i++) deinterleaved_bits[i] = 0; + for (int i = 0; i < 210; i++) temp[i] = 0; + for (int i = 0; i < 12; i++) trellis_bytes[i] = 0; + for (int i = 0; i < 14; i++) m_data[i] = 0; + + //convolution decoder + uint8_t s0; + uint8_t s1; + + //initialize our decoded byte buffer with zeroes + for (int i = 0; i < 12; i++) decoded[i] = 0; + + static const uint16_t deinterleave_tsbk[] = { + 0, 1, 2, 3, 52, 53, 54, 55, 100,101,102,103, 148,149,150,151, + 4, 5, 6, 7, 56, 57, 58, 59, 104,105,106,107, 152,153,154,155, + 8, 9, 10, 11, 60, 61, 62, 63, 108,109,110,111, 156,157,158,159, + 12, 13, 14, 15, 64, 65, 66, 67, 112,113,114,115, 160,161,162,163, + 16, 17, 18, 19, 68, 69, 70, 71, 116,117,118,119, 164,165,166,167, + 20, 21, 22, 23, 72, 73, 74, 75, 120,121,122,123, 168,169,170,171, + 24, 25, 26, 27, 76, 77, 78, 79, 124,125,126,127, 172,173,174,175, + 28, 29, 30, 31, 80, 81, 82, 83, 128,129,130,131, 176,177,178,179, + 32, 33, 34, 35, 84, 85, 86, 87, 132,133,134,135, 180,181,182,183, + 36, 37, 38, 39, 88, 89, 90, 91, 136,137,138,139, 184,185,186,187, + 40, 41, 42, 43, 92, 93, 94, 95, 140,141,142,143, 188,189,190,191, + 44, 45, 46, 47, 96, 97, 98, 99, 144,145,146,147, 192,193,194,195, + 48, 49, 50, 51 }; + + //get the deinterleaved bits + for (int i = 0; i < 196; i++) deinterleaved_bits[deinterleave_tsbk[i]] = payload[i]; + + //shift into proper position for the convolutional decoder + for (int i = 0; i < 196; i++) temp[i] = deinterleaved_bits[i] << 1; + + CNXDNConvolution_start(); + for (int i = 0U; i < 98U; i++) //102U + { + s0 = temp[(2*i)]; + s1 = temp[(2*i)+1]; + + CNXDNConvolution_decode(s0, s1); + } + + CNXDNConvolution_chainback(m_data, 96U); //98U + + //debug print + fprintf (stderr, "\n Convolution Chainback - "); + for (int i = 0; i < 14; i++) fprintf (stderr, "[%02X]", m_data[i]); + + //transfer m_data to decoded bytes -- when sorted out, can probably send decoded straight to chainback, and save the code + // for (int i = 0; i < 12; i++) decoded[i] = m_data[i]; + + ec = 0; //unknown if a method exists to returns errors from the convolutional decoder, just rely on CRC check for now + + return ec; +} + void processTSBK(dsd_opts * opts, dsd_state * state) { @@ -54,6 +121,9 @@ void processTSBK(dsd_opts * opts, dsd_state * state) } + //test with the nxdn convolutional decoder + // ec = block_convolution (tsbkbit, tsbk_byte); + //send tsbkbit to block_deinterleave and return tsbk_byte ec = bd_bridge(tsbkbit, tsbk_byte); @@ -84,7 +154,7 @@ void processTSBK(dsd_opts * opts, dsd_state * state) tsbk_byte[i] = byte; } - //convert tsbk_byte to PDU and send to vPDU handler + //convert tsbk_byte to vPDU and send to vPDU handler //...may or may not be entirely compatible, MFID = tsbk_byte[1]; PDU[0] = 0x07; //P25p1 TSBK Duid 0x07 @@ -106,8 +176,9 @@ void processTSBK(dsd_opts * opts, dsd_state * state) protectbit = (tsbk_byte[0] >> 6) & 0x1; //Don't run NET_STS out of this, or will set wrong NAC/CC //&& PDU[1] != 0x49 && PDU[1] != 0x45 - //0x49 is telephone grant, 0x46 Unit to Unit Channel Answer Request (seems bogus) - if (MFID < 0x2 && protectbit == 0 && err == 0 && ec == 0 && PDU[1] != 0x7B ) + //0x49 is telephone grant, 0x46 Unit to Unit Channel Answer Request (seems bogus) (mfid 90) + // if (MFID < 0x2 && protectbit == 0 && err == 0 && ec == 0 && PDU[1] != 0x7B ) + if ( (MFID < 0x2 || MFID == 0xA4 || MFID == 0x90) && protectbit == 0 && err == 0 && ec == 0 && PDU[1] != 0x7B ) { fprintf (stderr, "%s",KYEL); process_MAC_VPDU(opts, state, 0, PDU); @@ -115,7 +186,7 @@ void processTSBK(dsd_opts * opts, dsd_state * state) } //set our WACN and SYSID here now that we have valid ec and crc/checksum - if (protectbit == 0 && err == 0 && ec == 0 && (tsbk_byte[0] & 0x3F) == 0x3B) + else if (protectbit == 0 && err == 0 && ec == 0 && (tsbk_byte[0] & 0x3F) == 0x3B) { long int wacn = (tsbk_byte[3] << 12) | (tsbk_byte[4] << 4) | (tsbk_byte[5] >> 4);; int sysid = ((tsbk_byte[5] & 0xF) << 8) | tsbk_byte[6]; @@ -143,16 +214,43 @@ void processTSBK(dsd_opts * opts, dsd_state * state) if (opts->payload == 1) { fprintf (stderr, "%s",KCYN); - fprintf (stderr, "\n P25 PDU Payload "); + fprintf (stderr, "\n P25 PDU Payload #%d ", j); for (i = 0; i < 12; i++) { fprintf (stderr, "[%02X]", tsbk_byte[i]); } } + fprintf (stderr, "%s ", KNRM); } + else + { + if (opts->payload == 1) + { + fprintf (stderr, "%s",KCYN); + fprintf (stderr, "\n P25 PDU Payload #%d ", j+1); + for (i = 0; i < 12; i++) + { + fprintf (stderr, "[%02X]", tsbk_byte[i]); + } + fprintf (stderr, "\n MFID %02X Protected: %d Last Block: %d", MFID, protectbit, (tsbk_byte[0] >> 7) ); + + if (ec != 0) + { + fprintf (stderr, "%s",KRED); + fprintf (stderr, " (FEC ERR)"); + } + else if (err != 0) + { + fprintf (stderr, "%s",KRED); + fprintf (stderr, " (CRC ERR)"); + } + fprintf (stderr, "%s ", KNRM); + } + } + //reset for next rep ec = -2; err = -2; @@ -165,5 +263,7 @@ void processTSBK(dsd_opts * opts, dsd_state * state) j = 4; //set j to break the loop early } } + + fprintf (stderr, "%s ", KNRM); fprintf (stderr, "\n"); } diff --git a/src/p25p2_vpdu.c b/src/p25p2_vpdu.c index 5485de3..1a18acb 100644 --- a/src/p25p2_vpdu.c +++ b/src/p25p2_vpdu.c @@ -940,7 +940,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon } //Unit-to-Unit Answer Request (UU_ANS_REQ) - if (MAC[1+len_a] == 0x45) + if (MAC[1+len_a] == 0x45 && MAC[2+len_a] != 0x90) { int svc = MAC[2+len_a]; int answer = MAC[3+len_a]; @@ -952,17 +952,17 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon } - //Telephone Interconnect Voice Channel Grant (TELE_INT_CH_GRANT) - if (MAC[1+len_a] == 0x48) - { - fprintf (stderr, "\n Telephone Interconnect Voice Channel Grant "); - } + //Telephone Interconnect Voice Channel Grant (TELE_INT_CH_GRANT) //look at PDU for this, see if this is tunable + // if (MAC[1+len_a] == 0x48 && MAC[2+len_a] != 0x90) + // { + // fprintf (stderr, "\n Telephone Interconnect Voice Channel Grant "); + // } - //Telephone Interconnect Voice Channel Grant Update (TELE_INT_CH_GRANT_UPDT) - if (MAC[1+len_a] == 0x49) - { - fprintf (stderr, "\n Telephone Interconnect Voice Channel Grant Update "); - } + // //Telephone Interconnect Voice Channel Grant Update (TELE_INT_CH_GRANT_UPDT) + // if (MAC[1+len_a] == 0x49 && MAC[2+len_a] != 0x90) + // { + // fprintf (stderr, "\n Telephone Interconnect Voice Channel Grant Update "); + // } //Synchronization Broadcast (SYNC_BCST) if (MAC[1+len_a] == 0x70) @@ -986,12 +986,12 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon else offhour = ( (ltoff & 0b11111 ) / 2); int seconds = slots / 135; //very rough estimation, but may be close enough for grins - if (seconds > 60) seconds = 60; //sanity check for rounding error + if (seconds > 59) seconds = 59; //sanity check for rounding error fprintf (stderr, " Date: 20%02d.%02d.%02d Time: %02d:%02d:%02d UTC\n", year, month, day, hour, min, seconds); fprintf (stderr, " Local Time Offset: %.01f Hours;", offhour); //if ist bit is set, then time on system may be considered invalid (i.e., no external time sync) - if (ist % 1) + if (ist == 1) { fprintf (stderr, " Invalid System Time "); }