diff --git a/include/dsd.h b/include/dsd.h index eeec1c7..3b2e04a 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -535,9 +535,10 @@ typedef struct uint8_t data_p_head[2]; //flag for dmr proprietary header to follow //new stuff below here - uint8_t data_conf_data[2]; //flag for confirmed data blocks per slot - uint8_t dmr_pdu_sf[2][288]; //unified pdu 'superframe' //[slot][byte] - uint8_t cap_plus_csbk_bits[12*8*4]; //CSBK Cap+ FL initial and appended block bit storage + uint8_t data_conf_data[2]; //flag for confirmed data blocks per slot + uint8_t dmr_pdu_sf[2][288]; //unified pdu 'superframe' //[slot][byte] + uint8_t cap_plus_csbk_bits[12*8*8]; //CSBK Cap+ FL initial and appended block bit storage + uint8_t cap_plus_block_num; //received block number storage uint8_t data_block_crc_valid[2][25]; //flag each individual block as good crc on confirmed data char dmr_embedded_signalling[2][7][48]; //embedded signalling 2 slots by 6 vc by 48 bits (replacing TS1SuperFrame.TimeSlotRawVoiceFrame.Sync structure) diff --git a/src/dmr_csbk.c b/src/dmr_csbk.c index e5c33f2..12effcd 100644 --- a/src/dmr_csbk.c +++ b/src/dmr_csbk.c @@ -638,6 +638,15 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 uint8_t rest_channel = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[20], 4); uint8_t group_tally = 0; //set this to the number of active group channels tallied + uint8_t block_num = state->cap_plus_block_num; + + //sanity check + if (block_num > 6) + { + state->cap_plus_block_num = 6; + block_num = 6; + } + uint8_t ch[8]; //one bit per channel uint8_t pch[8]; //private or data call channel bits uint8_t tg = 0; @@ -655,14 +664,17 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 } //treating FL as a form of LCSS - if (fl != 1) //initial or single block (fl2 or fl3) + if (fl == 2 || fl == 3) //initial or single block (fl2 or fl3) { memset (state->cap_plus_csbk_bits, 0, sizeof(state->cap_plus_csbk_bits)); for (i = 0; i < 10*8; i++) state->cap_plus_csbk_bits[i] = cs_pdu_bits[i]; + state->cap_plus_block_num = 0; } - else //appended block (fl1) + else //appended block (fl0) or final block (fl1) { - for (i = 0; i < 7*8; i++) state->cap_plus_csbk_bits[i+80] = cs_pdu_bits[i+24]; + for (i = 0; i < 7*8; i++) state->cap_plus_csbk_bits[i+80+(7*8*block_num)] = cs_pdu_bits[i+24]; + block_num++; + state->cap_plus_block_num++; } if (rest_channel != state->dmr_rest_channel) @@ -679,9 +691,10 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 } fprintf (stderr, " Capacity Plus Channel Status - FL: %d TS: %d RS: %d - Rest Channel %d", fl, ts, res, rest_channel); - if (fl == 1) fprintf (stderr, " - Appended Block"); + if (fl == 0) fprintf (stderr, " - Appended Block"); //have not yet observed a system use this fl value + if (fl == 1) fprintf (stderr, " - Final Block"); if (fl == 2) fprintf (stderr, " - Initial Block"); - if (fl == 3) fprintf (stderr, " - Single Block"); + if (fl == 3) fprintf (stderr, " - Single Block"); //still considering a single, and not a final //look at each group channel bit -- run this PRIOR to checking private or data calls //or else we will overwrite the ch bits we set below for private calls with zeroes @@ -692,16 +705,16 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 if (ch[i] == 1) group_tally++; //figure out where to start looking in the byte stream for the 0x80 flag } - //check for private/data calls + //check for private/data calls -- user will neeed to enable 'data' call tuning in order to tune them uint8_t pdflag = (uint8_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[40+(group_tally*8)], 8); //seems to be 0x80 (last block flag?) on samples I have uint16_t private_target = 0; //first, check to see if we have a completed PDU - if (fl != 2) + if (fl == 1 || fl == 3) { //then check to see if this byte has a value, should be 0x80 //this bytes location seems to shift depending on level of activity - if (pdflag != 0) //now looking to see if any appended data was added + if (pdflag == 0x80) //now looking to see if any appended data was added { k = 0; //= 0 fprintf (stderr, "\n"); @@ -714,7 +727,7 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 fprintf (stderr, " Ch%d:", i+1); private_target = (uint16_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[56+(k*16)+(group_tally*8)], 16); fprintf (stderr, " TGT %d;", private_target); - if (opts->trunk_tune_private_calls == 1) t_tg[i] = private_target; //set here for tuning allow/block + if (opts->trunk_tune_data_calls == 1) t_tg[i] = private_target; //set here for tuning allow/block k++; } } @@ -744,7 +757,7 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 { fprintf (stderr, "P||D "); //flag as available for tuning if enabled - if (opts->trunk_tune_private_calls == 1) ch[i] = 1; + if (opts->trunk_tune_data_calls == 1) ch[i] = 1; } else if (i+1 == rest_channel) fprintf (stderr, "Rest "); else fprintf (stderr, "Idle "); @@ -819,16 +832,18 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 if (fl == 1 && opts->payload == 1) { fprintf (stderr, "%s\n", KYEL); - fprintf (stderr, " CAP+ Multi Block PDU "); + fprintf (stderr, " CAP+ Multi Block PDU \n "); uint8_t fl_bytes = 0; - for (i = 0; i < 17; i++) + for (i = 0; i < (10+(block_num*7)); i++) { fl_bytes = (uint8_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[i*8], 8); fprintf (stderr, "[%02X]", fl_bytes); + if (i == 17 || i == 35) fprintf (stderr, "\n "); } fprintf (stderr, "%s", KNRM); } memset (state->cap_plus_csbk_bits, 0, sizeof(state->cap_plus_csbk_bits)); + state->cap_plus_block_num = 0; } //fl != 2 } //opcode == 0x3E diff --git a/src/dmr_dburst.c b/src/dmr_dburst.c index 3d2ec26..8cb4aa0 100644 --- a/src/dmr_dburst.c +++ b/src/dmr_dburst.c @@ -185,6 +185,9 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196 } + //flag off prop head when not looking at data blocks + if (databurst != 0x6 && databurst != 0x7 && databurst != 0x8 && databurst != 0xA && databurst != 0xB) state->data_p_head[slot] = 0; + if (databurst != 0xEB) { if (state->dmr_ms_mode == 0) fprintf(stderr, "| Color Code=%02d ", state->dmr_color_code); diff --git a/src/dmr_flco.c b/src/dmr_flco.c index 912fa7a..3be4918 100644 --- a/src/dmr_flco.c +++ b/src/dmr_flco.c @@ -67,10 +67,10 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C if (IrrecoverableErrors == 0) { - + if (slot == 0) state->dmr_flco = flco; else state->dmr_flcoR = flco; - + //Embedded Talker Alias Header Only (format and len storage) if (fid == 0 && type == 3 && flco == 0x04) { @@ -226,7 +226,9 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C //0x04 and 0x05 on a TLC seem to indicate a Cap + Private Call Terminator (perhaps one for each MS) //0x07 on a VLC seems to indicate a Cap+ Private Call Header - //0x23 on the Embedded Voice Burst Sync seems to indicate a Cap+ Private Call in progress + //0x23 on the Embedded Voice Burst Sync seems to indicate a Cap+ or Cap+ TXI Private Call in progress + //0x20 on the Embedded Voice Burst Sync seems to indicate a Moto (non-specific) Group Call in progress + //its possible that both EMB FID 0x10 FLCO 0x20 and 0x23 are just Moto but non-specific (observed 0x20 on Tier 2) if (flco == 0x4 || flco == 0x5 || flco == 0x7 || flco == 0x23) //Cap+ Things { sprintf (state->call_string[slot], " Cap+"); diff --git a/src/dmr_le.c b/src/dmr_le.c index 210d9c6..71b1872 100644 --- a/src/dmr_le.c +++ b/src/dmr_le.c @@ -211,7 +211,7 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power) //I've observed it in the Private Cap+ TXI calls as well //there also seems to be a correlation between the SVC bits for TXI (reserved=3) and these extra cap+ values uint8_t sbrc_opcode = sbrc_hex; - uint8_t alg = sbrc_hex & 3; + uint8_t alg = sbrc_hex & 0x7; uint16_t key = (sbrc_hex >> 3) & 0xFF; if (opts->payload == 1) diff --git a/src/dsd_main.c b/src/dsd_main.c index 7f7e7e5..821756a 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -52,7 +52,7 @@ char * FM_banner[9] = { " ██║ ██║ ╚═══██╗██║ ██║   ██╔══╝ ██║╚██╔╝██║██╔══╝ ", " ██████╔╝██████╔╝██████╔╝   ██║ ██║ ╚═╝ ██║███████╗", " ╚═════╝ ╚═════╝ ╚═════╝    ╚═╝ ╚═╝ ╚═╝╚══════╝", - " 'Lite' Edition v2.0.0-28-ga02f992 Windows 32-bit RC3 " + " 'Lite' Edition v2.0.0-30-ga4ecfdc Windows 32-bit RC3a " }; int @@ -303,7 +303,10 @@ noCarrier (dsd_opts * opts, dsd_state * state) //initialize unified dmr pdu 'superframe' memset (state->dmr_pdu_sf, 0, sizeof (state->dmr_pdu_sf)); - memset (state->cap_plus_csbk_bits, 0, sizeof(state->cap_plus_csbk_bits)); + + //initialize cap+ bits and block num storage + memset (state->cap_plus_csbk_bits, 0, sizeof(state->cap_plus_csbk_bits)); + state->cap_plus_block_num = 0; //init confirmed data individual block crc as invalid memset (state->data_block_crc_valid, 0, sizeof(state->data_block_crc_valid)); @@ -833,7 +836,10 @@ initState (dsd_state * state) //initialize unified dmr pdu 'superframe' memset (state->dmr_pdu_sf, 0, sizeof (state->dmr_pdu_sf)); - memset (state->cap_plus_csbk_bits, 0, sizeof(state->cap_plus_csbk_bits)); + + //initialize cap+ bits and block num storage + memset (state->cap_plus_csbk_bits, 0, sizeof(state->cap_plus_csbk_bits)); + state->cap_plus_block_num = 0; //init confirmed data individual block crc as invalid memset (state->data_block_crc_valid, 0, sizeof(state->data_block_crc_valid)); @@ -1977,14 +1983,14 @@ main (int argc, char **argv) fprintf(stderr, "Decoding only dPMR frames.\n"); } break; - //don't mess with the modulations, doesn't really do anything meaningful anyways + //don't mess with the modulations unless you really need to case 'm': if (optarg[0] == 'a') { - // opts.mod_c4fm = 1; - // opts.mod_qpsk = 1; - // opts.mod_gfsk = 1; - // state.rf_mod = 0; + opts.mod_c4fm = 1; + opts.mod_qpsk = 1; + opts.mod_gfsk = 1; + state.rf_mod = 0; fprintf (stderr,"Don't use the -ma switch.\n"); } else if (optarg[0] == 'c') @@ -2023,6 +2029,29 @@ main (int argc, char **argv) opts.setmod_bw = 12000; fprintf (stderr,"Enabling 6000 sps P25p2 CQPSK.\n"); } + //test + else if (optarg[0] == '3') + { + opts.mod_c4fm = 1; + opts.mod_qpsk = 0; + opts.mod_gfsk = 0; + state.rf_mod = 0; + state.samplesPerSymbol = 8; + state.symbolCenter = 3; + opts.setmod_bw = 12000; + fprintf (stderr,"Enabling 6000 sps P25p2 C4FM.\n"); + } + else if (optarg[0] == '4') + { + opts.mod_c4fm = 1; + opts.mod_qpsk = 1; + opts.mod_gfsk = 1; + state.rf_mod = 0; + state.samplesPerSymbol = 8; + state.symbolCenter = 3; + opts.setmod_bw = 12000; + fprintf (stderr,"Enabling 6000 sps P25p2 all optimizations.\n"); + } break; case 'u': sscanf (optarg, "%i", &opts.uvquality); diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c index b2fcead..fad6069 100644 --- a/src/dsd_ncurses.c +++ b/src/dsd_ncurses.c @@ -2061,7 +2061,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) if (opts->ncurses_compact == 1) { printw ("------------------------------------------------------------------------------\n"); - printw ("| Digital Speech Decoder: Florida Man Edition - Win32 %s \n", "v2.0.0-28-ga02f992 RC3"); + printw ("| Digital Speech Decoder: Florida Man Edition - Win32 %s \n", "v2.0.0-30-ga4ecfdc RC3a"); } if (opts->ncurses_compact == 0) { @@ -2072,8 +2072,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) if (i == 1) printw (" ESC to Menu"); if (i == 2) printw (" 'q' to Quit "); if (i == 4) printw (" MBElib %s", versionstr); - if (i == 5) printw (" %s ", "Win32 RC3"); //printw (" %s \n", GIT_TAG); - if (i == 6) printw (" %s \n", "v2.0.0-28-ga02f992"); //printw (" %s \n", GIT_TAG); + if (i == 5) printw (" %s ", "Win32 RC3a"); //printw (" %s \n", GIT_TAG); + if (i == 6) printw (" %s \n", "v2.0.0-30-ga4ecfdc"); //printw (" %s \n", GIT_TAG); else printw ("\n"); } attroff(COLOR_PAIR(6)); //6