3 Commits
451 ... 454

Author SHA1 Message Date
lwvmobile
0635ab7121 Update README.md 2022-12-27 05:31:04 -05:00
lwvmobile
a0d9e349c2 TSBK NET_STS_BCST Last Block Fix; Protect Block; 2022-11-02 01:40:45 -04:00
lwvmobile
7ca65cf687 Call History Fix & Timestamp; Cap+ VLC Fix; 2022-11-01 03:54:10 -04:00
5 changed files with 119 additions and 137 deletions

View File

@@ -1,3 +1,5 @@
# Notice - This branch is now considered 'legacy' and the master branch will be considered the 'main' branch going forward.
# Digital Speech Decoder - Florida Man Edition
This version of DSD is a flavor blend of [szechyjs](https://github.com/szechyjs/dsd "szechyjs") RTL branch and some of my own additions, along with portions of DMR and NXDN code from the [LouisErigHerve](https://github.com/LouisErigHerve/dsd "LouisErigHerve") branch. This code also borrows snippets, inspiration, and ideas from other open source works including [Boatbod OP25](https://github.com/boatbod/op25 "Boatbod OP25"), [DSDcc](https://github.com/f4exb/dsdcc "DSDcc"), [SDTRunk](https://github.com/DSheirer/sdrtrunk "SDRTrunk"), [MMDVMHost](https://github.com/g4klx/MMDVMHost "MMDVMHost"), [LFSR](https://github.com/mattames/LFSR "LFSR"), and [EZPWD-Reed-Solomon](https://github.com/pjkundert/ezpwd-reed-solomon "EZPWD"). This project wouldn't be possible without a few good people providing me plenty of sample audio files to run over and over again. Special thanks to jurek1111, KrisMar, noamlivne, racingfan360, iScottyBotty, LimaZulu and hrh17 for the many hours of wav samples submitted by them.
@@ -242,11 +244,6 @@ sudo chmod 777 /usr/share/tone8.wav
sudo chmod 777 /usr/share/tone24.wav
```
# Join the Conversation
Want to help drive the direction of this project and read more about the latest updates and releases to DSD-FME? Then join the conversation on the 'unofficial official' [DSD-FME](https://forums.radioreference.com/threads/dsd-fme.438137/ "DSD-FME") Forum Thread on the Radio Reference Forums.
## License
Copyright (C) 2010 DSD Author
GPG Key ID: 0x3F1D7FD0 (74EF 430D F7F2 0A48 FCE6 F630 FAA2 635D 3F1D 7FD0)

View File

@@ -1757,32 +1757,6 @@ void ProcessCSBK(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t
sprintf(state->dmr_branding, " Hytera XPT ");
}
//Testing CSBK Voice Call on Tait //CSBK Protect RID ILLEGALLY_PARKED
// if ((IrrecoverableErrors == 0) && CRCCorrect)
// {
// if (DmrDataByte[0] == 0xAF)
// {
// if (state->currentslot == 0)
// {
// state->lastsrc = (DmrDataByte[4] << 16) | (DmrDataByte[5] << 8) | (DmrDataByte[6] << 0);
// state->lasttg = (DmrDataByte[7] << 16) | (DmrDataByte[8] << 8) | (DmrDataByte[9] << 0);
// fprintf (stderr, "%s", KGRN);
// fprintf (stderr, "\n SLOT %d ", state->currentslot+1);
// fprintf(stderr, "TGT=%u SRC=%u ", state->lasttg, state->lastsrc);
// fprintf(stderr, " CSBK Voice LC??");
// }
// if (state->currentslot == 1)
// {
// state->lastsrcR = (DmrDataByte[4] << 16) | (DmrDataByte[5] << 8) | (DmrDataByte[6] << 0);
// state->lasttgR = (DmrDataByte[7] << 16) | (DmrDataByte[8] << 8) | (DmrDataByte[9] << 0);
// fprintf (stderr, "%s", KGRN);
// fprintf (stderr, "\n SLOT %d ", state->currentslot+1);
// fprintf(stderr, "TGT=%u SRC=%u ", state->lasttgR, state->lastsrcR);
// fprintf(stderr, " CSBK Voice LC??");
// }
// }
// }
//Full
if (opts->payload == 1)
{
@@ -2049,9 +2023,12 @@ void ProcessDmrVoiceLcHeader(dsd_opts * opts, dsd_state * state, uint8_t info[19
/* Store the Source address */
TSVoiceSupFrame->FullLC.SourceAddress = (unsigned int)ConvertBitIntoBytes(&DmrDataBit[48], 24);
//truncate if Byte 0 isn't 0, 0x04 (or other) may signify a Cap+ System
if (DmrDataByte != 0x0)
int rest_channel = -1; //set rest_channel to -1; if set to other value, then we know we have a Cap+?
//Below "Should" be a MotoTRBO Cap+ system
if (TSVoiceSupFrame->FullLC.FullLinkControlOpcode & 0x4 && TSVoiceSupFrame->FullLC.FeatureSetID == 0x10)
{
rest_channel = (TSVoiceSupFrame->FullLC.SourceAddress >> 16); //8 bits for Rest Channel
TSVoiceSupFrame->FullLC.SourceAddress = TSVoiceSupFrame->FullLC.SourceAddress & 0xFFFF;
}
@@ -2144,38 +2121,13 @@ void ProcessDmrVoiceLcHeader(dsd_opts * opts, dsd_state * state, uint8_t info[19
else if(IrrecoverableErrors == 0) {}//fprintf(stderr, "RAS (FEC OK/CRC ERR)");
else {}//fprintf(stderr, "(FEC FAIL/CRC ERR)");
#ifdef PRINT_VOICE_LC_HEADER_BYTES
fprintf(stderr, "\n");
fprintf(stderr, "VOICE LC HEADER : ");
for(i = 0; i < 12; i++)
//check Cap+ rest channel info if available
if (rest_channel != -1)
{
fprintf(stderr, "0x%02X", DmrDataByte[i]);
if(i != 11) fprintf(stderr, " - ");
//fprintf (stderr, "Cap+ R-Ch=%d", rest_channel);
}
fprintf(stderr, "\n");
fprintf(stderr, "BPTC(196,96) Reserved bit R(0)-R(2) = 0x%02X\n", BPTCReservedBits);
fprintf(stderr, "CRC extracted = 0x%04X - CRC computed = 0x%04X - ", CRCExtracted, CRCComputed);
if((IrrecoverableErrors == 0) && CRCCorrect)
{
fprintf(stderr, "CRCs are equal + FEC OK !\n");
}
else if(IrrecoverableErrors == 0)
{
else fprintf(stderr, "FEC correctly corrected but CRCs are incorrect\n");
}
else
{
fprintf(stderr, "ERROR !!! CRCs are different and FEC Failed !\n");
}
fprintf(stderr, "Hamming Irrecoverable Errors = %u\n", IrrecoverableErrors);
#endif /* PRINT_VOICE_LC_HEADER_BYTES */
//Full
//Full
if (opts->payload == 1)
{
fprintf (stderr, "%s", KCYN);

View File

@@ -434,7 +434,7 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
}
}
//if using anything but DMR Stereo, borrowing state->dmr_encL to signal enc or clear for other types
//X2-TDMA? Not sure what still makes it this far to run under Framef
if (opts->dmr_stereo == 0)
{
mbe_processAmbe3600x2450Framef (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str, ambe_fr, ambe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);

View File

@@ -65,41 +65,21 @@ int i = 0;
char versionstr[25];
unsigned long long int call_matrix[33][6];
/*
___)__|_
.-*' '*-,
/ /| |\ \
; /_| |_\ ;
; |\ /| ;
; | ''--...--'' | ;
\ ''---.....--'' /
''*-.,_______,.-*' BOO!
*/
// char * FM_bannerN[9] = {
// " ESC or Arrow Keys For Menu ",
// " ██████╗ ██████╗██████╗    ███████╗███╗ ███╗███████╗ ",
// " ██╔══██╗██╔════╝██╔══██╗   ██╔════╝████╗ ████║██╔════╝ ",
// " ██║ ██║╚█████╗ ██║ ██║   █████╗ ██╔████╔██║█████╗ ",
// " ██║ ██║ ╚═══██╗██║ ██║   ██╔══╝ ██║╚██╔╝██║██╔══╝ ",
// " ██████╔╝██████╔╝██████╔╝   ██║ ██║ ╚═╝ ██║███████╗ ",
// " ╚═════╝ ╚═════╝ ╚═════╝    ╚═╝ ╚═╝ ╚═╝╚══════╝ ",
// " ",
// " "
// };
char * FM_bannerN[9] = {
" ESC or Arrow Keys For Menu Happy Halloween! ___)__|_ ",
" ██████╗ ██████╗██████╗    ███████╗███╗ ███╗███████╗ .-*' '*-, ",
" ██╔══██╗██╔════╝██╔══██╗   ██╔════╝████╗ ████║██╔════╝; /_| |_\\ ;",
" ██║ ██║╚█████╗ ██║ ██║   █████╗ ██╔████╔██║█████╗ ; |\\ /| ;",
" ██║ ██║ ╚═══██╗██║ ██║   ██╔══╝ ██║╚██╔╝██║██╔══╝ ; | ''--...--'' | ; ",
" ██████╔╝██████╔╝██████╔╝   ██║ ██║ ╚═╝ ██║███████╗ \\ ''---.....--'' / ",
" ╚═════╝ ╚═════╝ ╚═════╝    ╚═╝ ╚═╝ ╚═╝╚══════╝ ''*-.,_______,.-*' ",
" Happy Halloween ",
" "
" ESC or Arrow Keys For Menu ",
" ██████╗ ██████╗██████╗    ███████╗███╗ ███╗███████╗ ",
" ██╔══██╗██╔════╝██╔══██╗   ██╔════╝████╗ ████║██╔════╝ ",
" ██║ ██║╚█████╗ ██║ ██║   █████╗ ██╔████╔██║█████╗ ",
" ██║ ██║ ╚═══██╗██║ ██║   ██╔══╝ ██║╚██╔╝██║██╔══╝ ",
" ██████╔╝██████╔╝██████╔╝   ██║ ██║ ╚═╝ ██║███████╗ ",
" ╚═════╝ ╚═════╝ ╚═════╝    ╚═╝ ╚═╝ ╚═╝╚══════╝ ",
" ",
" "
};
char * SyncTypes[44] = {
"P25P1",
"P25P1",
@@ -111,10 +91,10 @@ char * SyncTypes[44] = {
"DSTAR",
"NXDN VOICE",
"NXDN VOICE",
"DMR DATA", //10
"DMR DATA",
"DMR VOICE",
"DMR VOICE",
"DMR ", //10
"DMR ",
"DMR ",
"DMR ",
"PROVOICE",
"PROVOICE",
"NXDN VOICE", //DATA
@@ -146,7 +126,7 @@ char * SyncTypes[44] = {
char * DMRBusrtTypes[32] = {
"PI Header ",
"VOICE LC HDR ",
"VOICE LC ",
"TLC ",
"CSBK ",
"MBC Header ",
@@ -155,7 +135,7 @@ char * DMRBusrtTypes[32] = {
"RATE 1/2 DATA ",
"RATE 3/4 DATA ",
"Slot Idle ",
"Rate 1 DATA ",
"RATE 1 DATA ",
"ERR ", //These values for ERR may be Reserved for use in future?
"DUID ERR ",
"R-S ERR ",
@@ -180,6 +160,11 @@ char * DMRBusrtTypes[32] = {
};
//there is still a bug in beeper, but the bug isn't related to call history,
//if it were, per call wav would also be affected.
//seems to do with playing a wav file,
//debug shows it should trigger even when you don't hear it
//no beep or double beep still happens randomly but debug shows only one played!?
void beeper (dsd_opts * opts, dsd_state * state, int type)
{
FILE *beep;
@@ -199,7 +184,8 @@ void beeper (dsd_opts * opts, dsd_state * state, int type)
if (stat(wav_name, &stat_buf) == 0)
{
beep = fopen (wav_name, "ro");
uint8_t buf[1024] = {0};
uint8_t buf[1024];
memset (buf, 0, sizeof(buf));
short blip = 0;
int loop = 1;
while (loop == 1)
@@ -215,14 +201,17 @@ void beeper (dsd_opts * opts, dsd_state * state, int type)
if (type == 0 && opts->dmr_stereo == 1 && opts->audio_out == 1)
{
pa_simple_write(opts->pulse_digi_dev_out, buf, sizeof(buf), NULL);
//fprintf (stderr, "BEEP 0 24\n");
}
if (type == 1 && opts->dmr_stereo == 1 && opts->audio_out == 1)
{
pa_simple_write(opts->pulse_digi_dev_outR, buf, sizeof(buf), NULL);
//fprintf (stderr, "BEEP 1 24\n");
}
if (opts->dmr_stereo == 0 && opts->audio_out == 1)
{
pa_simple_write(opts->pulse_digi_dev_out, buf, sizeof(buf), NULL);
//fprintf (stderr, "BEEP 0 8\n");
}
@@ -263,6 +252,30 @@ char * getTimeN(void) //get pretty hh:mm:ss timestamp
return curr;
}
char * getDateC(time_t t) {
char datename[99]; //Ubuntu 32-bit, use 80; everything else, use 99
char * curr2;
struct tm * to;
to = localtime( & t);
strftime(datename, sizeof(datename), "%Y-%m-%d", to);
curr2 = strtok(datename, " ");
return curr2;
}
char * getTimeC(time_t t) //get pretty hh:mm:ss timestamp
{
char * curr;
char * stamp = asctime(localtime( & t));
curr = strtok(stamp, " ");
curr = strtok(NULL, " ");
curr = strtok(NULL, " ");
curr = strtok(NULL, " ");
return curr;
}
//testing a few things, going to put this into ncursesMenu
#define WIDTH 36
#define HEIGHT 23
@@ -1637,15 +1650,17 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
}
//DMR SRC
// if ( (lls == 12 || lls == 13 || lls == 10 || lls == 11 || lls == 32) )
if ( (lls == 12 || lls == 11 || lls == 32) )
if ( (lls == 12 || lls == 13 || lls == 10 || lls == 11 || lls == 32) )
//if ( (lls == 12 || lls == 11 || lls == 32) )
{
if (state->dmrburstL == 16 && state->lastsrc > 0) //state->currentslot == 0 &&
//if (state->dmrburstL == 16 && state->lastsrc > 0) //state->currentslot == 0 &&
if (state->lastsrc > 0)
{
rd = state->lastsrc;
}
if (state->dmrburstR == 16 && state->lastsrcR > 0) //state->currentslot == 1 &&
//if (state->dmrburstR == 16 && state->lastsrcR > 0) //state->currentslot == 1 &&
if (state->lastsrcR > 0)
{
rdR = state->lastsrcR;
}
@@ -1653,14 +1668,17 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
}
//DMR TG
if ( (lls == 12 || lls == 11 || lls == 32) )
if ( (lls == 12 || lls == 13 || lls == 10 || lls == 11 || lls == 32) )
//if ( (lls == 12 || lls == 11 || lls == 32) )
{
if (state->dmrburstL == 16 && state->lasttg > 0) //state->currentslot == 0 &&
//if (state->dmrburstL == 16 && state->lasttg > 0) //state->currentslot == 0 &&
if (state->lasttg > 0)
{
tg = state->lasttg;
}
if (state->dmrburstR == 16 && state->lasttgR > 0) //state->currentslot == 1 &&
//if (state->dmrburstR == 16 && state->lasttgR > 0) //state->currentslot == 1 &&
if (state->lasttgR > 0)
{
tgR = state->lasttgR;
@@ -1808,13 +1826,14 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (opts->call_alert == 1)
{
//fprintf (stderr, "BEEP 0 MS LEFT\n");
beeper (opts, state, 0);
}
}
//DMR BS Slot 1 - matrix 0-4
if ( call_matrix[4][2] != rd && (lls == 11 || lls == 12 || lls == 35 || lls == 36) )
if ( call_matrix[4][2] != rd && (lls == 11 || lls == 12 || lls == 10 || lls == 13 || lls == 35 || lls == 36) )
{
for (short int k = 0; k < 4; k++)
@@ -1846,13 +1865,14 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (opts->call_alert == 1)
{
//fprintf (stderr, "BEEP 0 BS LEFT\n");
beeper (opts, state, 0);
}
}
//DMR BS Slot 2 - matrix 5-9
if ( call_matrix[9][2] != rdR && (lls == 11 || lls == 12 || lls == 35 || lls == 36) )
if ( call_matrix[9][2] != rdR && (lls == 11 || lls == 12 || lls == 10 || lls == 13 || lls == 35 || lls == 36) )
{
for (short int k = 5; k < 9; k++)
@@ -1883,6 +1903,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (opts->call_alert == 1)
{
//fprintf (stderr, "BEEP 1 BS RIGHT\n");
beeper (opts, state, 1);
}
@@ -1933,14 +1954,13 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
}
if (opts->ncurses_compact == 0)
{
attron(COLOR_PAIR(1)); //6
attron(COLOR_PAIR(6)); //6
for (short int i = 0; i < 7; i++)
{
printw("%s \n", FM_bannerN[i]);
}
printw (" https://github.com/lwvmobile/dsd-fme/tree/pulseaudio\n");
//printw (" Github Build Version: %s \n", GIT_TAG);
printw (" Github Build Version: %s \n", "1313"); //probably better than the first number I thought of
printw (" Github Build Version: %s \n", GIT_TAG);
attroff(COLOR_PAIR(6)); //6
// printw ("--Build Info------------------------------------------------------------------\n");
// printw ("| https://github.com/lwvmobile/dsd-fme/tree/pulseaudio\n"); //http link
@@ -2577,7 +2597,9 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
printw ("SRC [%8lld] ", call_matrix[9-j][2]);
printw ("DCC [%02lld] ", call_matrix[9-j][4]);
}
printw ("%lld secs ago\n", time(NULL) - call_matrix[9-j][5]);
printw ("%s ", getDateC(call_matrix[9-j][5]) ); //You're welcome
printw ("%s \n", getTimeC(call_matrix[9-j][5]) ); //Roman
}
} //end Call History
//fence bottom

View File

@@ -9,18 +9,20 @@
#include "dsd.h"
void processTSBK(dsd_opts * opts, dsd_state * state)
{
//process TSDU/TSBK and look for relevant data (WACN, SYSID, iden_up, other goodies later on)
int tsbkbit[196] = {0}; //tsbk bit array, 196 trellis encoded bits
int tsbk_dibit[98] = {0};
int dibit = 0;
uint8_t tsbk_byte[12] = {0}; //12 byte return from bd_bridge (block_deinterleave)
unsigned long long int PDU[24] = {0}; //24 byte PDU to send to the tsbk_byte vPDU handler, should be same formats
unsigned long long int PDU[24] = {0}; //24 byte PDU to send to the tsbk_byte vPDU handler, should be same formats (mostly)
int tsbk_decoded_bits[190] = {0}; //decoded bits from tsbk_bytes for sending to crc16_lb_bridge
int i, j, k, b, x, y;
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
//Update: Identified Bug in skipdibit incrememnt causing many block deinterleave/crc failures
//with correct values set, now we are decoding many more TSBKs
@@ -83,7 +85,8 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
}
//convert tsbk_byte to PDU and send to vPDU handler
//...may or may not be entirely compatible,
//...may or may not be entirely compatible,
MFID = tsbk_byte[1];
PDU[0] = 0x07; //P25p1 TSBK Duid 0x07
PDU[1] = tsbk_byte[0] & 0x3F;
PDU[2] = tsbk_byte[2];
@@ -99,8 +102,12 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
PDU[11] = 0; //tsbk_byte[11];
PDU[1] = PDU[1] ^ 0x40; //flip bit to make it compatible with MAC_PDUs, i.e. 3D to 7D
//Don't run NET_STS out of this, or will set wrong NAC/CC
if (err == 0 && ec == 0 && PDU[1] != 0x7B && PDU[1] != 0x49 && PDU[1] != 0x45) //0x49 is telephone grant, 0x46 Unit to Unit Channel Answer Request (seems bogus)
//check the protect bit, don't run if protected
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 )
{
fprintf (stderr, "%s",KMAG);
process_MAC_VPDU(opts, state, 0, PDU);
@@ -108,38 +115,42 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
}
//set our WACN and SYSID here now that we have valid ec and crc/checksum
if (err == 0 && ec == 0 && tsbk_byte[0] == 0x3B)
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];
int channel = (tsbk_byte[7] << 8) | tsbk_byte[8];
fprintf (stderr, "%s",KMAG);
fprintf (stderr, "\n Network Status Broadcast TSBK - Abbreviated \n");
fprintf (stderr, " WACN [%05lX] SYSID [%03X] NAC [%03llX]", wacn, sysid, state->p2_cc);
state->p25_cc_freq = process_channel_to_freq(opts, state, channel);
//only set IF these values aren't already hard set by the user
if (state->p2_hardset == 0)
{
state->p2_wacn = (tsbk_byte[3] << 12) | (tsbk_byte[4] << 4) | (tsbk_byte[5] >> 4);
state->p2_sysid = ((tsbk_byte[5] & 0xF) << 8) | tsbk_byte[6];
int channel = (tsbk_byte[7] << 8) | tsbk_byte[8];
fprintf (stderr, "%s",KMAG);
fprintf (stderr, "\n Network Status Broadcast TSBK - Abbreviated \n");
fprintf (stderr, " WACN [%05llX] SYSID [%03llX] NAC [%03llX]", state->p2_wacn, state->p2_sysid, state->p2_cc);
state->p2_wacn = wacn;
state->p2_sysid = sysid;
}
state->p25_cc_freq = process_channel_to_freq(opts, state, channel);
if (opts->payload == 1)
if (opts->payload == 1)
{
fprintf (stderr, "%s",KCYN);
fprintf (stderr, "\n P25 PDU Payload ");
for (i = 0; i < 12; i++)
{
fprintf (stderr, "%s",KCYN);
fprintf (stderr, "\n P25 PDU Payload ");
for (i = 0; i < 12; i++)
{
fprintf (stderr, "[%02X]", tsbk_byte[i]);
}
fprintf (stderr, "[%02X]", tsbk_byte[i]);
}
fprintf (stderr, "%s ", KNRM);
}
fprintf (stderr, "%s ", KNRM);
}
//reset for next rep
ec = -2;
err = -2;
protectbit = 0;
MFID = 0xFF;
//check for last block bit
if ( (tsbk_byte[0] >> 7) == 1 )
{