15 Commits

Author SHA1 Message Date
lwvmobile
8e230a08b5 Misc; 2023-06-20 04:15:51 -04:00
lwvmobile
dfc4f6f304 TXI FLC and Misc; 2023-06-19 10:01:22 -04:00
lwvmobile
5a3061f942 Merge pull request #134 from lwvmobile/zDEV
Zdev Updates
2023-06-19 06:42:26 -04:00
lwvmobile
b40281fda3 Renable DMR Late Entry SB; Misc; 2023-06-19 06:40:21 -04:00
lwvmobile
966fbf8c6a Fix Alignment 3; 2023-06-18 20:15:12 -04:00
lwvmobile
ca65f1b209 Fix Alignment 2; 2023-06-18 20:12:37 -04:00
lwvmobile
a5d73f06d2 DMR - SB TXI Information and ENC Identifiers Fix; 2023-06-18 19:54:18 -04:00
lwvmobile
56b0e8440e Initialize/Zero Some Arrays; 2023-06-17 17:32:59 -04:00
lwvmobile
b6a12b6ceb Fix RC4 'Pop' on DMR when VC6 is Null; Fix Align; 2023-06-17 17:29:03 -04:00
lwvmobile
15a12acfd3 Update Cmake for zDEV; 2023-06-15 17:47:58 -04:00
lwvmobile
c534e0f1fe Merge pull request #133 from lwvmobile/zDEV
Updates;
2023-06-15 17:39:51 -04:00
lwvmobile
5e68580fa6 DMR - Minor Cosmetic Tweaks; 2023-06-15 17:35:42 -04:00
lwvmobile
e6d83e7305 Fix CMake Options error; Update Readme; 2023-06-15 17:29:33 -04:00
lwvmobile
d56cf106b4 DMR Late Entry ENC Fix; Switch to User Option; 2023-06-12 12:38:32 -04:00
lwvmobile
4279ccf292 DMR Anytone RC4 Fix; 2023-06-12 12:35:32 -04:00
15 changed files with 1015 additions and 850 deletions

View File

@@ -46,14 +46,14 @@ if (LZ)
endif () endif ()
#use cmake option -DTONES to change default location of the tones.wav files (lwvmobile precompiled 'Aero' releases only) #use cmake option -DTONES to change default location of the tones.wav files (lwvmobile precompiled 'Aero' releases only)
option(NXDN option(TN
"Build with tone wav files in the dsd-fme folder and not in /usr/share/" OFF) "Build with tone wav files in the dsd-fme folder and not in /usr/share/" OFF)
if (TN) if (TN)
add_definitions(-DTONES) add_definitions(-DTONES)
endif () endif ()
#use cmake option -DZDEV to change designation of this build from MAIN to zDEV #use cmake option -DZDEV to change designation of this build from MAIN to zDEV
option(NXDN option(ZDEV
"change designation of this build from MAIN to zDEV" OFF) "change designation of this build from MAIN to zDEV" OFF)
if (ZDEV) if (ZDEV)
add_definitions(-DZDEV_BUILD) add_definitions(-DZDEV_BUILD)

View File

