diff --git a/include/dsd.h b/include/dsd.h index 83486d0..6eb84f1 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -981,6 +981,8 @@ void soft_tonef (float samp[160], int n, int ID, int AD); //new p25lcw void p25_lcw (dsd_opts * opts, dsd_state * state, uint8_t LCW_bits[], uint8_t irrecoverable_errors); +//new p25 1/2 rate decoder +int p25_12(uint8_t * input, uint8_t treturn[12]); void processP25lcw (dsd_opts * opts, dsd_state * state, char *lcformat, char *mfid, char *lcinfo); void processHDU (dsd_opts * opts, dsd_state * state); diff --git a/src/dsd_dibit.c b/src/dsd_dibit.c index b64039a..ebb488c 100644 --- a/src/dsd_dibit.c +++ b/src/dsd_dibit.c @@ -287,8 +287,11 @@ int digitize (dsd_opts* opts, dsd_state* state, int symbol) valid = 0; + UNUSED(opts); + //testing again, either on Voice channels only (when tuned) or with trunk disabled - if (state->synctype == 1 && (opts->p25_is_tuned == 1 || opts->p25_trunk == 0) && opts->use_heuristics == 1) + // if (state->synctype == 1 && (opts->p25_is_tuned == 1 || opts->p25_trunk == 0) && opts->use_heuristics == 1) + if (state->synctype == 1 && opts->use_heuristics == 1) { // Use the P25p1 heuristics if available valid = estimate_symbol(state->rf_mod, &(state->inv_p25_heuristics), state->last_dibit, symbol, &dibit); @@ -354,7 +357,8 @@ int digitize (dsd_opts* opts, dsd_state* state, int symbol) valid = 0; //testing again, either on Voice channels only (when tuned) or with trunk disabled - if (state->synctype == 0 && (opts->p25_is_tuned == 1 || opts->p25_trunk == 0) && opts->use_heuristics == 1) + // if (state->synctype == 0 && (opts->p25_is_tuned == 1 || opts->p25_trunk == 0) && opts->use_heuristics == 1) + if (state->synctype == 0 && opts->use_heuristics == 1) { // Use the P25p1 heuristics if available valid = estimate_symbol(state->rf_mod, &(state->p25_heuristics), state->last_dibit, symbol, &dibit); diff --git a/src/dsd_main.c b/src/dsd_main.c index d4237d7..9b202d6 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -2219,6 +2219,7 @@ main (int argc, char **argv) // opts.setmod_bw = 12000; //safe default on both DMR and P25 opts.pulse_digi_rate_out = 8000; opts.pulse_digi_out_channels = 2; + opts.use_heuristics = 1; //enable for Phase 1 on -ft switch (testing) sprintf (opts.output_name, "TDMA"); fprintf (stderr,"Decoding P25 and DMR\n"); } diff --git a/src/p25_12.c b/src/p25_12.c new file mode 100644 index 0000000..e9df8c2 --- /dev/null +++ b/src/p25_12.c @@ -0,0 +1,165 @@ +/*------------------------------------------------------------------------------- + * p25_12.c + * P25p1 1/2 Rate Simple Trellis Decoder + * + * LWVMOBILE + * 2023-09 DSD-FME Florida Man Edition + *-----------------------------------------------------------------------------*/ + +#include "dsd.h" + +uint8_t p25_interleave[98] = { +0, 1, 8, 9, 16, 17, 24, 25, 32, 33, 40, 41, 48, 49, 56, 57, 64, 65, 72, 73, 80, 81, 88, 89, 96, 97, +2, 3, 10, 11, 18, 19, 26, 27, 34, 35, 42, 43, 50, 51, 58, 59, 66, 67, 74, 75, 82, 83, 90, 91, +4, 5, 12, 13, 20, 21, 28, 29, 36, 37, 44, 45, 52, 53, 60, 61, 68, 69, 76, 77, 84, 85, 92, 93, +6, 7, 14, 15, 22, 23, 30, 31, 38, 39, 46, 47, 54, 55, 62, 63, 70, 71, 78, 79, 86, 87, 94, 95}; + +//this is a convertion table for converting the dibit pairs into constellation points +uint8_t p25_constellation_map[16] = { +11, 12, 0, 7, 14, 9, 5, 2, 10, 13, 1, 6, 15, 8, 4, 3 +}; + +//digitized dibit to OTA symbol conversion for reference +//0 = +1; 1 = +3; +//2 = -1; 3 = -3; + +//finite state machine values +uint8_t p25_fsm[16] = { +0,15,12,3, +4,11,8,7, +13,2,1,14, +9,6,5,10 }; + + +int p25_12(uint8_t * input, uint8_t treturn[12]) +{ + int i, j; + int irr_err = 0; + + uint8_t deinterleaved_dibits[98]; + memset (deinterleaved_dibits, 0, sizeof(deinterleaved_dibits)); + + //deinterleave our input dibits + for (i = 0; i < 98; i++) + deinterleaved_dibits[p25_interleave[i]] = input[i]; + + //pack the input into nibbles (dibit pairs) + uint8_t nibs[49]; + memset (nibs, 0, sizeof(nibs)); + + for (i = 0; i < 49; i++) + nibs[i] = (deinterleaved_dibits[i*2+0] << 2) | (deinterleaved_dibits[i*2+1] << 0); + + //convert our dibit pairs into constellation point values + uint8_t point[49]; + memset (point, 0xFF, sizeof(point)); + + for (i = 0; i < 49; i++) + point[i] = p25_constellation_map[nibs[i]]; + + //debug view points -- point[0] should be zero + // fprintf (stderr, "\n P ="); + // for (i = 0; i < 49; i++) + // fprintf (stderr, " %02d", point[i]); + + //free-bee on err correction, point[0] should always be zero (flush bits) + // point[0] = 0; + + //convert constellation points into tdibit values using the FSM + uint8_t state = 0; + uint8_t temp_s = 0; + uint8_t tdibits[49]; //trellis dibits 1/2 rate + memset (tdibits, 0xF, sizeof(tdibits)); + uint8_t hd[4]; //array of the four fsm words hamming distance + memset (hd, 0, sizeof(hd)); + + for (i = 0; i < 49; i++) + { + + //just quickly peek for the correct state of the current point in the fsm + for (j = 0; j < 16; j++) + { + if (p25_fsm[j] == point[i]) + temp_s = j&3; //set position to correct state output value + } + + + for (j = 0; j < 4; j++) + { + if ( p25_fsm[(state*4)+j] == point[i] ) + { + //return our tdibit value and state for the next point + tdibits[i] = state = (uint8_t)j; + break; + } + } + + //if tdibit value is greater than 3, then we have a decoding error + if (tdibits[i] == 0xF) + { + irr_err++; //increment number of errors + + //debug position of error and state value + // fprintf (stderr, " %d:%d;", i, state); + + //use the predicted correct state/value at output instead -- last resort + tdibits[i] = state = temp_s; //this still performs better than the min hamming distance method + + } + + } + + //debug view tdibits/states + // fprintf (stderr, "\n T ="); + // for (i = 0; i < 49; i++) + // fprintf (stderr, " %02d", tdibits[i]); + + //pack tdibits into return payload bytes + for (i = 0; i < 12; i++) + treturn[i] = (tdibits[(i*4)+0] << 6) | (tdibits[(i*4)+1] << 4) | (tdibits[(i*4)+2] << 2) | tdibits[(i*4)+3]; + + //trellis point/state err tally + // if (irr_err != 0) + // fprintf (stderr, " ERR = %d", irr_err); + + return (irr_err); +} + +int count_bits(uint8_t b, int slen) +{ + int i = 0; int j = 0; + for (j = 0; j < slen; j++) + { + if ( (b & 1) == 1) i++; + b = b >> 1; + } + return i; +} + +uint8_t find_min(uint8_t list[4], int len) +{ + int min = list[0]; + uint8_t index = 0; + int unique = 1; + int i; + + for (i = 1; i < len; i++) + { + if (list[i] < min) + { + min = list[i]; + index = (uint8_t)i; + unique = 1; + } + else if (list[i] == min) + { + unique = 0; + + } + } + + if (unique == 0) + return 0xF; + + return index; +} diff --git a/src/p25p1_mdpu.c b/src/p25p1_mdpu.c index ea31b5a..0ea7d27 100644 --- a/src/p25p1_mdpu.c +++ b/src/p25p1_mdpu.c @@ -34,9 +34,9 @@ void processMPDU(dsd_opts * opts, dsd_state * state) { memset (state->active_channel, 0, sizeof(state->active_channel)); } - + int tsbkbit[196]; //tsbk bit array, 196 trellis encoded bits - int tsbk_dibit[98]; + uint8_t tsbk_dibit[98]; memset (tsbkbit, 0, sizeof(tsbkbit)); memset (tsbk_dibit, 0, sizeof(tsbk_dibit)); @@ -110,16 +110,11 @@ void processMPDU(dsd_opts * opts, dsd_state * state) } - //flushing the trellis state machine - if (j == 0) - { - bd_bridge(flushing_bits, tsbk_byte); - //reset tsbk_byte afterwards - memset (tsbk_byte, 0, sizeof(tsbk_byte)); - } + //send tsbkbit to block_deinterleave and return tsbk_byte + // ec[j] = bd_bridge(tsbkbit, tsbk_byte); //send tsbkbit to block_deinterleave and return tsbk_byte - ec[j] = bd_bridge(tsbkbit, tsbk_byte); + ec[j] = p25_12 (tsbk_dibit, tsbk_byte); //too many bit manipulations! k = 0; @@ -162,12 +157,12 @@ void processMPDU(dsd_opts * opts, dsd_state * state) MFID = mpdu_byte[2]; //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 + 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 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"); fprintf (stderr, "%s",KGRN); fprintf (stderr, " P25 MBF FMT: %02X SAP: %02X", fmt, sap); @@ -241,36 +236,36 @@ void processMPDU(dsd_opts * opts, dsd_state * state) } } //RFSS Status Broadcast - Extended 6.2.15.2 - else if (opcode == 0x3A) - { - int lra = mpdu_byte[3]; - int lsysid = ((mpdu_byte[4] & 0xF) << 8) | mpdu_byte[5]; - int rfssid = mpdu_byte[12]; - int siteid = mpdu_byte[13]; - int channelt = (mpdu_byte[14] << 8) | mpdu_byte[15]; + else if (opcode == 0x3A) + { + int lra = mpdu_byte[3]; + int lsysid = ((mpdu_byte[4] & 0xF) << 8) | mpdu_byte[5]; + int rfssid = mpdu_byte[12]; + int siteid = mpdu_byte[13]; + int channelt = (mpdu_byte[14] << 8) | mpdu_byte[15]; int channelr = (mpdu_byte[16] << 8) | mpdu_byte[17]; - int sysclass = mpdu_byte[18]; + int sysclass = mpdu_byte[18]; fprintf (stderr, "%s",KYEL); - fprintf (stderr, "\n RFSS Status Broadcast MBF - Extended \n"); - fprintf (stderr, " LRA [%02X] SYSID [%03X] RFSS ID [%02X] SITE ID [%02X]\n CHAN-T [%04X] CHAN-R [%02X] SSC [%02X] ", lra, lsysid, rfssid, siteid, channelt, channelr, sysclass); - process_channel_to_freq (opts, state, channelt); - process_channel_to_freq (opts, state, channelr); + fprintf (stderr, "\n RFSS Status Broadcast MBF - Extended \n"); + fprintf (stderr, " LRA [%02X] SYSID [%03X] RFSS ID [%02X] SITE ID [%02X]\n CHAN-T [%04X] CHAN-R [%02X] SSC [%02X] ", lra, lsysid, rfssid, siteid, channelt, channelr, sysclass); + process_channel_to_freq (opts, state, channelt); + process_channel_to_freq (opts, state, channelr); - state->p2_siteid = siteid; - state->p2_rfssid = rfssid; - } + state->p2_siteid = siteid; + state->p2_rfssid = rfssid; + } //Adjacent Status Broadcast (ADJ_STS_BCST) Extended 6.2.2.2 else if (opcode == 0x3C) { int lra = mpdu_byte[3]; int cfva = mpdu_byte[4] >> 4; - int lsysid = ((mpdu_byte[4] & 0xF) << 8) | mpdu_byte[5]; - int rfssid = mpdu_byte[8]; - int siteid = mpdu_byte[9]; - int channelt = (mpdu_byte[12] << 8) | mpdu_byte[13]; - int channelr = (mpdu_byte[14] << 8) | mpdu_byte[15]; - int sysclass = mpdu_byte[16]; + int lsysid = ((mpdu_byte[4] & 0xF) << 8) | mpdu_byte[5]; + int rfssid = mpdu_byte[8]; + int siteid = mpdu_byte[9]; + int channelt = (mpdu_byte[12] << 8) | mpdu_byte[13]; + int channelr = (mpdu_byte[14] << 8) | mpdu_byte[15]; + int sysclass = mpdu_byte[16]; long int wacn = (mpdu_byte[17] << 12) | (mpdu_byte[18] << 4) | (mpdu_byte[19] >> 4); fprintf (stderr, "%s",KYEL); fprintf (stderr, "\n Adjacent Status Broadcast - Extended\n"); @@ -289,12 +284,12 @@ void processMPDU(dsd_opts * opts, dsd_state * state) else if (opcode == 0x0) { int svc = mpdu_byte[8]; - int channelt = (mpdu_byte[14] << 8) | mpdu_byte[15]; - int channelr = (mpdu_byte[16] << 8) | mpdu_byte[17]; + int channelt = (mpdu_byte[14] << 8) | mpdu_byte[15]; + int channelr = (mpdu_byte[16] << 8) | mpdu_byte[17]; long int source = (mpdu_byte[3] << 16) |(mpdu_byte[4] << 8) | mpdu_byte[5]; - int group = (mpdu_byte[18] << 8) | mpdu_byte[19]; - long int freq1 = 0; - long int freq2 = 0; + int group = (mpdu_byte[18] << 8) | mpdu_byte[19]; + long int freq1 = 0; + long int freq2 = 0; UNUSED2(source, freq2); fprintf (stderr, "%s\n ",KYEL); if (svc & 0x80) fprintf (stderr, " Emergency"); @@ -308,13 +303,13 @@ void processMPDU(dsd_opts * opts, dsd_state * state) if (svc & 0x8) fprintf (stderr, " R"); //reserved bit is on fprintf (stderr, " Priority %d", svc & 0x7); //call priority } - fprintf (stderr, " Group Voice Channel Grant Update - Extended"); - fprintf (stderr, "\n SVC [%02X] CHAN-T [%04X] CHAN-R [%04X] Group [%d][%04X]", svc, channelt, channelr, group, group); - freq1 = process_channel_to_freq (opts, state, channelt); - freq2 = process_channel_to_freq (opts, state, channelr); + fprintf (stderr, " Group Voice Channel Grant Update - Extended"); + fprintf (stderr, "\n SVC [%02X] CHAN-T [%04X] CHAN-R [%04X] Group [%d][%04X]", svc, channelt, channelr, group, group); + freq1 = process_channel_to_freq (opts, state, channelt); + freq2 = process_channel_to_freq (opts, state, channelr); //add active channel to string for ncurses display - sprintf (state->active_channel[0], "Active Ch: %04X TG: %d ", channelt, group); + sprintf (state->active_channel[0], "Active Ch: %04X TG: %d ", channelt, group); state->last_active_time = time(NULL); for (int i = 0; i < state->group_tally; i++) @@ -328,59 +323,59 @@ void processMPDU(dsd_opts * opts, dsd_state * state) } - //Skip tuning group calls if group calls are disabled - if (opts->trunk_tune_group_calls == 0) goto SKIPCALL; + //Skip tuning group calls if group calls are disabled + if (opts->trunk_tune_group_calls == 0) goto SKIPCALL; //Skip tuning encrypted calls if enc calls are disabled if ( (svc & 0x40) && opts->trunk_tune_enc_calls == 0) goto SKIPCALL; - //tune if tuning available - if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0)) - { - //reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot - if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq1 != 0) //if we aren't already on a VC and have a valid frequency - { - //testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel - // if (opts->mod_qpsk == 1) - // { - // int spacing = state->p25_chan_spac[channelt >> 12]; - // if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32 - // { - // state->samplesPerSymbol = 8; - // state->symbolCenter = 3; - // } - // } + //tune if tuning available + if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0)) + { + //reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot + if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq1 != 0) //if we aren't already on a VC and have a valid frequency + { + //testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel + // if (opts->mod_qpsk == 1) + // { + // int spacing = state->p25_chan_spac[channelt >> 12]; + // if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32 + // { + // state->samplesPerSymbol = 8; + // state->symbolCenter = 3; + // } + // } //changed to allow symbol rate change on C4FM Phase 2 systems as well as QPSK - if (1 == 1) - { - if (state->p25_chan_tdma[channelt >> 12] == 1) - { - state->samplesPerSymbol = 8; - state->symbolCenter = 3; - } - } - //rigctl + if (1 == 1) + { + if (state->p25_chan_tdma[channelt >> 12] == 1) + { + state->samplesPerSymbol = 8; + state->symbolCenter = 3; + } + } + //rigctl if (opts->use_rigctl == 1) - { - if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw); - SetFreq(opts->rigctl_sockfd, freq1); - state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1; - opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop + { + if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw); + SetFreq(opts->rigctl_sockfd, freq1); + state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1; + opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop state->last_vc_sync_time = time(NULL); - } - //rtl - else if (opts->audio_in_type == 3) - { + } + //rtl + else if (opts->audio_in_type == 3) + { #ifdef USE_RTLSDR - rtl_dev_tune (opts, freq1); - state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1; - opts->p25_is_tuned = 1; + rtl_dev_tune (opts, freq1); + state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1; + opts->p25_is_tuned = 1; state->last_vc_sync_time = time(NULL); #endif - } - } - } + } + } + } } //Unit to Unit Voice Channel Grant - Extended @@ -388,13 +383,13 @@ void processMPDU(dsd_opts * opts, dsd_state * state) { //I'm not doing EVERY element of this, just enough for tuning! int svc = mpdu_byte[8]; - int channelt = (mpdu_byte[22] << 8) | mpdu_byte[23]; - int channelr = (mpdu_byte[24] << 8) | mpdu_byte[25]; //optional! + int channelt = (mpdu_byte[22] << 8) | mpdu_byte[23]; + int channelr = (mpdu_byte[24] << 8) | mpdu_byte[25]; //optional! //using source and target address, not source and target id (is this correct?) long int source = (mpdu_byte[3] << 16) |(mpdu_byte[4] << 8) | mpdu_byte[5]; - long int target = (mpdu_byte[19] << 16) |(mpdu_byte[20] << 8) | mpdu_byte[21]; - long int freq1 = 0; - long int freq2 = 0; + long int target = (mpdu_byte[19] << 16) |(mpdu_byte[20] << 8) | mpdu_byte[21]; + long int freq1 = 0; + long int freq2 = 0; UNUSED(freq2); fprintf (stderr, "%s\n ",KYEL); if (svc & 0x80) fprintf (stderr, " Emergency"); @@ -408,13 +403,13 @@ void processMPDU(dsd_opts * opts, dsd_state * state) if (svc & 0x8) fprintf (stderr, " R"); //reserved bit is on fprintf (stderr, " Priority %d", svc & 0x7); //call priority } - fprintf (stderr, " Unit to Unit Voice Channel Grant Update - Extended"); - fprintf (stderr, "\n SVC [%02X] CHAN-T [%04X] CHAN-R [%04X] Source [%ld][%04lX] Target [%ld][%04lX]", svc, channelt, channelr, source, source, target, target); - freq1 = process_channel_to_freq (opts, state, channelt); - freq2 = process_channel_to_freq (opts, state, channelr); //optional! + fprintf (stderr, " Unit to Unit Voice Channel Grant Update - Extended"); + fprintf (stderr, "\n SVC [%02X] CHAN-T [%04X] CHAN-R [%04X] Source [%ld][%04lX] Target [%ld][%04lX]", svc, channelt, channelr, source, source, target, target); + freq1 = process_channel_to_freq (opts, state, channelt); + freq2 = process_channel_to_freq (opts, state, channelr); //optional! //add active channel to string for ncurses display - sprintf (state->active_channel[0], "Active Ch: %04X TGT: %ld; ", channelt, target); + sprintf (state->active_channel[0], "Active Ch: %04X TGT: %ld; ", channelt, target); for (int i = 0; i < state->group_tally; i++) { @@ -427,60 +422,60 @@ void processMPDU(dsd_opts * opts, dsd_state * state) } - //Skip tuning private calls if group calls are disabled - if (opts->trunk_tune_private_calls == 0) goto SKIPCALL; + //Skip tuning private calls if group calls are disabled + if (opts->trunk_tune_private_calls == 0) goto SKIPCALL; //Skip tuning encrypted calls if enc calls are disabled if ( (svc & 0x40) && opts->trunk_tune_enc_calls == 0) goto SKIPCALL; - //tune if tuning available - if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0)) - { - //reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot - if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq1 != 0) //if we aren't already on a VC and have a valid frequency - { + //tune if tuning available + if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0)) + { + //reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot + if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq1 != 0) //if we aren't already on a VC and have a valid frequency + { - //testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel - // if (opts->mod_qpsk == 1) - // { - // int spacing = state->p25_chan_spac[channelt >> 12]; - // if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32 - // { - // state->samplesPerSymbol = 8; - // state->symbolCenter = 3; - // } - // } + //testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel + // if (opts->mod_qpsk == 1) + // { + // int spacing = state->p25_chan_spac[channelt >> 12]; + // if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32 + // { + // state->samplesPerSymbol = 8; + // state->symbolCenter = 3; + // } + // } //changed to allow symbol rate change on C4FM Phase 2 systems as well as QPSK - if (1 == 1) - { - if (state->p25_chan_tdma[channelt >> 12] == 1) - { - state->samplesPerSymbol = 8; - state->symbolCenter = 3; - } - } - //rigctl + if (1 == 1) + { + if (state->p25_chan_tdma[channelt >> 12] == 1) + { + state->samplesPerSymbol = 8; + state->symbolCenter = 3; + } + } + //rigctl if (opts->use_rigctl == 1) - { - if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw); - SetFreq(opts->rigctl_sockfd, freq1); - state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1; - opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop + { + if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw); + SetFreq(opts->rigctl_sockfd, freq1); + state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1; + opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop state->last_vc_sync_time = time(NULL); - } - //rtl - else if (opts->audio_in_type == 3) - { + } + //rtl + else if (opts->audio_in_type == 3) + { #ifdef USE_RTLSDR - rtl_dev_tune (opts, freq1); - state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1; - opts->p25_is_tuned = 1; + rtl_dev_tune (opts, freq1); + state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1; + opts->p25_is_tuned = 1; state->last_vc_sync_time = time(NULL); #endif - } - } - } + } + } + } } else diff --git a/src/p25p1_tsbk.c b/src/p25p1_tsbk.c index c7e1670..54756fd 100644 --- a/src/p25p1_tsbk.c +++ b/src/p25p1_tsbk.c @@ -20,9 +20,9 @@ void processTSBK(dsd_opts * opts, dsd_state * state) { memset (state->active_channel, 0, sizeof(state->active_channel)); } - + int tsbkbit[196]; //tsbk bit array, 196 trellis encoded bits - int tsbk_dibit[98]; + uint8_t tsbk_dibit[98]; memset (tsbkbit, 0, sizeof(tsbkbit)); memset (tsbk_dibit, 0, sizeof(tsbk_dibit)); @@ -38,15 +38,13 @@ void processTSBK(dsd_opts * opts, dsd_state * state) int tsbk_decoded_bits[190]; //decoded bits from tsbk_bytes for sending to crc16_lb_bridge memset (tsbk_decoded_bits, 0, sizeof(tsbk_decoded_bits)); - int flushing_bits[196]; //for flushing the trellis state machine - memset (flushing_bits, 0, sizeof(flushing_bits)); - int i, j, k, x; int ec = -2; //error value returned from (block_deinterleave) int err = -2; //error value returned from crc16_lb_bridge int skipdibit = 14; //initial status dibit will occur at 14, then add 36 each time it occurs int protectbit = 0; int MFID = 0xFF; //Manufacturer ID - Might be beneficial to NOT send anything but standard 0x00 or 0x01 messages + int lb = 0; //last block //TODO: Don't Print TSBKs/vPDUs unless verbosity levels set higher @@ -74,16 +72,14 @@ void processTSBK(dsd_opts * opts, dsd_state * state) } - //flushing the trellis state machine - if (j == 0) - { - bd_bridge(flushing_bits, tsbk_byte); - //reset tsbk_byte afterwards - memset (tsbk_byte, 0, sizeof(tsbk_byte)); - } + //send to p25_12 + ec = p25_12 (tsbk_dibit, tsbk_byte); + + //debug err tally from 1/2 decoder + // if (ec) fprintf (stderr, " #%d ERR = %d;", j+1, ec); //send tsbkbit to block_deinterleave and return tsbk_byte - ec = bd_bridge(tsbkbit, tsbk_byte); + // ec = bd_bridge(tsbkbit, tsbk_byte); //too many bit manipulations! k = 0; @@ -132,13 +128,14 @@ void processTSBK(dsd_opts * opts, dsd_state * state) //check the protect bit, don't run if protected protectbit = (tsbk_byte[0] >> 6) & 0x1; + lb = (tsbk_byte[0] >> 7) & 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) (mfid 90) // if (MFID < 0x2 && protectbit == 0 && err == 0 && ec == 0 && PDU[1] != 0x7B ) //running with A4 and 90 causing some false positives when sending to vPDU, issuing bad call grants to nowhere! // if ( (MFID < 0x2 || MFID == 0xA4 || MFID == 0x90) && protectbit == 0 && err == 0 && ec == 0 && PDU[1] != 0x7B ) - if (MFID < 0x2 && protectbit == 0 && err == 0 && ec == 0 && PDU[1] != 0x7B ) + if (MFID < 0x2 && protectbit == 0 && err == 0 && PDU[1] != 0x7B ) { fprintf (stderr, "%s",KYEL); process_MAC_VPDU(opts, state, 0, PDU); @@ -195,14 +192,14 @@ void processTSBK(dsd_opts * opts, dsd_state * state) { fprintf (stderr, "[%02X]", tsbk_byte[i]); } - fprintf (stderr, "\n MFID %02X Protected: %d Last Block: %d", MFID, protectbit, (tsbk_byte[0] >> 7) ); + fprintf (stderr, "\n MFID %02X Protected: %d Last Block: %d", MFID, protectbit, lb); if (ec != 0) { fprintf (stderr, "%s",KRED); - fprintf (stderr, " (FEC ERR)"); + fprintf (stderr, " ERR = %d", ec); } - else if (err != 0) + if (err != 0) { fprintf (stderr, "%s",KRED); fprintf (stderr, " (CRC ERR)"); @@ -218,10 +215,7 @@ void processTSBK(dsd_opts * opts, dsd_state * state) MFID = 0xFF; //check for last block bit - if ( (tsbk_byte[0] >> 7) == 1 ) - { - j = 4; //set j to break the loop early - } + if (lb) break; } fprintf (stderr, "%s ", KNRM);