@@ -4,7 +4,7 @@
DSD-FME is an evolution of the original DSD project from 'DSD Author' using the base code of [szechyjs](https://github.com/szechyjs/dsd "szechyjs"), some code and ideas from [LouisErigHerve](https://github.com/LouisErigHerve/dsd "LouisErigHerve"), [Boatbod OP25](https://github.com/boatbod/op25 "Boatbod OP25") and DSD-FME is an evolution of the original DSD project from 'DSD Author' using the base code of [szechyjs](https://github.com/szechyjs/dsd "szechyjs"), some code and ideas from [LouisErigHerve](https://github.com/LouisErigHerve/dsd "LouisErigHerve"), [Boatbod OP25](https://github.com/boatbod/op25 "Boatbod OP25") and
[Osmocom OP25](https://gitea.osmocom.org/op25/op25 "Osmocom OP25"), along with other snippets of code, information, and inspirations from other projects including [DSDcc](https://github.com/f4exb/dsdcc "DSDcc"), [SDRTRunk](https://github.com/DSheirer/sdrtrunk "SDRTrunk"), [MMDVMHost](https://github.com/g4klx/MMDVMHost "MMDVMHost"), [LFSR](https://github.com/mattames/LFSR "LFSR"), [OK-DMRlib](https://github.com/OK-DMR/ok-dmrlib "OK-DMRlib"), and [EZPWD-Reed-Solomon](https://github.com/pjkundert/ezpwd-reed-solomon "EZPWD"), Eric Cottrell, SP5WWP and others. Finally, this is all brought together with original code to extend the fuctionality and add new features including NCurses Terminal and Menu system, Pulse Audio, TCP Direct Link Audio, RIGCTL, Trunking Features, LRRP/GPS Mapping, P25 Phase 2, EDACS, OP25 Capture Bin compatability, etc. DSD-FME is primarily focused with Linux Desktop users in mind, so please understand that this version may not compile, compile easily, or run correctly in other environments. [Osmocom OP25](https://gitea.osmocom.org/op25/op25 "Osmocom OP25"), along with other snippets of code, information, and inspirations from other projects including [DSDcc](https://github.com/f4exb/dsdcc "DSDcc"), [SDRTRunk](https://github.com/DSheirer/sdrtrunk "SDRTrunk"), [MMDVMHost](https://github.com/g4klx/MMDVMHost "MMDVMHost"), [LFSR](https://github.com/mattames/LFSR "LFSR"), [OK-DMRlib](https://github.com/OK-DMR/ok-dmrlib "OK-DMRlib"), and [EZPWD-Reed-Solomon](https://github.com/pjkundert/ezpwd-reed-solomon "EZPWD"), Eric Cottrell, SP5WWP and others. Finally, this is all brought together with original code to extend the fuctionality and add new features including NCurses Terminal and Menu system, Pulse Audio, TCP Direct Link Audio, RIGCTL, Trunking Features, LRRP/GPS Mapping, P25 Phase 2, EDACS, OP25 Capture Bin compatability, etc. DSD-FME is primarily focused with Linux Desktop users in mind, so please understand that this version may not compile, compile easily, or run correctly in other environments.
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, Forts, thewraithe2008, RayAir, and others for the many hours of wav samples and information provided by them. Most importantly, HRH17, whose insight, information, samples, and willingness to let me remote into a computer half-way across the globe in order to test trunking features are what make DSD-FME what it has become. I'd also like to thank mrscanner2008 for providing an additional remote where additional NXDN Type-C, 'Idas' Type-D, and XPT decoding and trunking could be sorted out. Thank you everybody. 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, Forts, thewraithe2008, RayAir, Cretu, and others for the many hours of wav samples and information provided by them. Most importantly, HRH17, whose insight, information, samples, and willingness to let me remote into a computer half-way across the globe in order to test trunking features are what make DSD-FME what it has become. I'd also like to thank mrscanner2008 for providing an additional remote where additional NXDN Type-C, 'Idas' Type-D, and XPT decoding and trunking could be sorted out. Thank you everybody.
![DSD-FME](https://github.com/lwvmobile/dsd-fme/blob/main/dsd-fme2.png) ![DSD-FME](https://github.com/lwvmobile/dsd-fme/blob/main/dsd-fme2.png)

View File

@@ -13,6 +13,10 @@
#dsd-fme -i tcp:192.168.7.8:7355 -U 4532 -T -f2 -m2 -N 2> log.ans #dsd-fme -i tcp:192.168.7.8:7355 -U 4532 -T -f2 -m2 -N 2> log.ans
#dsd-fme -i rtl:0:855.625M:0:-2:12 -T -f2 -m2 -N 2> log.ans #dsd-fme -i rtl:0:855.625M:0:-2:12 -T -f2 -m2 -N 2> log.ans
#P25 P2 TDMA CC with C4FM
#dsd-fme -i tcp:192.168.7.8:7355 -U 4532 -T -f2 -N 2> log.ans
#dsd-fme -i rtl:0:855.625M:0:-2:12 -T -f2 -m2 -N 2> log.ans
#DMR TIII, Con+, Cap+, XPT #DMR TIII, Con+, Cap+, XPT
dsd-fme -fs -i tcp -U 4532 -T -C dmr_t3_chan.csv -G group.csv -N 2> log.ans dsd-fme -fs -i tcp -U 4532 -T -C dmr_t3_chan.csv -G group.csv -N 2> log.ans
#dsd-fme -fs -i rtl:0:450M:44:-2:8 -T -C connect_plus_chan.csv -G group.csv -N 2> log.ans #dsd-fme -fs -i rtl:0:450M:44:-2:8 -T -C connect_plus_chan.csv -G group.csv -N 2> log.ans

View File

@@ -358,6 +358,9 @@ typedef struct
uint8_t dmr_dmrla_is_set; //flag to tell us dmrla is set by the user uint8_t dmr_dmrla_is_set; //flag to tell us dmrla is set by the user
uint8_t dmr_dmrla_n; //n value for dmrla uint8_t dmr_dmrla_n; //n value for dmrla
//DMR Late Entry
uint8_t dmr_le; //user option to turn on or turn off late entry for enc identifiers
//Trunking - Use Group List as Allow List //Trunking - Use Group List as Allow List
uint8_t trunk_use_allow_list; uint8_t trunk_use_allow_list;
@@ -1010,7 +1013,9 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power);
bool Hamming17123(uint8_t* d); bool Hamming17123(uint8_t* d);
uint8_t crc8(uint8_t bits[], unsigned int len); uint8_t crc8(uint8_t bits[], unsigned int len);
bool crc8_ok(uint8_t bits[], unsigned int len); bool crc8_ok(uint8_t bits[], unsigned int len);
//modified CRC functions for SB/RC
uint8_t crc7(uint8_t bits[], unsigned int len); uint8_t crc7(uint8_t bits[], unsigned int len);
uint8_t crc3(uint8_t bits[], unsigned int len);
//LFSR and LFSRP code courtesy of https://github.com/mattames/LFSR/ //LFSR and LFSRP code courtesy of https://github.com/mattames/LFSR/
void LFSR(dsd_state * state); void LFSR(dsd_state * state);

View File

@@ -96,6 +96,10 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
//Run Loop while the getting is good //Run Loop while the getting is good
while (loop == 1) { while (loop == 1) {
memset (ambe_fr, 0, sizeof(ambe_fr));
memset (ambe_fr2, 0, sizeof(ambe_fr2));
memset (ambe_fr3, 0, sizeof(ambe_fr3));
internalslot = -1; //reset here so we know if this value is being set properly internalslot = -1; //reset here so we know if this value is being set properly
for(i = 0; i < 12; i++) for(i = 0; i < 12; i++)
{ {
@@ -363,30 +367,17 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
memcpy (m2, ambe_fr2, sizeof(m2)); memcpy (m2, ambe_fr2, sizeof(m2));
memcpy (m3, ambe_fr3, sizeof(m3)); memcpy (m3, ambe_fr3, sizeof(m3));
// if ( opts->audio_in_type == 5 && internalslot == 0 && state->dmrburstR != 16 ) //(OSS shim)
// {
// processMbeFrame (opts, state, NULL, ambe_fr, NULL);
// processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
// processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
// }
// if ( opts->audio_in_type == 5 && internalslot == 1 && state->dmrburstL != 16 ) //(OSS shim)
// {
// processMbeFrame (opts, state, NULL, ambe_fr, NULL);
// processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
// processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
// }
processMbeFrame (opts, state, NULL, ambe_fr, NULL); processMbeFrame (opts, state, NULL, ambe_fr, NULL);
processMbeFrame (opts, state, NULL, ambe_fr2, NULL); processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
processMbeFrame (opts, state, NULL, ambe_fr3, NULL); processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
cach_err = dmr_cach (opts, state, cachdata);
if (opts->payload == 0) fprintf (stderr, "\n");
//run sbrc here to look for the late entry key and alg after we observe potential errors in VC6 //run sbrc here to look for the late entry key and alg after we observe potential errors in VC6
if (internalslot == 0 && vc1 == 6) dmr_sbrc (opts, state, power); if (internalslot == 0 && vc1 == 6) dmr_sbrc (opts, state, power);
if (internalslot == 1 && vc2 == 6) dmr_sbrc (opts, state, power); if (internalslot == 1 && vc2 == 6) dmr_sbrc (opts, state, power);
cach_err = dmr_cach (opts, state, cachdata);
if (opts->payload == 0) fprintf (stderr, "\n");
// run alg refresh after vc6 ambe processing // run alg refresh after vc6 ambe processing
if (internalslot == 0 && vc1 == 6) dmr_alg_refresh (opts, state); if (internalslot == 0 && vc1 == 6) dmr_alg_refresh (opts, state);
if (internalslot == 1 && vc2 == 6) dmr_alg_refresh (opts, state); if (internalslot == 1 && vc2 == 6) dmr_alg_refresh (opts, state);
@@ -507,6 +498,10 @@ void dmrBSBootstrap (dsd_opts * opts, dsd_state * state)
char ambe_fr2[4][24]; char ambe_fr2[4][24];
char ambe_fr3[4][24]; char ambe_fr3[4][24];
memset (ambe_fr, 0, sizeof(ambe_fr));
memset (ambe_fr2, 0, sizeof(ambe_fr2));
memset (ambe_fr3, 0, sizeof(ambe_fr3));
//memcpy of ambe_fr for late entry //memcpy of ambe_fr for late entry
char m1[4][24]; char m1[4][24];
char m2[4][24]; char m2[4][24];

View File

@@ -686,7 +686,7 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
if (gi == 0) target = (uint32_t)ConvertBitIntoBytes(&cs_pdu_bits[40], 16); if (gi == 0) target = (uint32_t)ConvertBitIntoBytes(&cs_pdu_bits[40], 16);
source = (uint32_t)ConvertBitIntoBytes(&cs_pdu_bits[64], 16); source = (uint32_t)ConvertBitIntoBytes(&cs_pdu_bits[64], 16);
int rest = (uint32_t)ConvertBitIntoBytes(&cs_pdu_bits[60], 4); int rest = (uint32_t)ConvertBitIntoBytes(&cs_pdu_bits[60], 4);
fprintf (stderr, "Source: %d - Target: %d - Rest Channel: %d", source, target, rest); fprintf (stderr, "Source: %d - Target: %d - Rest LSN: %d", source, target, rest);
} }
else fprintf (stderr, "Source: %d - Target: %d ", source, target); else fprintf (stderr, "Source: %d - Target: %d ", source, target);
@@ -820,7 +820,7 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
opts->p25_is_tuned = 1; opts->p25_is_tuned = 1;
} }
fprintf (stderr, " Capacity Plus Channel Status - FL: %d TS: %d RS: %d - Rest Channel %d", fl, ts, res, rest_channel); fprintf (stderr, " Capacity Plus Channel Status - FL: %d TS: %d RS: %d - Rest LSN: %d", fl, ts, res, rest_channel);
if (fl == 0) fprintf (stderr, " - Appended Block"); //have not yet observed a system use this fl value 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 == 1) fprintf (stderr, " - Final Block");
if (fl == 2) fprintf (stderr, " - Initial Block"); if (fl == 2) fprintf (stderr, " - Initial Block");
@@ -1018,6 +1018,9 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
//Skip tuning group calls if group calls are disabled -- moved to individual switches in the parsing phase //Skip tuning group calls if group calls are disabled -- moved to individual switches in the parsing phase
// if (opts->trunk_tune_group_calls == 0) goto SKIPCAP; // if (opts->trunk_tune_group_calls == 0) goto SKIPCAP;
//Test allowing a group in the white list to preempt a call in progress and tune to a white listed call
if (opts->trunk_use_allow_list == 1) state->last_vc_sync_time = 0;
//don't tune if vc on the current channel //don't tune if vc on the current channel
if ( (time(NULL) - state->last_vc_sync_time > 2) ) if ( (time(NULL) - state->last_vc_sync_time > 2) )
{ {
@@ -1354,6 +1357,9 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
//Skip tuning calls if group calls are disabled //Skip tuning calls if group calls are disabled
if (opts->trunk_tune_group_calls == 0) goto SKIPXPT; if (opts->trunk_tune_group_calls == 0) goto SKIPXPT;
//Test allowing a group in the white list to preempt a call in progress and tune to a white listed call
if (opts->trunk_use_allow_list == 1) state->last_vc_sync_time = 0;
//don't tune if vc on the current channel //don't tune if vc on the current channel
if ( (time(NULL) - state->last_vc_sync_time) > 2 ) //parenthesis error fixed if ( (time(NULL) - state->last_vc_sync_time) > 2 ) //parenthesis error fixed
{ {

View File

@@ -45,6 +45,13 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196
uint8_t LC_DataBytes[10]; uint8_t LC_DataBytes[10];
int Burst = -1; int Burst = -1;
memset (BPTCDeInteleavedData, 0, sizeof(BPTCDeInteleavedData));
memset (BPTCDmrDataBit, 0, sizeof(BPTCDmrDataBit));
memset (BPTCDmrDataByte, 0, sizeof(BPTCDmrDataByte));
memset (BptcDataMatrix, 0, sizeof(BptcDataMatrix));
memset (LC_DataBit, 0, sizeof(LC_DataBit));
memset (LC_DataBytes, 0, sizeof(LC_DataBytes));
//PDU Bytes and Bits //PDU Bytes and Bits
uint8_t DMR_PDU[25]; uint8_t DMR_PDU[25];
uint8_t DMR_PDU_bits[196]; uint8_t DMR_PDU_bits[196];

View File

@@ -421,22 +421,17 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C
if (fid == 0x10) if (fid == 0x10)
{ {
/* Check the "Service Option" bits */ /* Check the "Service Option" bits */
if(so & 0x30) if(so & 0x20)
{ {
/* Experimentally determined with DSD+, //REMUS! Uncomment Line Below if desired
* is equal to 0x2, this is a TXI call */ // strcat (state->call_string[slot], " TXI");
if((so & 0x30) == 0x20) fprintf(stderr, "TXI ");
{ }
//REMUS! Uncomment Line Below if desired if (so & 0x10)
// strcat (state->call_string[slot], " TXI"); {
fprintf(stderr, "TXI "); //REMUS! Uncomment Line Below if desired
} // strcat (state->call_string[slot], " RPT");
else fprintf(stderr, "RPT "); //Short way of saying the next SF's VC6 will be pre-empted/repeat frames for the TXI backwards channel
{
//REMUS! Uncomment Line Below if desired
// strcat (state->call_string[slot], " RES");
fprintf(stderr, "RS%d ", (so & 0x30) >> 4);
}
} }
if(so & 0x08) if(so & 0x08)
{ {
@@ -494,7 +489,7 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C
if (restchannel != -1) if (restchannel != -1)
{ {
fprintf (stderr, "%s ", KYEL); fprintf (stderr, "%s ", KYEL);
fprintf (stderr, "Cap+ R-Ch %d", restchannel); fprintf (stderr, "Rest LSN: %d", restchannel);
} }
} }
@@ -512,14 +507,35 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C
} }
} }
if (state->K != 0 && fid == 0x10 && so & 0x40) //BUGFIX: Include slot and algid so we don't accidentally print more than one loaded key
//this can happen on Missing PI header and LE when the keyloader has loaded a TG/Hash key and an RC4 key simultandeously
//subsequennt EMB would print two key values until call cleared out
if (state->K != 0 && fid == 0x10 && so & 0x40 && slot == 0 && state->payload_algid == 0)
{ {
fprintf (stderr, "%s", KYEL); fprintf (stderr, "%s", KYEL);
fprintf (stderr, "Key %lld ", state->K); fprintf (stderr, "Key %lld ", state->K);
fprintf (stderr, "%s ", KNRM); fprintf (stderr, "%s ", KNRM);
} }
if (state->K1 != 0 && fid == 0x68 && so & 0x40) if (state->K != 0 && fid == 0x10 && so & 0x40 && slot == 1 && state->payload_algidR == 0)
{
fprintf (stderr, "%s", KYEL);
fprintf (stderr, "Key %lld ", state->K);
fprintf (stderr, "%s ", KNRM);
}
if (state->K1 != 0 && fid == 0x68 && so & 0x40 && slot == 0 && state->payload_algid == 0)
{
if (state->K2 != 0) fprintf (stderr, "\n ");
fprintf (stderr, "%s", KYEL);
fprintf (stderr, "Key %010llX ", state->K1);
if (state->K2 != 0) fprintf (stderr, "%016llX ", state->K2);
if (state->K4 != 0) fprintf (stderr, "%016llX %016llX", state->K3, state->K4);
fprintf (stderr, "%s ", KNRM);
}
if (state->K1 != 0 && fid == 0x68 && so & 0x40 && slot == 1 && state->payload_algidR == 0)
{ {
if (state->K2 != 0) fprintf (stderr, "\n "); if (state->K2 != 0) fprintf (stderr, "\n ");
fprintf (stderr, "%s", KYEL); fprintf (stderr, "%s", KYEL);

View File

@@ -178,13 +178,24 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power)
uint8_t slot = state->currentslot; uint8_t slot = state->currentslot;
uint8_t sbrc_interleaved[32]; uint8_t sbrc_interleaved[32];
uint8_t sbrc_return[32]; uint8_t sbrc_return[32];
uint8_t sbrc_retcrc[32]; //crc significant bits of the return for SB
memset (sbrc_interleaved, 0, sizeof(sbrc_interleaved)); memset (sbrc_interleaved, 0, sizeof(sbrc_interleaved));
memset (sbrc_return, 0, sizeof(sbrc_return)); memset (sbrc_return, 0, sizeof(sbrc_return));
memset (sbrc_retcrc, 0, sizeof(sbrc_retcrc));
uint32_t irr_err = 0; uint32_t irr_err = 0;
uint32_t sbrc_hex = 0; uint32_t sbrc_hex = 0;
uint16_t crc_extracted = 7777; uint16_t crc_extracted = 7777;
uint16_t crc_computed = 9999; uint16_t crc_computed = 9999;
uint8_t crc_okay = 0; uint8_t crc7_okay = 0; //RC
uint8_t crc3_okay = 0; //TXI
uint8_t txi = 0; //SEE: https://patents.google.com/patent/US8271009B2
//NOTE: Any previous mentions to Cap+ in this area may have been in error,
//The signalling observed here was actually TXI information, not Cap+ Specifically
//check to see if this a TXI system
if (slot == 0 && state->dmr_so & 0x20) txi = 1;
if (slot == 1 && state->dmr_soR & 0x20) txi = 1;
// 9.3.2 Pre-emption and power control Indicator (PI) // 9.3.2 Pre-emption and power control Indicator (PI)
// 0 - The embedded signalling carries information associated to the same logical channel or the Null embedded message // 0 - The embedded signalling carries information associated to the same logical channel or the Null embedded message
@@ -198,8 +209,11 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power)
//bad emb burst, never set a valid power indicator value (probably 9) //bad emb burst, never set a valid power indicator value (probably 9)
if (power > 1) goto SBRC_END; if (power > 1) goto SBRC_END;
//arrange the return for proper order for the crc3 check
for (i = 0; i < 8; i++) sbrc_retcrc[i] = sbrc_return[i+3];
//RC Channel CRC 7 Mask = 0x7A; CRC bits are used as privacy indicators on //RC Channel CRC 7 Mask = 0x7A; CRC bits are used as privacy indicators on
//Single Voice Burst F (see below), other moto values seem to exist there as well //Single Voice Burst F (see below), other moto values seem to exist there as well -- See TXI patent
if (power == 1) //RC if (power == 1) //RC
{ {
crc_extracted = 0; crc_extracted = 0;
@@ -209,65 +223,106 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power)
crc_extracted = crc_extracted | sbrc_return[i+4]; crc_extracted = crc_extracted | sbrc_return[i+4];
} }
crc_extracted = crc_extracted ^ 0x7A; crc_extracted = crc_extracted ^ 0x7A;
crc_computed = crc7((uint8_t *) sbrc_return, 11); crc_computed = crc7((uint8_t *) sbrc_return, 7);
if (crc_extracted == crc_computed) crc_okay = 1; if (crc_extracted == crc_computed) crc7_okay = 1;
} }
else crc_okay = 1; //SB else //if (txi == 1) //if TXI -- but TXI systems also carry the non-crc protected ENC identifiers
{
crc_extracted = 0;
for (i = 0; i < 3; i++)
{
crc_extracted = crc_extracted << 1;
crc_extracted = crc_extracted | sbrc_return[i]; //first 3 most significant bits
}
crc_computed = crc3((uint8_t *) sbrc_retcrc, 8); //working now seems consistent as well
if (crc_extracted == crc_computed) crc3_okay = 1;
// fprintf (stderr, " CRC EXT %02X, CRC CMP %02X", crc_extracted, crc_computed);
}
// else //crc_okay = 0; //CRC invalid / not available when is ENC Identifiers (I really hate that)
for(i = 0; i < 11; i++) for(i = 0; i < 11; i++)
{ {
sbrc_hex = sbrc_hex << 1; sbrc_hex = sbrc_hex << 1;
sbrc_hex |= sbrc_return[i] & 1; //sbrc_return sbrc_hex |= sbrc_return[i] & 1;
} }
if (opts->payload == 1) //hide the sb/rc behind the payload printer, won't be useful to most people if (opts->payload == 1) //hide the sb/rc behind the payload printer, won't be useful to most people
{ {
fprintf (stderr, "\n %s", KCYN); fprintf (stderr, "%s", KCYN);
if (power == 0) fprintf (stderr, " SB: "); if (power == 0) fprintf (stderr, " SB: ");
if (power == 1) fprintf (stderr, " RC: "); if (power == 1) fprintf (stderr, " RC: ");
for(i = 0; i < 11; i++) for(i = 0; i < 11; i++)
fprintf (stderr, "%d", sbrc_return[i]); fprintf (stderr, "%d", sbrc_return[i]);
fprintf (stderr, " - %03X", sbrc_hex); fprintf (stderr, " - %03X; ", sbrc_hex);
fprintf (stderr, "%s", KNRM); fprintf (stderr, "%s", KNRM);
if (crc_okay == 0) // if (crc_okay == 0) //forego this since the crc can vary or not be used at all
{ // {
fprintf (stderr, "%s", KRED); // fprintf (stderr, "%s", KRED);
fprintf (stderr, " (CRC ERR)"); // fprintf (stderr, " (CRC ERR)");
fprintf (stderr, "%s", KNRM); // fprintf (stderr, "%s", KNRM);
fprintf (stderr, " CRC EXT %02X, CRC CMP %02X", crc_extracted, crc_computed); // fprintf (stderr, " CRC EXT %02X, CRC CMP %02X", crc_extracted, crc_computed);
} // }
fprintf (stderr, "\n");
} }
uint8_t sbrc_opcode = sbrc_hex; uint8_t sbrc_opcode = sbrc_hex & 0x7; //opcode and alg the same bits, but the alg is present when CRC is bad (I know they are limited on bits, but I hate that idea)
uint8_t alg = sbrc_hex & 0x7; uint8_t alg = sbrc_hex & 0x7;
uint8_t key = (sbrc_hex >> 3) & 0xFF; uint8_t key = (sbrc_hex >> 3) & 0xFF;
uint8_t cap_site = (sbrc_hex >> 4) & 0x7; //signalling on Cap+ when voice errors (non voice VC6 is present) uint8_t txi_delay = (sbrc_hex >> 3) & 0x1F; //middle five are the 'delay' value on a TXI system
if (1 == 1) //opts->payload == 1 if (opts->dmr_le == 1) //this will now require a user to switch it on or off until more testing/figuring can be done
{ {
if (irr_err != 0) ; //fprintf (stderr, "\n %s SLOT %d SB/RC (FEC ERR) %d %s \n", KRED, slot, irr_err, KNRM); if (irr_err != 0) fprintf (stderr, "\n %s SLOT %d SB/RC (FEC ERR) %d %s \n", KRED, slot, irr_err, KNRM);
if (irr_err == 0) if (irr_err == 0)
{ {
if (sbrc_hex == 0) ; //NULL if (sbrc_hex == 0) ; //NULL, do nothing
//else if (placeholder for future conditions) //else if (placeholder for future conditions)
// { // {
// placeholder for future conditions // placeholder for future conditions
// } // }
else //Finally have a consistent set-up for this
else if (crc7_okay == 1)
{ {
//the signalling here is always presents on good voice frames, if errs are [3][2] then its not a VC6 voice frame, but some other 'hidden' frame //do something with the reverse channel information
if (slot == 0 && state->errs < 3) }
//if the call is interruptable (TXI) and the crc3 is okay
else if (crc3_okay == 1)
{
//opcodes -- 0 (NULL), BR Delay (3)
fprintf (stderr, "\n");
fprintf (stderr, " TXI Op: %X - ", sbrc_opcode);
if (sbrc_opcode == 0) fprintf (stderr, " Null; ");
else if (sbrc_opcode == 3)
{
if (txi_delay != 0)
fprintf (stderr, " BR Delay: %d - %d ms; ", txi_delay, txi_delay * 30); //could also indicate number of superframes until next VC6 pre-emption
else fprintf (stderr, "BR Delay: Irrelevant / Send at any time;");
}
else fprintf (stderr, " Unk; ");
if (opts->payload == 1) fprintf (stderr, "\n"); //only during payload
}
else //all that should be left in this field is the potential ENC identifiers
{
if (slot == 0) //may not need the state->errs anymore //&& state->errs < 3
{ {
if (state->dmr_so & 0x40 && key != 0 && state->payload_keyid == 0) if (state->dmr_so & 0x40 && key != 0 && state->payload_keyid == 0)
{ {
//if we aren't forcing a particular alg or privacy key set //if we aren't forcing a particular alg or privacy key set
if (state->M == 0) if (state->M == 0)
{ {
fprintf (stderr, "\n");
fprintf (stderr, "%s ", KYEL); fprintf (stderr, "%s ", KYEL);
fprintf (stderr, " Slot 1"); fprintf (stderr, " Slot 1");
fprintf (stderr, " DMR LE SB ALG ID: %X KEY ID: %0X", alg + 0x20, key); fprintf (stderr, " DMR LE SB ALG ID: %X KEY ID: %0X", alg + 0x20, key);
fprintf (stderr, "\n"); // fprintf (stderr, "\n");
fprintf (stderr, "%s ", KNRM); fprintf (stderr, "%s ", KNRM);
state->payload_keyid = key; state->payload_keyid = key;
@@ -277,18 +332,18 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power)
} }
} }
//the signalling here is always presents on good voice frames, if errs are [3][2] then its not a VC6 voice frame, but some other 'hidden' frame if (slot == 1) //may not need the state->errs anymore //&& state->errsR < 3
if (slot == 1 && state->errsR < 3)
{ {
if (state->dmr_soR & 0x40 && key != 0 && state->payload_keyidR == 0) if (state->dmr_soR & 0x40 && key != 0 && state->payload_keyidR == 0)
{ {
//if we aren't forcing a particular alg or privacy key set //if we aren't forcing a particular alg or privacy key set
if (state->M == 0) if (state->M == 0)
{ {
fprintf (stderr, "%s ", KYEL);
fprintf (stderr, " Slot 1");
fprintf (stderr, " DMR LE SB ALG ID: %X KEY ID: %0X", alg + 0x20, key);
fprintf (stderr, "\n"); fprintf (stderr, "\n");
fprintf (stderr, "%s ", KYEL);
fprintf (stderr, " Slot 2");
fprintf (stderr, " DMR LE SB ALG ID: %X KEY ID: %0X", alg + 0x20, key);
// fprintf (stderr, "\n");
fprintf (stderr, "%s ", KNRM); fprintf (stderr, "%s ", KNRM);
state->payload_keyidR = key; state->payload_keyidR = key;
@@ -323,3 +378,27 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power)
} }
uint8_t crc3(uint8_t bits[], unsigned int len)
{
uint8_t crc=0;
unsigned int K = 3;
//x^3+x+1
uint8_t poly[4] = {1,1,0,1};
uint8_t buf[256];
if (len+K > sizeof(buf)) {
return 0;
}
memset (buf, 0, sizeof(buf));
for (unsigned int i=0; i<len; i++){
buf[i] = bits[i];
}
for (unsigned int i=0; i<len; i++)
if (buf[i])
for (unsigned int j=0; j<K+1; j++)
buf[i+j] ^= poly[j];
for (unsigned int i=0; i<K; i++){
crc = (crc << 1) + buf[len + i];
}
return crc;
}

View File

@@ -89,6 +89,10 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
for (j = 0; j < 6; j++) { for (j = 0; j < 6; j++) {
state->dmrburstL = 16; state->dmrburstL = 16;
memset (ambe_fr, 0, sizeof(ambe_fr));
memset (ambe_fr2, 0, sizeof(ambe_fr2));
memset (ambe_fr3, 0, sizeof(ambe_fr3));
for(i = 0; i < 12; i++) for(i = 0; i < 12; i++)
{ {
dibit = getDibit(opts, state); dibit = getDibit(opts, state);
@@ -370,7 +374,11 @@ void dmrMSBootstrap (dsd_opts * opts, dsd_state * state)
char ambe_fr[4][24]; char ambe_fr[4][24];
char ambe_fr2[4][24]; char ambe_fr2[4][24];
char ambe_fr3[4][24]; char ambe_fr3[4][24];
char ambe_fr4[4][24]; //shim for crappy tdma direct, need more samples to see if this is really a necessary shim or not char ambe_fr4[4][24];
memset (ambe_fr, 0, sizeof(ambe_fr));
memset (ambe_fr2, 0, sizeof(ambe_fr2));
memset (ambe_fr3, 0, sizeof(ambe_fr3));
//memcpy of ambe_fr for late entry //memcpy of ambe_fr for late entry
char m1[4][24]; char m1[4][24];

View File

@@ -26,6 +26,14 @@ void dmr_pi (dsd_opts * opts, dsd_state * state, uint8_t PI_BYTE[], uint32_t CRC
fprintf (stderr, "%s ", KYEL); fprintf (stderr, "%s ", KYEL);
fprintf (stderr, "\n Slot 1"); fprintf (stderr, "\n Slot 1");
fprintf (stderr, " DMR PI H- ALG ID: 0x%02X KEY ID: 0x%02X MI: 0x%08X", state->payload_algid, state->payload_keyid, state->payload_mi); fprintf (stderr, " DMR PI H- ALG ID: 0x%02X KEY ID: 0x%02X MI: 0x%08X", state->payload_algid, state->payload_keyid, state->payload_mi);
//Anytone RC4 Shim
if (state->payload_algid == 0x01)
{
fprintf (stderr, " Anytone (0x01)");
state->payload_algid = 0x21;
}
fprintf (stderr, "%s ", KNRM); fprintf (stderr, "%s ", KNRM);
if (state->payload_algid != 0x21) if (state->payload_algid != 0x21)
{ {
@@ -53,6 +61,14 @@ void dmr_pi (dsd_opts * opts, dsd_state * state, uint8_t PI_BYTE[], uint32_t CRC
fprintf (stderr, "%s ", KYEL); fprintf (stderr, "%s ", KYEL);
fprintf (stderr, "\n Slot 2"); fprintf (stderr, "\n Slot 2");
fprintf (stderr, " DMR PI H- ALG ID: 0x%02X KEY ID: 0x%02X MI: 0x%08X", state->payload_algidR, state->payload_keyidR, state->payload_miR); fprintf (stderr, " DMR PI H- ALG ID: 0x%02X KEY ID: 0x%02X MI: 0x%08X", state->payload_algidR, state->payload_keyidR, state->payload_miR);
//Anytone RC4 Shim
if (state->payload_algidR == 0x01)
{
fprintf (stderr, " Anytone (0x01)");
state->payload_algidR = 0x21;
}
fprintf (stderr, "%s ", KNRM); fprintf (stderr, "%s ", KNRM);
if (state->payload_algidR != 0x21) if (state->payload_algidR != 0x21)
{ {

View File

@@ -1606,7 +1606,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
if ((opts->errorbars == 1) && (opts->verbose > 1) && (state->carrier == 1)) if ((opts->errorbars == 1) && (opts->verbose > 1) && (state->carrier == 1))
{ {
fprintf (stderr,"Sync: no sync\n"); fprintf (stderr,"Sync: no sync\n");
fprintf (stderr,"Press CTRL + C to close.\n"); // fprintf (stderr,"Press CTRL + C to close.\n");
} }
noCarrier (opts, state); noCarrier (opts, state);

View File

@@ -627,6 +627,9 @@ initOpts (dsd_opts * opts)
opts->dmr_dmrla_is_set = 0; opts->dmr_dmrla_is_set = 0;
opts->dmr_dmrla_n = 0; opts->dmr_dmrla_n = 0;
//DMR Late Entry
opts->dmr_le = 1; //re-enabled again
//Trunking - Use Group List as Allow List //Trunking - Use Group List as Allow List
opts->trunk_use_allow_list = 0; //disabled by default opts->trunk_use_allow_list = 0; //disabled by default
@@ -1153,6 +1156,12 @@ usage ()
printf (" -4 Force Privacy Key over Encryption Identifiers (DMR BP and NXDN Scrambler) \n"); printf (" -4 Force Privacy Key over Encryption Identifiers (DMR BP and NXDN Scrambler) \n");
printf (" \n"); printf (" \n");
printf (" -0 Force RC4 Key over Missing PI header/LE Encryption Identifiers (DMR) \n"); printf (" -0 Force RC4 Key over Missing PI header/LE Encryption Identifiers (DMR) \n");
printf (" \n");
printf (" -3 Disable DMR Late Entry Encryption Identifiers (VC6 Single Burst) \n");
printf (" Note: Disable this if false positives on Voice ENC occur. \n");
// printf (" -3 Enable DMR Late Entry Encryption Identifiers (VC6 Single Burst) \n");
// printf (" Note: This is experimental and may produce false positives depending on system type, notably TXI. \n");
// printf (" Use -0 or -4 options above instead if needed. \n");
printf ("\n"); printf ("\n");
printf (" Trunking Options:\n"); printf (" Trunking Options:\n");
printf (" -C <file> Import Channel to Frequency Map (channum, freq) from csv file. (Capital C) \n"); printf (" -C <file> Import Channel to Frequency Map (channum, freq) from csv file. (Capital C) \n");
@@ -1356,7 +1365,7 @@ main (int argc, char **argv)
mbe_printVersion (versionstr); mbe_printVersion (versionstr);
#ifdef LIMAZULUTWEAKS #ifdef LIMAZULUTWEAKS
fprintf (stderr," Digital Speech Decoder: LimaZulu Edition IV\n"); fprintf (stderr," Digital Speech Decoder: LimaZulu Edition V\n");
#else #else
fprintf (stderr," Digital Speech Decoder: Florida Man Edition\n"); fprintf (stderr," Digital Speech Decoder: Florida Man Edition\n");
#endif #endif
@@ -1365,7 +1374,7 @@ main (int argc, char **argv)
} }
#ifdef AERO_BUILD #ifdef AERO_BUILD
fprintf (stderr, "Build Version: v2.1 Beta \n"); fprintf (stderr, "Build Version: v2.1 \n");
#else #else
fprintf (stderr, "Build Version: %s \n", GIT_TAG); fprintf (stderr, "Build Version: %s \n", GIT_TAG);
#endif #endif
@@ -1415,6 +1424,11 @@ main (int argc, char **argv)
state.keyloader = 0; //turn off keyloader state.keyloader = 0; //turn off keyloader
break; break;
case '3':
opts.dmr_le = 0;
fprintf (stderr,"DMR Late Entry Encryption Identifiers Disabled (VC6 Single Burst)\n");
break;
case 'Y': //conventional scanner mode case 'Y': //conventional scanner mode
opts.scanner_mode = 1; //enable scanner opts.scanner_mode = 1; //enable scanner
opts.p25_trunk = 0; //turn off trunking mode if user enabled it opts.p25_trunk = 0; //turn off trunking mode if user enabled it

File diff suppressed because it is too large Load Diff

View File

@@ -2158,7 +2158,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (opts->ncurses_compact == 1) if (opts->ncurses_compact == 1)
{ {
printw ("------------------------------------------------------------------------------\n"); printw ("------------------------------------------------------------------------------\n");
printw ("| Digital Speech Decoder: Florida Man Edition - Aero %s \n", "v2.1 Beta"); printw ("| Digital Speech Decoder: Florida Man Edition - Aero %s \n", "v2.1 ");
printw ("------------------------------------------------------------------------------\n"); printw ("------------------------------------------------------------------------------\n");
} }
#elif LIMAZULUTWEAKS #elif LIMAZULUTWEAKS
@@ -2194,7 +2194,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (i == 4) printw (" MBElib %s", versionstr); if (i == 4) printw (" MBElib %s", versionstr);
#ifdef AERO_BUILD #ifdef AERO_BUILD
if (i == 5) printw (" %s ", "Aero Build"); if (i == 5) printw (" %s ", "Aero Build");
if (i == 6) printw (" v2.1 Beta \n"); if (i == 6) printw (" v2.1 \n");
#elif ZDEV_BUILD #elif ZDEV_BUILD
if (i == 5) printw (" %s ", "zDEV Build"); if (i == 5) printw (" %s ", "zDEV Build");
if (i == 6) printw (" %s \n", GIT_TAG); if (i == 6) printw (" %s \n", GIT_TAG);
@@ -2701,7 +2701,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
attron(COLOR_PAIR(3)); attron(COLOR_PAIR(3));
} }
if (state->payload_algid == 0xAA || state->payload_algid == 0x21) //Anytone 0x01 will never show here since its converted to 0x21 for handling
if (state->payload_algid == 0xAA || state->payload_algid == 0x21 || state->payload_algid == 0x01)
{ {
attron(COLOR_PAIR(1)); attron(COLOR_PAIR(1));
printw("RC4 "); printw("RC4 ");
@@ -2898,7 +2899,9 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
attroff(COLOR_PAIR(1)); attroff(COLOR_PAIR(1));
attron(COLOR_PAIR(3)); attron(COLOR_PAIR(3));
} }
if (state->payload_algidR == 0xAA || state->payload_algidR == 0x21)
//Anytone 0x01 will never show here since its converted to 0x21 for handling
if (state->payload_algidR == 0xAA || state->payload_algidR == 0x21 || state->payload_algidR == 0x01)
{ {
attron(COLOR_PAIR(1)); attron(COLOR_PAIR(1));
printw("RC4 "); printw("RC4 ");