mirror of https://github.com/lwvmobile/dsd-fme.git
Data Header and Data Bursts Cleanup
Cleanup the code in the dmr_sync.c file, fix minor code errors. Include the dsd-fme-qgis-map file for opening with QGIS and importing LRRP data dumped to ~/lrrp.txt Update the Readme file.
This commit is contained in:
parent
b39d5d8401
commit
11b353089b
53
README.md
53
README.md
|
|
@ -1,26 +1,34 @@
|
||||||
# Digital Speech Decoder - Florida Man Edition
|
# 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 as well. 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"), and [LFSR](https://github.com/mattames/LFSR "LFSR"). 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.
|
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 as well. 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"), and [LFSR](https://github.com/mattames/LFSR "LFSR"). 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.
|
||||||
|
|
||||||
## 2022.06.20 Update - Current Users Please Read!! ##
|
## 2022.08.12 Update ##
|
||||||
The executable for this project has been changed from `dsd` to `dsd-fme` so after pulling or cloning the lastest version, make sure to call the software with `dsd-fme`. It may also be beneficial to open your current build folder and run `sudo make uninstall` to uninstall the binary named `dsd` or to run `sudo rm /usr/local/bin/dsd` to alleviate any confusion or from accidentally calling the older version as it will still be installed along with the new `dsd-fme` executable. The Summer Cleanup Project has also seen a lot of the files that weren't in use, or used for github workflows and cmake files removed from the project folder, slimming it down quite considerably. If you have any issue doing a git pull to get the current version, you may need to instead do a fresh clone, build, and install in a clean folder. Check the info below about running download-and-install-nodeps.sh if needed.
|
A new menu system has been introduced in the NCURSES Terminal. While running DSD-FME, a user can simply use the ESC or arrow keys to open the menu and change options on the fly. This is extremely beneficial when wanting to change settings on the fly, and also to alleviate the need to use complex start up command line arguments. All of the previous command line arguments still work and will get you up faster, but if you would rather configure after start up, or change settings while running, the menu system is very helpful in that regard.
|
||||||
|
|
||||||
## 2022.05.05 Update ##
|

|
||||||
I have successfully added a DMR Stereo method for listening to voice audio in both TDMA channels/slots simultaneously. This method will also allow for data decoding in the opposite slot if only one voice call is active, allowing the user not to miss any useful information in the second slot while the previous slot is in use. DMR Stereo also has vastly improved handling of MS/Simplex voice decoding and (hit or miss) MS data decoding. To call this method, see the example below. The old method of decoding DMR is also included and is stil the default for the time being, but the DMR Stereo method is working well, users are encouraged to try both methods and find the one that is suitable for them. New commands include:
|
|
||||||
```
|
|
||||||
-T Enable DMR 'TDMA' Stereo
|
|
||||||
-F Enable Passive Frame Sync
|
|
||||||
```
|
|
||||||
Please note, for the time being, MBE file saving and WAV file saving are disabled while using DMR Stereo. These features are still present in the default DMR handling and other voice decoder options and will be re-integrated into DMR Stereo in the future. DMR Stereo will also need to be enabled to handle DMR MS/Simplex voice, as it was removed from the default method due to poor performance.
|
|
||||||
|
|
||||||
Use Passive Frame Sync if voice in both slots becomes choppy or skips. Using Passive Sync may cause wonky audio though, depends on quality of signal and bit errors present.
|
To get started with the new menu system, simply launch with:
|
||||||
|
|
||||||
|
`dsd-fme -N 2> log.txt`
|
||||||
|
|
||||||
|
Virtually all the examples listed below can now be set up on the fly with the menu system, no need to check the help or refer to this page.
|
||||||
|
|
||||||
|
This release also has provisional support for playing back OP25 capture bin files, and the creation and playback of its own capture bin files as well (most likely not OP25 compatible). Mileage may vary. Be sure to choose the decoder option required when playing a bin file back, do not rely on auto-detect. Capture Bin files can be used to reliably replay P25, DMR, and NXDN decodings, and can replace the need for MBE file saving in the case of DMR Stereo, allowing for a complete replay of all events on a system, rather than just voice only.
|
||||||
|
|
||||||
|
Per Call wav file creation has been implemented, currently only for DMR Stereo. Complete audio decode wav is available for all over decoder types. LRRP has been revamped, working more consistently, and an option to dump LRRP data to ~/lrrp.txt in the user home directory now exists, and can be imported into open-source QGIS to provide mapping data for LRRP output. Simply open the newly included map file in QGIS and point it at your geographic region. (Be sure the lrrp.txt file exists, and has data populated in it prior to opening the map file in QGIS, otherwise, the map layer may not want to show back up!)
|
||||||
|
|
||||||
|
DMR Data Header decoding has been revamped, and most data burst decoding types tightened up and code cleaned. FEC error checking now implemented on CACH and Burst types, cleaning up some erroneous slot and burst errors.
|
||||||
|
|
||||||
|
## 2022.06.20 Update - Current Users Please Read!! ##
|
||||||
|
The executable for this project has been changed from `dsd` to `dsd-fme` so after pulling or cloning the lastest version, make sure to call the software with `dsd-fme`.
|
||||||
|
|
||||||
|
## 2022.05.05 Update ##
|
||||||
|
DMR Stereo method added for listening to voice audio in both TDMA channels/slots simultaneously.
|
||||||
|
|
||||||
### Example Usage and Note!
|
### Example Usage and Note!
|
||||||
`dsd-fme` or `./dsd-fme` may need to be used in your usage, depending on if you are running it from the build folder, or if you have run make install. You will need to tweak the examples to your particular usage. Users can always check `dsd-fme -h` for help and all command line switches to use.
|
`dsd-fme` or `./dsd-fme` may need to be used in your usage, depending on if you are running it from the build folder, or if you have run make install. You will need to tweak the examples to your particular usage. Users can always check `dsd-fme -h` for help and all command line switches to use.
|
||||||
|
|
||||||
`dsd-fme` is all you need to run for pulse input, pulse output, and auto detect for DMR, P25P1, D-STAR, and X2-TDMA decoding. To use other decoding methods which cannot be auto detected, please use the following command line switches. Make sure to route audio into and out of DSD-FME using pavucontrol and virtual sinks as needed.
|
`dsd-fme` is all you need to run for pulse input, pulse output, and auto detect for DMR, P25P1, D-STAR, and X2-TDMA decoding. To use other decoding methods which cannot be auto detected, please use the following command line switches. Make sure to route audio into and out of DSD-FME using pavucontrol and virtual sinks as needed.
|
||||||
|
|
||||||
```
|
```
|
||||||
-fi NXDN48
|
-fi NXDN48
|
||||||
|
|
@ -82,21 +90,22 @@ and in a second terminal tab, same folder, run
|
||||||
## Roadmap
|
## Roadmap
|
||||||
The Current list of objectives include:
|
The Current list of objectives include:
|
||||||
|
|
||||||
1. ~~Random Tinkering~~ More Random Tinkering
|
1. Include P25 P2 Audio decoding with capture bin files, then RTL input and/or disc tap input.
|
||||||
|
~~Random Tinkering~~ ~~More Random Tinkering~~
|
||||||
|
|
||||||
2. ~~Implemented Pulse Audio~~ Remove remaining PortAudio code, ~~improved Pulse Audio for stereo output and channel/slot separation~~ and reimplement wav file saving using DMR Stereo method for stereo wav files, or seperate as per call wav files.
|
2. ~~Implemented Pulse Audio~~ ~~Remove remaining PortAudio code,~~ ~~improved Pulse Audio for stereo output and channel/slot separation~~ ~~and reimplement wav file saving using DMR Stereo method for stereo wav files, or seperate as per call wav files.~~
|
||||||
|
|
||||||
3. ~~Improve NXDN and DMR support~~ Continue to improve ~~NXDN and DMR~~ all data and voice decoding.
|
3. ~~Improve NXDN and DMR support~~ Continue to improve ~~NXDN and DMR~~ all data and voice decoding.
|
||||||
|
|
||||||
4. ~~More Concise Printouts - Ncurses~~
|
4. ~~More Concise Printouts - Ncurses~~
|
||||||
|
|
||||||
5. ~~Make simple to use installer script.~~
|
5. ~~Make simple to use installer script.~~
|
||||||
|
|
||||||
## How to clone, check out, and build this branch
|
## How to clone, check out, and build this branch
|
||||||
|
|
||||||
### Ubuntu 22.04/20.04/LM20/Debian Bullseye or Newer:
|
### Ubuntu 22.04/20.04/LM20/Debian Bullseye or Newer:
|
||||||
|
|
||||||
Using the included download-and-install.sh should make for a simple and painless clone, build, and install on newer Debian/Ubuntu/Mint/Pi systems. Simply acquire or copy the script, and run it. Update: Ubuntu 22.04 and RPi Bullseye 64-bit has been tested working with the installer script and functions appropriately.
|
Using the included download-and-install.sh should make for a simple and painless clone, build, and install on newer Debian/Ubuntu/Mint/Pi systems. Simply acquire or copy the script, and run it. Update: Ubuntu 22.04 and RPi Bullseye 64-bit has been tested working with the installer script and functions appropriately.
|
||||||
|
|
||||||
If you need all dependencies build and installed first (only on Debian/Ubuntu/Mint/Pi), run:
|
If you need all dependencies build and installed first (only on Debian/Ubuntu/Mint/Pi), run:
|
||||||
|
|
||||||
|
|
@ -119,7 +128,7 @@ The above install.sh should now function on older system types. You can elect to
|
||||||
|
|
||||||
## Manual Install
|
## Manual Install
|
||||||
|
|
||||||
First, install dependency packages. This guide will assume you are using Debian/Ubuntu based distros. Check your package manager for equivalent packages if different.
|
First, install dependency packages. This guide will assume you are using Debian/Ubuntu based distros. Check your package manager for equivalent packages if different.
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo apt update
|
sudo apt update
|
||||||
|
|
@ -139,7 +148,7 @@ sudo apt install libpulse-dev libsndfile1-dev libfftw3-dev liblapack-dev socat l
|
||||||
wget -O itpp-latest.tar.bz2 http://sourceforge.net/projects/itpp/files/latest/download?source=files
|
wget -O itpp-latest.tar.bz2 http://sourceforge.net/projects/itpp/files/latest/download?source=files
|
||||||
tar xjf itpp*
|
tar xjf itpp*
|
||||||
#if you can't cd into this folder, double check folder name first
|
#if you can't cd into this folder, double check folder name first
|
||||||
cd itpp-4.3.1
|
cd itpp-4.3.1
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake ..
|
cmake ..
|
||||||
|
|
@ -225,5 +234,3 @@ GPG Key ID: 0x3F1D7FD0 (74EF 430D F7F2 0A48 FCE6 F630 FAA2 635D 3F1D 7FD0)
|
||||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
PERFORMANCE OF THIS SOFTWARE.
|
PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -519,8 +519,8 @@ typedef struct
|
||||||
TimeSlotVoiceSuperFrame_t TS2SuperFrame;
|
TimeSlotVoiceSuperFrame_t TS2SuperFrame;
|
||||||
|
|
||||||
char dmr_branding[25];
|
char dmr_branding[25];
|
||||||
uint8_t dmr_12_rate_sf[2][84]; //going seven blocks deep by 12 bytes //[slot][value]
|
uint8_t dmr_12_rate_sf[2][288]; //was 84, expanded to 288 to prevent possible crash if more comes in than expected
|
||||||
uint8_t dmr_34_rate_sf[2][96]; //going six blocks deep by 16 bytes //[slot][value]
|
uint8_t dmr_34_rate_sf[2][288]; //was 96, expanded to 288 to prevent possible crash if more comes in than expected
|
||||||
int dmr_stereo_payload[144]; //load up 144 dibit buffer for every single DMR TDMA frame
|
int dmr_stereo_payload[144]; //load up 144 dibit buffer for every single DMR TDMA frame
|
||||||
uint8_t data_header_blocks[2]; //collect number of blocks to follow from data header per slot
|
uint8_t data_header_blocks[2]; //collect number of blocks to follow from data header per slot
|
||||||
uint8_t data_header_padding[2]; //collect number of padding octets in last block per slot
|
uint8_t data_header_padding[2]; //collect number of padding octets in last block per slot
|
||||||
|
|
@ -833,7 +833,7 @@ void Process12Data(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_
|
||||||
void Process34Data(dsd_opts * opts, dsd_state * state, unsigned char tdibits[98], uint8_t syncdata[48], uint8_t SlotType[20]);
|
void Process34Data(dsd_opts * opts, dsd_state * state, unsigned char tdibits[98], uint8_t syncdata[48], uint8_t SlotType[20]);
|
||||||
void ProcessMBCData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20]);
|
void ProcessMBCData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20]);
|
||||||
void ProcessMBChData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20]);
|
void ProcessMBChData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20]);
|
||||||
void ProcessWTFData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20]);
|
void ProcessReservedData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20]);
|
||||||
void ProcessUnifiedData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20]);
|
void ProcessUnifiedData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20]);
|
||||||
|
|
||||||
//LFSR code courtesy of https://github.com/mattames/LFSR/
|
//LFSR code courtesy of https://github.com/mattames/LFSR/
|
||||||
|
|
|
||||||
|
|
@ -523,14 +523,14 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||||
/* Burst = MBC Header */
|
/* Burst = MBC Header */
|
||||||
case 0b0100:
|
case 0b0100:
|
||||||
{
|
{
|
||||||
//ProcessMBChData(opts, state, (uint8_t *)info, (uint8_t *)syncdata, (uint8_t *)SlotType);
|
ProcessMBChData(opts, state, (uint8_t *)info, (uint8_t *)syncdata, (uint8_t *)SlotType);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Burst = MBC Continuation*/
|
/* Burst = MBC Continuation*/
|
||||||
case 0b0101:
|
case 0b0101:
|
||||||
{
|
{
|
||||||
//ProcessMBCData(opts, state, (uint8_t *)info, (uint8_t *)syncdata, (uint8_t *)SlotType);
|
ProcessMBCData(opts, state, (uint8_t *)info, (uint8_t *)syncdata, (uint8_t *)SlotType);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -566,14 +566,14 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||||
/* Burst = Rate 1 DATA */
|
/* Burst = Rate 1 DATA */
|
||||||
case 0b1010:
|
case 0b1010:
|
||||||
{
|
{
|
||||||
//Process1Data(opts, state, (uint8_t *)info, (uint8_t *)syncdata, (uint8_t *)SlotType);
|
Process1Data(opts, state, (uint8_t *)info, (uint8_t *)syncdata, (uint8_t *)SlotType);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Burst = Unified Single Block DATA */
|
/* Burst = Unified Single Block DATA */
|
||||||
case 0b1101:
|
case 0b1101:
|
||||||
{
|
{
|
||||||
//ProcessUnifiedData(opts, state, (uint8_t *)info, (uint8_t *)syncdata, (uint8_t *)SlotType);
|
ProcessUnifiedData(opts, state, (uint8_t *)info, (uint8_t *)syncdata, (uint8_t *)SlotType);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -581,7 +581,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
/* Nothing to do */
|
/* Nothing to do */
|
||||||
//ProcessWTFData(opts, state, (uint8_t *)info, (uint8_t *)syncdata, (uint8_t *)SlotType);
|
ProcessReservedData(opts, state, (uint8_t *)info, (uint8_t *)syncdata, (uint8_t *)SlotType);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} /* End switch(burst) */
|
} /* End switch(burst) */
|
||||||
|
|
|
||||||
458
src/dmr_sync.c
458
src/dmr_sync.c
|
|
@ -17,8 +17,6 @@
|
||||||
|
|
||||||
#include "dsd.h"
|
#include "dsd.h"
|
||||||
|
|
||||||
|
|
||||||
//time_t now;
|
|
||||||
char * getTimeL(void) //get pretty hh:mm:ss timestamp
|
char * getTimeL(void) //get pretty hh:mm:ss timestamp
|
||||||
{
|
{
|
||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
|
|
@ -47,11 +45,10 @@ char * getDateL(void) {
|
||||||
return curr2;
|
return curr2;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Need to work in a way to seperate data bursts on seperate slots, having data pouring into both slots simultaneously
|
//Trellis Decoding still needs work, so be surprised by bad decodes
|
||||||
//Need to make seperate superframe arrays for each
|
|
||||||
void Process34Data(dsd_opts * opts, dsd_state * state, unsigned char tdibits[98], uint8_t syncdata[48], uint8_t SlotType[20])
|
void Process34Data(dsd_opts * opts, dsd_state * state, unsigned char tdibits[98], uint8_t syncdata[48], uint8_t SlotType[20])
|
||||||
{
|
{
|
||||||
//NEED TRELLIS DECODER HERE
|
|
||||||
uint32_t i, j, k;
|
uint32_t i, j, k;
|
||||||
uint32_t CRCExtracted = 0;
|
uint32_t CRCExtracted = 0;
|
||||||
uint32_t CRCComputed = 0;
|
uint32_t CRCComputed = 0;
|
||||||
|
|
@ -76,52 +73,18 @@ void Process34Data(dsd_opts * opts, dsd_state * state, unsigned char tdibits[98]
|
||||||
TSVoiceSupFrame = &state->TS2SuperFrame;
|
TSVoiceSupFrame = &state->TS2SuperFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
CRCExtracted = 0;
|
|
||||||
CRCComputed = 0;
|
|
||||||
IrrecoverableErrors = 0;
|
|
||||||
|
|
||||||
/* Deinterleave DMR data */
|
|
||||||
//BPTCDeInterleaveDMRData(info, DeInteleavedData);
|
|
||||||
//info is the dibits; is output DeInterleavedData?
|
|
||||||
//data is dibits I think, so sub info for data? only wants 98U dibits though.
|
|
||||||
//returns 'payload' which is 144 bit array, so DmrDataBit maybe?
|
|
||||||
//CDMRTrellisDecode(const unsigned char* data, unsigned char* payload)
|
|
||||||
unsigned char tdibits_reverse[98];
|
unsigned char tdibits_reverse[98];
|
||||||
unsigned char tdibits_inverted[98];
|
unsigned char tdibits_inverted[98];
|
||||||
unsigned char tdibits_to_bits[196];
|
unsigned char tdibits_to_bits[196];
|
||||||
if (1 == 2)
|
|
||||||
{
|
|
||||||
//fprintf (stderr, "\n Raw Trellis Dibits to Bits\n ");
|
|
||||||
for (i = 0; i < 98; i++)
|
|
||||||
{
|
|
||||||
tdibits_to_bits[i * 2] = (tdibits[i] >> 0) & 1;
|
|
||||||
tdibits_to_bits[(i * 2) + 1] = (tdibits[1] >> 1) & 1;
|
|
||||||
//fprintf (stderr, "%d%d", tdibits_to_bits[i * 2], tdibits_to_bits[(i * 2) + 1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//fprintf (stderr, "\n Raw Trellis Dibits\n ");
|
|
||||||
for (i = 0; i < 98; i++)
|
for (i = 0; i < 98; i++)
|
||||||
{
|
{
|
||||||
//fprintf (stderr, "#%d [%X] ", i, tdibits[i]);
|
|
||||||
tdibits_reverse[97-i] = tdibits[i];
|
tdibits_reverse[97-i] = tdibits[i];
|
||||||
//tdibits_reverse[97-i] = ((tdibits[i] & 1)<<1) | ((tdibits[i] & 2)>>1);
|
|
||||||
//tdibits_inverted[i] = tdibits[i] ^ 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned char TrellisReturn[18];
|
unsigned char TrellisReturn[18];
|
||||||
//CDMRTrellisDecode(tdibits, TrellisReturn); //figure out how this works!!
|
|
||||||
CDMRTrellisDecode(tdibits_reverse, TrellisReturn); //NEEDS REVERSE DIBITS!
|
CDMRTrellisDecode(tdibits_reverse, TrellisReturn); //NEEDS REVERSE DIBITS!
|
||||||
|
|
||||||
/* Extract the BPTC 196,96 DMR data */
|
|
||||||
//IrrecoverableErrors = BPTC_196x96_Extract_Data(DeInteleavedData, DmrDataBit, R);
|
|
||||||
//
|
|
||||||
//CDMRTrellisDibitsToPoints(const signed char* dibits, unsigned char* points) ??
|
|
||||||
//
|
|
||||||
/* Fill the reserved bit (R(0)-R(2) of the BPTC(196,96) block) */
|
|
||||||
//BPTCReservedBits = (R[0] & 0x01) | ((R[1] << 1) & 0x02) | ((R[2] << 2) & 0x08);
|
|
||||||
|
|
||||||
for(i = 0, j = 0; i < 18; i++, j+=8)
|
for(i = 0, j = 0; i < 18; i++, j+=8)
|
||||||
{
|
{
|
||||||
DmrDataBit[j + 0] = (TrellisReturn[i] >> 7) & 0x01;
|
DmrDataBit[j + 0] = (TrellisReturn[i] >> 7) & 0x01;
|
||||||
|
|
@ -134,28 +97,12 @@ void Process34Data(dsd_opts * opts, dsd_state * state, unsigned char tdibits[98]
|
||||||
DmrDataBit[j + 7] = (TrellisReturn[i] >> 0) & 0x01;
|
DmrDataBit[j + 7] = (TrellisReturn[i] >> 0) & 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
//the reverse card
|
|
||||||
/*
|
|
||||||
for(i = 0, j = 0; i < 18; i++, j+=8)
|
|
||||||
{
|
|
||||||
DmrDataBit[j + 0] = (TrellisReturn[17-i] >> 0) & 0x01;
|
|
||||||
DmrDataBit[j + 1] = (TrellisReturn[17-i] >> 1) & 0x01;
|
|
||||||
DmrDataBit[j + 2] = (TrellisReturn[17-i] >> 2) & 0x01;
|
|
||||||
DmrDataBit[j + 3] = (TrellisReturn[17-i] >> 3) & 0x01;
|
|
||||||
DmrDataBit[j + 4] = (TrellisReturn[17-i] >> 4) & 0x01;
|
|
||||||
DmrDataBit[j + 5] = (TrellisReturn[17-i] >> 5) & 0x01;
|
|
||||||
DmrDataBit[j + 6] = (TrellisReturn[17-i] >> 6) & 0x01;
|
|
||||||
DmrDataBit[j + 7] = (TrellisReturn[17-i] >> 7) & 0x01;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/* Convert the 96 bit of voice LC Header data into 12 bytes */
|
|
||||||
|
|
||||||
//define our block and padding values
|
//define our block and padding values
|
||||||
uint8_t blocks = state->data_header_blocks[slot] - 1; //subtract 1 for the relevant value in the calc below
|
uint8_t blocks = state->data_header_blocks[slot] - 1; //subtract 1 for the relevant value in the calc below
|
||||||
uint8_t padding = state->data_header_padding[slot];
|
uint8_t padding = state->data_header_padding[slot];
|
||||||
|
|
||||||
//shift data in the superframe up a block
|
//shift data in the superframe up a block
|
||||||
k = 0; //is this still used?
|
k = 0;
|
||||||
for(i = 0; i < 16; i++) //16, or 18? seems to have two extra bytes in front currently
|
for(i = 0; i < 16; i++) //16, or 18? seems to have two extra bytes in front currently
|
||||||
{
|
{
|
||||||
state->dmr_34_rate_sf[slot][i] = state->dmr_34_rate_sf[slot][i+16];
|
state->dmr_34_rate_sf[slot][i] = state->dmr_34_rate_sf[slot][i+16];
|
||||||
|
|
@ -168,7 +115,6 @@ void Process34Data(dsd_opts * opts, dsd_state * state, unsigned char tdibits[98]
|
||||||
for(j = 0; j < 8; j++)
|
for(j = 0; j < 8; j++)
|
||||||
{
|
{
|
||||||
DmrDataByte[i] = DmrDataByte[i] << 1;
|
DmrDataByte[i] = DmrDataByte[i] << 1;
|
||||||
//DmrDataByte[i] = DmrDataByte[i] | (DmrDataBit[k] & 0x01);
|
|
||||||
DmrDataByte[i] = DmrDataByte[i] | (DmrDataBit[k] & 0x01);
|
DmrDataByte[i] = DmrDataByte[i] | (DmrDataBit[k] & 0x01);
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
|
|
@ -182,8 +128,6 @@ void Process34Data(dsd_opts * opts, dsd_state * state, unsigned char tdibits[98]
|
||||||
int message_legnth = 0;
|
int message_legnth = 0;
|
||||||
if ( (state->dmr_34_rate_sf[slot][0] & 0x7F) == 0x45) //Start LRRP now
|
if ( (state->dmr_34_rate_sf[slot][0] & 0x7F) == 0x45) //Start LRRP now
|
||||||
{
|
{
|
||||||
//test opening a file with fopen and dumping the LRRP data into it.
|
|
||||||
//just going to use the same code from EDACS-FM
|
|
||||||
|
|
||||||
//find user home directory and append directory and filename.
|
//find user home directory and append directory and filename.
|
||||||
FILE * pFile; //put this outside of the if statement?
|
FILE * pFile; //put this outside of the if statement?
|
||||||
|
|
@ -201,7 +145,6 @@ void Process34Data(dsd_opts * opts, dsd_state * state, unsigned char tdibits[98]
|
||||||
//hard code filename override for those wanting to use other software
|
//hard code filename override for those wanting to use other software
|
||||||
//pFile = fopen("DSDPlus.LRRP", "a");
|
//pFile = fopen("DSDPlus.LRRP", "a");
|
||||||
|
|
||||||
|
|
||||||
fprintf (pFile, "%s\t %s\t", getDateL(), getTimeL()); //current timestamp, may find a way to only add this IF no included timestamp in LRRP data?
|
fprintf (pFile, "%s\t %s\t", getDateL(), getTimeL()); //current timestamp, may find a way to only add this IF no included timestamp in LRRP data?
|
||||||
fprintf (pFile, "%08lld\t", state->dmr_lrrp_source[state->currentslot]); //source address from data header
|
fprintf (pFile, "%08lld\t", state->dmr_lrrp_source[state->currentslot]); //source address from data header
|
||||||
}
|
}
|
||||||
|
|
@ -363,7 +306,7 @@ void Process34Data(dsd_opts * opts, dsd_state * state, unsigned char tdibits[98]
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s",KGRN);
|
fprintf (stderr, "%s",KGRN);
|
||||||
fprintf (stderr, "\n Rate 3/4 Superframe - Slot [%d]\n ",slot+1);
|
fprintf (stderr, "\n Rate 3/4 Superframe - Slot [%d]\n ",slot+1);
|
||||||
for (i = 0; i < (16*4); i++) //16, or 18?
|
for (i = 0; i < ((blocks+1)*16); i++) //(16*4), using 16 since we jump the first two bytes
|
||||||
{
|
{
|
||||||
fprintf (stderr, "[%02X]", state->dmr_34_rate_sf[slot][i]);
|
fprintf (stderr, "[%02X]", state->dmr_34_rate_sf[slot][i]);
|
||||||
if (i == 15 || i == 31 || i == 47 || i == 63 || i == 79)
|
if (i == 15 || i == 31 || i == 47 || i == 63 || i == 79)
|
||||||
|
|
@ -376,7 +319,7 @@ void Process34Data(dsd_opts * opts, dsd_state * state, unsigned char tdibits[98]
|
||||||
state->data_block_counter[state->currentslot]++; //increment block counter
|
state->data_block_counter[state->currentslot]++; //increment block counter
|
||||||
}
|
}
|
||||||
|
|
||||||
//This is Data Header, why did I name it Data Data
|
//This is Data Header
|
||||||
void ProcessDataData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20])
|
void ProcessDataData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20])
|
||||||
{
|
{
|
||||||
short int slot = 0;
|
short int slot = 0;
|
||||||
|
|
@ -384,12 +327,12 @@ void ProcessDataData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint
|
||||||
|
|
||||||
//see if we still need this portion if we are going to use the data block info
|
//see if we still need this portion if we are going to use the data block info
|
||||||
//clear out the 3/4 rate data superframe so we don't repeat old info
|
//clear out the 3/4 rate data superframe so we don't repeat old info
|
||||||
for (short int i = 0; i < (16*6); i++)
|
for (short int i = 0; i < 288; i++) //expanded to 288 to prevent crashing
|
||||||
{
|
{
|
||||||
state->dmr_34_rate_sf[slot][i] = 0;
|
state->dmr_34_rate_sf[slot][i] = 0;
|
||||||
}
|
}
|
||||||
//clear out the 1/2 rate data superframe so we don't repeat old info
|
//clear out the 1/2 rate data superframe so we don't repeat old info
|
||||||
for (short int i = 0; i < (12*5); i++) //12*5 = 60
|
for (short int i = 0; i < 288; i++) //expanded to 288 to prevent crashing
|
||||||
{
|
{
|
||||||
state->dmr_12_rate_sf[slot][i] = 0;
|
state->dmr_12_rate_sf[slot][i] = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -407,13 +350,6 @@ void ProcessDataData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint
|
||||||
uint8_t R[3];
|
uint8_t R[3];
|
||||||
uint8_t BPTCReservedBits = 0;
|
uint8_t BPTCReservedBits = 0;
|
||||||
|
|
||||||
// Extract parameters for logging purposes
|
|
||||||
uint8_t csbk_lb = 0;
|
|
||||||
uint8_t csbk_pf = 0;
|
|
||||||
uint8_t csbk_o = 0;
|
|
||||||
uint8_t csbk_fid = 0;
|
|
||||||
uint64_t csbk_data = 0;
|
|
||||||
uint8_t csbk = 0;
|
|
||||||
|
|
||||||
/* Check the current time slot */
|
/* Check the current time slot */
|
||||||
if(state->currentslot == 0)
|
if(state->currentslot == 0)
|
||||||
|
|
@ -453,23 +389,17 @@ void ProcessDataData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint
|
||||||
|
|
||||||
/* Fill the CRC extracted (before Reed-Solomon (12,9) FEC correction) */
|
/* Fill the CRC extracted (before Reed-Solomon (12,9) FEC correction) */
|
||||||
CRCExtracted = 0;
|
CRCExtracted = 0;
|
||||||
//for(i = 0; i < 24; i++)
|
|
||||||
for(i = 0; i < 16; i++)
|
for(i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
CRCExtracted = CRCExtracted << 1;
|
CRCExtracted = CRCExtracted << 1;
|
||||||
//CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 72] & 1);
|
CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 80] & 1);
|
||||||
CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 80] & 1); //80-96 for PI header
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Look into whether or not we need to run these CRC checks for this header information
|
|
||||||
//and see if its applied the same or differently
|
|
||||||
/* Apply the CRC mask (see DMR standard B.3.12 Data Type CRC Mask) */
|
/* Apply the CRC mask (see DMR standard B.3.12 Data Type CRC Mask) */
|
||||||
//CRCExtracted = CRCExtracted ^ 0x969696; //does this mask get applied here though for PI?
|
|
||||||
CRCExtracted = CRCExtracted ^ 0xCCCC;
|
CRCExtracted = CRCExtracted ^ 0xCCCC;
|
||||||
|
|
||||||
/* Check/correct the full link control data and compute the Reed-Solomon (12,9) CRC */
|
/* Check/correct the full link control data and compute the Reed-Solomon (12,9) CRC */
|
||||||
CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0xCCCC);
|
CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0xCCCC);
|
||||||
//CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0x6969);
|
|
||||||
|
|
||||||
/* Convert corrected 12 bytes into 96 bits */
|
/* Convert corrected 12 bytes into 96 bits */
|
||||||
for(i = 0, j = 0; i < 12; i++, j+=8)
|
for(i = 0, j = 0; i < 12; i++, j+=8)
|
||||||
|
|
@ -686,116 +616,97 @@ void Process1Data(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t
|
||||||
uint32_t IrrecoverableErrors = 0;
|
uint32_t IrrecoverableErrors = 0;
|
||||||
uint8_t DeInteleavedData[196];
|
uint8_t DeInteleavedData[196];
|
||||||
uint8_t DmrDataBit[96];
|
uint8_t DmrDataBit[96];
|
||||||
uint8_t DmrDataByte[12];
|
uint8_t DmrDataByte[25];
|
||||||
TimeSlotVoiceSuperFrame_t * TSVoiceSupFrame = NULL;
|
TimeSlotVoiceSuperFrame_t * TSVoiceSupFrame = NULL;
|
||||||
uint8_t R[3];
|
uint8_t R[3];
|
||||||
uint8_t BPTCReservedBits = 0;
|
uint8_t BPTCReservedBits = 0;
|
||||||
|
short int slot = 0;
|
||||||
|
slot = (short int)state->currentslot;
|
||||||
|
|
||||||
// Extract parameters for logging purposes
|
//define our block and padding values
|
||||||
uint8_t csbk_lb = 0;
|
uint8_t blocks = state->data_header_blocks[slot] - 1; //subtract 1 for the relevant value in the calc below
|
||||||
uint8_t csbk_pf = 0;
|
uint8_t padding = state->data_header_padding[slot];
|
||||||
uint8_t csbk_o = 0;
|
//shift data in the superframe up a block
|
||||||
uint8_t csbk_fid = 0;
|
|
||||||
uint64_t csbk_data = 0;
|
|
||||||
uint8_t csbk = 0;
|
|
||||||
|
|
||||||
/* Check the current time slot */
|
|
||||||
if(state->currentslot == 0)
|
|
||||||
{
|
|
||||||
TSVoiceSupFrame = &state->TS1SuperFrame;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TSVoiceSupFrame = &state->TS2SuperFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
CRCExtracted = 0;
|
|
||||||
CRCComputed = 0;
|
|
||||||
IrrecoverableErrors = 0;
|
|
||||||
|
|
||||||
/* Deinterleave DMR data */
|
|
||||||
BPTCDeInterleaveDMRData(info, DeInteleavedData);
|
|
||||||
|
|
||||||
/* Extract the BPTC 196,96 DMR data */
|
|
||||||
IrrecoverableErrors = BPTC_196x96_Extract_Data(DeInteleavedData, DmrDataBit, R);
|
|
||||||
|
|
||||||
/* Fill the reserved bit (R(0)-R(2) of the BPTC(196,96) block) */
|
|
||||||
BPTCReservedBits = (R[0] & 0x01) | ((R[1] << 1) & 0x02) | ((R[2] << 2) & 0x08);
|
|
||||||
|
|
||||||
/* Convert the 96 bit of voice LC Header data into 12 bytes */
|
|
||||||
k = 0;
|
k = 0;
|
||||||
for(i = 0; i < 12; i++)
|
for(i = 0; i < 24; i++)
|
||||||
{
|
{
|
||||||
|
//reuse dmr_12_rate_sf since 12, we can use 2 blocks to load 1 block here
|
||||||
|
state->dmr_12_rate_sf[slot][i] = state->dmr_12_rate_sf[slot][i+24]; //shift block 2 to block 1
|
||||||
|
state->dmr_12_rate_sf[slot][i+24] = state->dmr_12_rate_sf[slot][i+48]; //shift block 3 to block 2
|
||||||
|
state->dmr_12_rate_sf[slot][i+48] = state->dmr_12_rate_sf[slot][i+72]; //shift block 3 to block 2
|
||||||
DmrDataByte[i] = 0;
|
DmrDataByte[i] = 0;
|
||||||
for(j = 0; j < 8; j++)
|
for(j = 0; j < 8; j++)
|
||||||
{
|
{
|
||||||
DmrDataByte[i] = DmrDataByte[i] << 1;
|
DmrDataByte[i] = DmrDataByte[i] << 1;
|
||||||
DmrDataByte[i] = DmrDataByte[i] | (DmrDataBit[k] & 0x01);
|
DmrDataByte[i] = DmrDataByte[i] | (info[k] ); //& 1
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//start loading new superframe at appropriate block count determined by the data header
|
||||||
|
state->dmr_12_rate_sf[slot][i+(blocks*24)] = DmrDataByte[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//need to rework this for rate 1 data, will be a crc 9 for each confirmed block,
|
||||||
|
//and/or CRC 32 on last block (full superframe)
|
||||||
|
//NOTE 2: Only used when CRC-9 present in burst.
|
||||||
|
|
||||||
/* Fill the CRC extracted (before Reed-Solomon (12,9) FEC correction) */
|
/* Fill the CRC extracted (before Reed-Solomon (12,9) FEC correction) */
|
||||||
CRCExtracted = 0;
|
// CRCExtracted = 0;
|
||||||
//for(i = 0; i < 24; i++)
|
// //for(i = 0; i < 24; i++)
|
||||||
for(i = 0; i < 16; i++)
|
// for(i = 0; i < 16; i++)
|
||||||
{
|
// {
|
||||||
CRCExtracted = CRCExtracted << 1;
|
// CRCExtracted = CRCExtracted << 1;
|
||||||
//CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 72] & 1);
|
// //CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 72] & 1);
|
||||||
CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 80] & 1); //80-96 for PI header
|
// CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 80] & 1);
|
||||||
}
|
// }
|
||||||
|
|
||||||
//Look into whether or not we need to run these CRC checks for this header information
|
|
||||||
//and see if its applied the same or differently
|
|
||||||
/* Apply the CRC mask (see DMR standard B.3.12 Data Type CRC Mask) */
|
|
||||||
//CRCExtracted = CRCExtracted ^ 0x969696; //does this mask get applied here though for PI?
|
|
||||||
//CRCExtracted = CRCExtracted ^ 0x6969;
|
//CRCExtracted = CRCExtracted ^ 0x6969;
|
||||||
|
|
||||||
/* Check/correct the full link control data and compute the Reed-Solomon (12,9) CRC */
|
/* Check/correct the full link control data and compute the Reed-Solomon (12,9) CRC */
|
||||||
//CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0x969696);
|
//CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0x969696);
|
||||||
//CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0x6969);
|
|
||||||
|
|
||||||
/* Convert corrected 12 bytes into 96 bits */
|
|
||||||
for(i = 0, j = 0; i < 12; i++, j+=8)
|
|
||||||
{
|
|
||||||
DmrDataBit[j + 0] = (DmrDataByte[i] >> 7) & 0x01;
|
|
||||||
DmrDataBit[j + 1] = (DmrDataByte[i] >> 6) & 0x01;
|
|
||||||
DmrDataBit[j + 2] = (DmrDataByte[i] >> 5) & 0x01;
|
|
||||||
DmrDataBit[j + 3] = (DmrDataByte[i] >> 4) & 0x01;
|
|
||||||
DmrDataBit[j + 4] = (DmrDataByte[i] >> 3) & 0x01;
|
|
||||||
DmrDataBit[j + 5] = (DmrDataByte[i] >> 2) & 0x01;
|
|
||||||
DmrDataBit[j + 6] = (DmrDataByte[i] >> 1) & 0x01;
|
|
||||||
DmrDataBit[j + 7] = (DmrDataByte[i] >> 0) & 0x01;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
if (DmrDataByte[0] == 0x43)
|
|
||||||
{
|
|
||||||
//fprintf (stderr, "\n IP4 Source IP:");
|
|
||||||
//fprintf (stderr, " %d", (DmrDataByte[2] <<16 ) + (DmrDataByte[3] << 8) + DmrDataByte[4] );
|
|
||||||
//fprintf (stderr, " Destination IP:");
|
|
||||||
//fprintf (stderr, " %d", (DmrDataByte[5] <<16 ) + (DmrDataByte[6] <<8 ) + DmrDataByte[7] );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DmrDataByte[0] == 0x01)
|
|
||||||
{
|
|
||||||
//fprintf (stderr, "\n LRRP Control ACK - ");
|
|
||||||
//fprintf (stderr, " Source:");
|
|
||||||
//fprintf (stderr, " %d", (DmrDataByte[2] <<16 ) + (DmrDataByte[3] << 8) + DmrDataByte[4] );
|
|
||||||
//fprintf (stderr, " Destination:");
|
|
||||||
//fprintf (stderr, " %d", (DmrDataByte[5] <<16 ) + (DmrDataByte[6] <<8 ) + DmrDataByte[7] );
|
|
||||||
}
|
|
||||||
//Full
|
//Full
|
||||||
if (opts->payload == 1)
|
if (opts->payload == 1)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s", KCYN);
|
fprintf (stderr, "%s", KCYN);
|
||||||
fprintf (stderr, "\nFull Rate 1 Payload ");
|
fprintf (stderr, "\nFull Rate 1 Payload \n");
|
||||||
for (i = 0; i < 12; i++)
|
for (i = 0; i < 24; i++)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "[%02X]", DmrDataByte[i]);
|
fprintf (stderr, "[%02X]", DmrDataByte[i]);
|
||||||
|
if (i == 11)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf (stderr, "\n Hex to Ascii - ");
|
||||||
|
for (i = 0; i < 24; i++)
|
||||||
|
{
|
||||||
|
if (DmrDataByte[i] <= 0x7E && DmrDataByte[i] >=0x20)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%c", DmrDataByte[i]);
|
||||||
|
}
|
||||||
|
else fprintf (stderr, ".");
|
||||||
}
|
}
|
||||||
fprintf (stderr, "%s", KNRM);
|
fprintf (stderr, "%s", KNRM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Full Super Frame - Debug Output
|
||||||
|
if (opts->payload == 1 && state->data_block_counter[state->currentslot] == state->data_header_blocks[state->currentslot])
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s",KGRN);
|
||||||
|
fprintf (stderr, "\n Rate 1 Superframe - Slot [%d]\n ",slot+1);
|
||||||
|
for (i = 0; i < ((blocks+1)*24); i++) //only print as many as we have blocks
|
||||||
|
{
|
||||||
|
fprintf (stderr, "[%02X]", state->dmr_12_rate_sf[slot][i]);
|
||||||
|
if (i == 11 || i == 23 || i == 35 || i == 47 || i == 59 || i == 71) //line break and two spaces after each 12 bytes
|
||||||
|
{
|
||||||
|
fprintf (stderr, "\n ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf (stderr, "%s ", KNRM);
|
||||||
|
}
|
||||||
|
state->data_block_counter[state->currentslot]++; //increment block counter
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessMBChData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20])
|
void ProcessMBChData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20])
|
||||||
|
|
@ -813,14 +724,6 @@ void ProcessMBChData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint
|
||||||
uint8_t R[3];
|
uint8_t R[3];
|
||||||
uint8_t BPTCReservedBits = 0;
|
uint8_t BPTCReservedBits = 0;
|
||||||
|
|
||||||
// Extract parameters for logging purposes
|
|
||||||
uint8_t csbk_lb = 0;
|
|
||||||
uint8_t csbk_pf = 0;
|
|
||||||
uint8_t csbk_o = 0;
|
|
||||||
uint8_t csbk_fid = 0;
|
|
||||||
uint64_t csbk_data = 0;
|
|
||||||
uint8_t csbk = 0;
|
|
||||||
|
|
||||||
/* Check the current time slot */
|
/* Check the current time slot */
|
||||||
if(state->currentslot == 0)
|
if(state->currentslot == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -859,22 +762,16 @@ void ProcessMBChData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint
|
||||||
|
|
||||||
/* Fill the CRC extracted (before Reed-Solomon (12,9) FEC correction) */
|
/* Fill the CRC extracted (before Reed-Solomon (12,9) FEC correction) */
|
||||||
CRCExtracted = 0;
|
CRCExtracted = 0;
|
||||||
//for(i = 0; i < 24; i++)
|
|
||||||
for(i = 0; i < 16; i++)
|
for(i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
CRCExtracted = CRCExtracted << 1;
|
CRCExtracted = CRCExtracted << 1;
|
||||||
//CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 72] & 1);
|
CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 80] & 1);
|
||||||
CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 80] & 1); //80-96 for PI header
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Look into whether or not we need to run these CRC checks for this header information
|
|
||||||
//and see if its applied the same or differently
|
|
||||||
/* Apply the CRC mask (see DMR standard B.3.12 Data Type CRC Mask) */
|
/* Apply the CRC mask (see DMR standard B.3.12 Data Type CRC Mask) */
|
||||||
//CRCExtracted = CRCExtracted ^ 0x969696; //does this mask get applied here though for PI?
|
|
||||||
CRCExtracted = CRCExtracted ^ 0xAAAA;
|
CRCExtracted = CRCExtracted ^ 0xAAAA;
|
||||||
|
|
||||||
/* Check/correct the full link control data and compute the Reed-Solomon (12,9) CRC */
|
/* Check/correct the full link control data and compute the Reed-Solomon (12,9) CRC */
|
||||||
//CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0x969696);
|
|
||||||
CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0xAAAA);
|
CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0xAAAA);
|
||||||
|
|
||||||
/* Convert corrected 12 bytes into 96 bits */
|
/* Convert corrected 12 bytes into 96 bits */
|
||||||
|
|
@ -889,23 +786,7 @@ void ProcessMBChData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint
|
||||||
DmrDataBit[j + 6] = (DmrDataByte[i] >> 1) & 0x01;
|
DmrDataBit[j + 6] = (DmrDataByte[i] >> 1) & 0x01;
|
||||||
DmrDataBit[j + 7] = (DmrDataByte[i] >> 0) & 0x01;
|
DmrDataBit[j + 7] = (DmrDataByte[i] >> 0) & 0x01;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
if (DmrDataByte[0] == 0x43)
|
|
||||||
{
|
|
||||||
//fprintf (stderr, "\n IP4 Source IP:");
|
|
||||||
//fprintf (stderr, " %d", (DmrDataByte[2] <<16 ) + (DmrDataByte[3] << 8) + DmrDataByte[4] );
|
|
||||||
//fprintf (stderr, " Destination IP:");
|
|
||||||
//fprintf (stderr, " %d", (DmrDataByte[5] <<16 ) + (DmrDataByte[6] <<8 ) + DmrDataByte[7] );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DmrDataByte[0] == 0x01)
|
|
||||||
{
|
|
||||||
//fprintf (stderr, "\n LRRP Control ACK - ");
|
|
||||||
//fprintf (stderr, " Source:");
|
|
||||||
//fprintf (stderr, " %d", (DmrDataByte[2] <<16 ) + (DmrDataByte[3] << 8) + DmrDataByte[4] );
|
|
||||||
//fprintf (stderr, " Destination:");
|
|
||||||
//fprintf (stderr, " %d", (DmrDataByte[5] <<16 ) + (DmrDataByte[6] <<8 ) + DmrDataByte[7] );
|
|
||||||
}
|
|
||||||
//Full
|
//Full
|
||||||
if (opts->payload == 1)
|
if (opts->payload == 1)
|
||||||
{
|
{
|
||||||
|
|
@ -935,14 +816,6 @@ void ProcessMBCData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8
|
||||||
uint8_t R[3];
|
uint8_t R[3];
|
||||||
uint8_t BPTCReservedBits = 0;
|
uint8_t BPTCReservedBits = 0;
|
||||||
|
|
||||||
// Extract parameters for logging purposes
|
|
||||||
uint8_t csbk_lb = 0;
|
|
||||||
uint8_t csbk_pf = 0;
|
|
||||||
uint8_t csbk_o = 0;
|
|
||||||
uint8_t csbk_fid = 0;
|
|
||||||
uint64_t csbk_data = 0;
|
|
||||||
uint8_t csbk = 0;
|
|
||||||
|
|
||||||
/* Check the current time slot */
|
/* Check the current time slot */
|
||||||
if(state->currentslot == 0)
|
if(state->currentslot == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -979,25 +852,24 @@ void ProcessMBCData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill the CRC extracted (before Reed-Solomon (12,9) FEC correction) */
|
//NO CRC or FEC on MBC Cont. Data?
|
||||||
CRCExtracted = 0;
|
//...that seems to be according to the manual
|
||||||
//for(i = 0; i < 24; i++)
|
|
||||||
for(i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
CRCExtracted = CRCExtracted << 1;
|
|
||||||
//CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 72] & 1);
|
|
||||||
CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 80] & 1); //80-96 for PI header
|
|
||||||
}
|
|
||||||
|
|
||||||
//Look into whether or not we need to run these CRC checks for this header information
|
/* Fill the CRC extracted (before Reed-Solomon (12,9) FEC correction) */
|
||||||
//and see if its applied the same or differently
|
// CRCExtracted = 0;
|
||||||
|
// for(i = 0; i < 16; i++)
|
||||||
|
// {
|
||||||
|
// CRCExtracted = CRCExtracted << 1;
|
||||||
|
// CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 80] & 1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
//No CRC Mask for MBC Continuation Data
|
||||||
|
//Note 1. None required for intermediate or last blocks.
|
||||||
/* Apply the CRC mask (see DMR standard B.3.12 Data Type CRC Mask) */
|
/* Apply the CRC mask (see DMR standard B.3.12 Data Type CRC Mask) */
|
||||||
//CRCExtracted = CRCExtracted ^ 0x969696; //does this mask get applied here though for PI?
|
|
||||||
//CRCExtracted = CRCExtracted ^ 0x6969;
|
//CRCExtracted = CRCExtracted ^ 0x6969;
|
||||||
|
|
||||||
/* Check/correct the full link control data and compute the Reed-Solomon (12,9) CRC */
|
/* Check/correct the full link control data and compute the Reed-Solomon (12,9) CRC */
|
||||||
//CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0x969696);
|
// CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0x0); //0, or FFFF?
|
||||||
//CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0x6969);
|
|
||||||
|
|
||||||
/* Convert corrected 12 bytes into 96 bits */
|
/* Convert corrected 12 bytes into 96 bits */
|
||||||
for(i = 0, j = 0; i < 12; i++, j+=8)
|
for(i = 0, j = 0; i < 12; i++, j+=8)
|
||||||
|
|
@ -1011,28 +883,12 @@ void ProcessMBCData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8
|
||||||
DmrDataBit[j + 6] = (DmrDataByte[i] >> 1) & 0x01;
|
DmrDataBit[j + 6] = (DmrDataByte[i] >> 1) & 0x01;
|
||||||
DmrDataBit[j + 7] = (DmrDataByte[i] >> 0) & 0x01;
|
DmrDataBit[j + 7] = (DmrDataByte[i] >> 0) & 0x01;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
if (DmrDataByte[0] == 0x43)
|
|
||||||
{
|
|
||||||
//fprintf (stderr, "\n IP4 Source IP:");
|
|
||||||
//fprintf (stderr, " %d", (DmrDataByte[2] <<16 ) + (DmrDataByte[3] << 8) + DmrDataByte[4] );
|
|
||||||
//fprintf (stderr, " Destination IP:");
|
|
||||||
//fprintf (stderr, " %d", (DmrDataByte[5] <<16 ) + (DmrDataByte[6] <<8 ) + DmrDataByte[7] );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DmrDataByte[0] == 0x01)
|
|
||||||
{
|
|
||||||
//fprintf (stderr, "\n LRRP Control ACK - ");
|
|
||||||
//fprintf (stderr, " Source:");
|
|
||||||
//fprintf (stderr, " %d", (DmrDataByte[2] <<16 ) + (DmrDataByte[3] << 8) + DmrDataByte[4] );
|
|
||||||
//fprintf (stderr, " Destination:");
|
|
||||||
//fprintf (stderr, " %d", (DmrDataByte[5] <<16 ) + (DmrDataByte[6] <<8 ) + DmrDataByte[7] );
|
|
||||||
}
|
|
||||||
//Full
|
//Full
|
||||||
if (opts->payload == 1)
|
if (opts->payload == 1)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s", KCYN);
|
fprintf (stderr, "%s", KCYN);
|
||||||
fprintf (stderr, "\nFull MBC Payload ");
|
fprintf (stderr, "\nFull MBC Continuation Payload ");
|
||||||
for (i = 0; i < 12; i++)
|
for (i = 0; i < 12; i++)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "[%02X]", DmrDataByte[i]);
|
fprintf (stderr, "[%02X]", DmrDataByte[i]);
|
||||||
|
|
@ -1042,7 +898,8 @@ void ProcessMBCData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessWTFData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20])
|
//This data shouldn't be active, but come here to dump in case of data burst type decoding failure
|
||||||
|
void ProcessReservedData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20])
|
||||||
{
|
{
|
||||||
//Placeholder
|
//Placeholder
|
||||||
uint32_t i, j, k;
|
uint32_t i, j, k;
|
||||||
|
|
@ -1057,13 +914,74 @@ void ProcessWTFData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8
|
||||||
uint8_t R[3];
|
uint8_t R[3];
|
||||||
uint8_t BPTCReservedBits = 0;
|
uint8_t BPTCReservedBits = 0;
|
||||||
|
|
||||||
// Extract parameters for logging purposes
|
/* Check the current time slot */
|
||||||
uint8_t csbk_lb = 0;
|
if(state->currentslot == 0)
|
||||||
uint8_t csbk_pf = 0;
|
{
|
||||||
uint8_t csbk_o = 0;
|
TSVoiceSupFrame = &state->TS1SuperFrame;
|
||||||
uint8_t csbk_fid = 0;
|
}
|
||||||
uint64_t csbk_data = 0;
|
else
|
||||||
uint8_t csbk = 0;
|
{
|
||||||
|
TSVoiceSupFrame = &state->TS2SuperFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert the 196 bit of voice LC Header data into 12 bytes */
|
||||||
|
k = 0;
|
||||||
|
for(i = 0; i < 24; i++)
|
||||||
|
{
|
||||||
|
DmrDataByte[i] = 0;
|
||||||
|
for(j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
DmrDataByte[i] = DmrDataByte[i] << 1;
|
||||||
|
DmrDataByte[i] = DmrDataByte[i] | info[i];
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert corrected 12 bytes into 96 bits */
|
||||||
|
for(i = 0, j = 0; i < 12; i++, j+=8)
|
||||||
|
{
|
||||||
|
DmrDataBit[j + 0] = (DmrDataByte[i] >> 7) & 0x01;
|
||||||
|
DmrDataBit[j + 1] = (DmrDataByte[i] >> 6) & 0x01;
|
||||||
|
DmrDataBit[j + 2] = (DmrDataByte[i] >> 5) & 0x01;
|
||||||
|
DmrDataBit[j + 3] = (DmrDataByte[i] >> 4) & 0x01;
|
||||||
|
DmrDataBit[j + 4] = (DmrDataByte[i] >> 3) & 0x01;
|
||||||
|
DmrDataBit[j + 5] = (DmrDataByte[i] >> 2) & 0x01;
|
||||||
|
DmrDataBit[j + 6] = (DmrDataByte[i] >> 1) & 0x01;
|
||||||
|
DmrDataBit[j + 7] = (DmrDataByte[i] >> 0) & 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Full
|
||||||
|
if (opts->payload == 1)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s", KCYN);
|
||||||
|
fprintf (stderr, "\nFull Reserved Payload ");
|
||||||
|
for (i = 0; i < 12; i++)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "[%02X]", DmrDataByte[i]);
|
||||||
|
}
|
||||||
|
fprintf (stderr, "%s", KRED);
|
||||||
|
fprintf (stderr, "\nINFO! This Payload Dump May be caused by erroneous data burst type decoding! ");
|
||||||
|
fprintf (stderr, "%s", KNRM);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessUnifiedData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20])
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t i, j, k;
|
||||||
|
uint32_t CRCExtracted = 0;
|
||||||
|
uint32_t CRCComputed = 0;
|
||||||
|
uint32_t CRCCorrect = 0;
|
||||||
|
uint32_t IrrecoverableErrors = 0;
|
||||||
|
uint8_t DeInteleavedData[196];
|
||||||
|
uint8_t DmrDataBit[96];
|
||||||
|
uint8_t DmrDataByte[12];
|
||||||
|
TimeSlotVoiceSuperFrame_t * TSVoiceSupFrame = NULL;
|
||||||
|
uint8_t R[3];
|
||||||
|
uint8_t BPTCReservedBits = 0;
|
||||||
|
short int slot = 0;
|
||||||
|
slot = (short int)state->currentslot;
|
||||||
|
|
||||||
/* Check the current time slot */
|
/* Check the current time slot */
|
||||||
if(state->currentslot == 0)
|
if(state->currentslot == 0)
|
||||||
|
|
@ -1088,7 +1006,7 @@ void ProcessWTFData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8
|
||||||
/* Fill the reserved bit (R(0)-R(2) of the BPTC(196,96) block) */
|
/* Fill the reserved bit (R(0)-R(2) of the BPTC(196,96) block) */
|
||||||
BPTCReservedBits = (R[0] & 0x01) | ((R[1] << 1) & 0x02) | ((R[2] << 2) & 0x08);
|
BPTCReservedBits = (R[0] & 0x01) | ((R[1] << 1) & 0x02) | ((R[2] << 2) & 0x08);
|
||||||
|
|
||||||
/* Convert the 96 bit of voice LC Header data into 12 bytes */
|
|
||||||
k = 0;
|
k = 0;
|
||||||
for(i = 0; i < 12; i++)
|
for(i = 0; i < 12; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -1099,6 +1017,7 @@ void ProcessWTFData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8
|
||||||
DmrDataByte[i] = DmrDataByte[i] | (DmrDataBit[k] & 0x01);
|
DmrDataByte[i] = DmrDataByte[i] | (DmrDataBit[k] & 0x01);
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill the CRC extracted (before Reed-Solomon (12,9) FEC correction) */
|
/* Fill the CRC extracted (before Reed-Solomon (12,9) FEC correction) */
|
||||||
|
|
@ -1107,19 +1026,32 @@ void ProcessWTFData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8
|
||||||
for(i = 0; i < 16; i++)
|
for(i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
CRCExtracted = CRCExtracted << 1;
|
CRCExtracted = CRCExtracted << 1;
|
||||||
//CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 72] & 1);
|
CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 80] & 1);
|
||||||
CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 80] & 1); //80-96 for PI header
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Look into whether or not we need to run these CRC checks for this header information
|
//Look into whether or not we need to run these CRC checks for this header information
|
||||||
//and see if its applied the same or differently
|
//and see if its applied the same or differently
|
||||||
/* Apply the CRC mask (see DMR standard B.3.12 Data Type CRC Mask) */
|
/* Apply the CRC mask (see DMR standard B.3.12 Data Type CRC Mask) */
|
||||||
//CRCExtracted = CRCExtracted ^ 0x969696; //does this mask get applied here though for PI?
|
CRCExtracted = CRCExtracted ^ 0x3333;
|
||||||
//CRCExtracted = CRCExtracted ^ 0x6969;
|
|
||||||
|
|
||||||
/* Check/correct the full link control data and compute the Reed-Solomon (12,9) CRC */
|
/* Check/correct the full link control data and compute the Reed-Solomon (12,9) CRC */
|
||||||
//CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0x969696);
|
CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0x3333);
|
||||||
//CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0x6969);
|
|
||||||
|
//test
|
||||||
|
if((IrrecoverableErrors == 0) && CRCCorrect)
|
||||||
|
{
|
||||||
|
//fprintf (stderr, "\n(Unified Data CRC Okay)");
|
||||||
|
}
|
||||||
|
else if((IrrecoverableErrors == 0))
|
||||||
|
{
|
||||||
|
//fprintf (stderr, "\n(Unified Data FEC Okay)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s", KRED);
|
||||||
|
fprintf (stderr, ("\n(Unified Rate CRC Fail, FEC Fail)"));
|
||||||
|
fprintf (stderr, "%s", KNRM);
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert corrected 12 bytes into 96 bits */
|
/* Convert corrected 12 bytes into 96 bits */
|
||||||
for(i = 0, j = 0; i < 12; i++, j+=8)
|
for(i = 0, j = 0; i < 12; i++, j+=8)
|
||||||
|
|
@ -1133,38 +1065,30 @@ void ProcessWTFData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8
|
||||||
DmrDataBit[j + 6] = (DmrDataByte[i] >> 1) & 0x01;
|
DmrDataBit[j + 6] = (DmrDataByte[i] >> 1) & 0x01;
|
||||||
DmrDataBit[j + 7] = (DmrDataByte[i] >> 0) & 0x01;
|
DmrDataBit[j + 7] = (DmrDataByte[i] >> 0) & 0x01;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
if (DmrDataByte[0] == 0x43)
|
|
||||||
{
|
|
||||||
//fprintf (stderr, "\n IP4 Source IP:");
|
|
||||||
//fprintf (stderr, " %d", (DmrDataByte[2] <<16 ) + (DmrDataByte[3] << 8) + DmrDataByte[4] );
|
|
||||||
//fprintf (stderr, " Destination IP:");
|
|
||||||
//fprintf (stderr, " %d", (DmrDataByte[5] <<16 ) + (DmrDataByte[6] <<8 ) + DmrDataByte[7] );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DmrDataByte[0] == 0x01)
|
|
||||||
{
|
|
||||||
//fprintf (stderr, "\n LRRP Control ACK - ");
|
|
||||||
//fprintf (stderr, " Source:");
|
|
||||||
//fprintf (stderr, " %d", (DmrDataByte[2] <<16 ) + (DmrDataByte[3] << 8) + DmrDataByte[4] );
|
|
||||||
//fprintf (stderr, " Destination:");
|
|
||||||
//fprintf (stderr, " %d", (DmrDataByte[5] <<16 ) + (DmrDataByte[6] <<8 ) + DmrDataByte[7] );
|
|
||||||
}
|
|
||||||
//Full
|
//Full
|
||||||
if (opts->payload == 1)
|
if (opts->payload == 1)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s", KCYN);
|
fprintf (stderr,"%s", KCYN);
|
||||||
fprintf (stderr, "\nFull WTF Payload ");
|
fprintf (stderr, "\n Full Unified Data Payload ");
|
||||||
for (i = 0; i < 12; i++)
|
for (i = 0; i < 12; i++)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "[%02X]", DmrDataByte[i]);
|
fprintf (stderr, "[%02X]", DmrDataByte[i]);
|
||||||
}
|
}
|
||||||
fprintf (stderr, "%s", KNRM);
|
fprintf (stderr, "\n Hex to Ascii - ");
|
||||||
|
for (i = 0; i < 12; i++)
|
||||||
|
{
|
||||||
|
if (DmrDataByte[i] <= 0x7E && DmrDataByte[i] >=0x20)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%c", DmrDataByte[i]);
|
||||||
|
}
|
||||||
|
else fprintf (stderr, ".");
|
||||||
|
}
|
||||||
|
fprintf (stderr,"%s", KNRM);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Process12Data(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20])
|
void Process12Data(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20])
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -1232,23 +1156,17 @@ void Process12Data(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_
|
||||||
|
|
||||||
/* Fill the CRC extracted (before Reed-Solomon (12,9) FEC correction) */
|
/* Fill the CRC extracted (before Reed-Solomon (12,9) FEC correction) */
|
||||||
CRCExtracted = 0;
|
CRCExtracted = 0;
|
||||||
//for(i = 0; i < 24; i++)
|
for(i = 0; i < 24; i++)
|
||||||
for(i = 0; i < 16; i++)
|
|
||||||
{
|
{
|
||||||
CRCExtracted = CRCExtracted << 1;
|
CRCExtracted = CRCExtracted << 1;
|
||||||
CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 72] & 1);
|
CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 72] & 1);
|
||||||
//CRCExtracted = CRCExtracted | (uint32_t)(DmrDataBit[i + 80] & 1); //80-96 for PI header
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Look into whether or not we need to run these CRC checks for this header information
|
|
||||||
//and see if its applied the same or differently
|
|
||||||
/* Apply the CRC mask (see DMR standard B.3.12 Data Type CRC Mask) */
|
/* Apply the CRC mask (see DMR standard B.3.12 Data Type CRC Mask) */
|
||||||
CRCExtracted = CRCExtracted ^ 0x969696; //does this mask get applied here though for PI?
|
CRCExtracted = CRCExtracted ^ 0x969696; //does this mask get applied here though for PI?
|
||||||
//CRCExtracted = CRCExtracted ^ 0x6969;
|
|
||||||
|
|
||||||
/* Check/correct the full link control data and compute the Reed-Solomon (12,9) CRC */
|
/* Check/correct the full link control data and compute the Reed-Solomon (12,9) CRC */
|
||||||
CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0x969696);
|
CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0x969696);
|
||||||
//CRCCorrect = ComputeAndCorrectFullLinkControlCrc(DmrDataByte, &CRCComputed, 0x6969);
|
|
||||||
|
|
||||||
//test
|
//test
|
||||||
if((IrrecoverableErrors == 0) && CRCCorrect)
|
if((IrrecoverableErrors == 0) && CRCCorrect)
|
||||||
|
|
@ -1466,7 +1384,7 @@ void Process12Data(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_
|
||||||
for (i = 0; i < ((blocks+1)*12); i++) //only print as many as we have blocks
|
for (i = 0; i < ((blocks+1)*12); i++) //only print as many as we have blocks
|
||||||
{
|
{
|
||||||
fprintf (stderr, "[%02X]", state->dmr_12_rate_sf[slot][i]);
|
fprintf (stderr, "[%02X]", state->dmr_12_rate_sf[slot][i]);
|
||||||
if (i == 11 || i == 23 || i == 35 || i == 47 || i == 59 || i == 71) //line break and two spaces after each 16 bytes
|
if (i == 11 || i == 23 || i == 35 || i == 47 || i == 59 || i == 71) //line break and two spaces after each 12 bytes
|
||||||
{
|
{
|
||||||
fprintf (stderr, "\n ");
|
fprintf (stderr, "\n ");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -153,14 +153,14 @@ noCarrier (dsd_opts * opts, dsd_state * state)
|
||||||
state->dmr_lrrp_source[1] = 0;
|
state->dmr_lrrp_source[1] = 0;
|
||||||
|
|
||||||
//initialize 12 rate superframe
|
//initialize 12 rate superframe
|
||||||
for (short i = 0; i < 84; i++)
|
for (short i = 0; i < 288; i++)
|
||||||
{
|
{
|
||||||
state->dmr_12_rate_sf[0][i] = 0;
|
state->dmr_12_rate_sf[0][i] = 0;
|
||||||
state->dmr_12_rate_sf[1][i] = 0;
|
state->dmr_12_rate_sf[1][i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//initialize 34 rate superframe
|
//initialize 34 rate superframe
|
||||||
for (short i = 0; i < 96; i++)
|
for (short i = 0; i < 288; i++)
|
||||||
{
|
{
|
||||||
state->dmr_34_rate_sf[0][i] = 0;
|
state->dmr_34_rate_sf[0][i] = 0;
|
||||||
state->dmr_34_rate_sf[1][i] = 0;
|
state->dmr_34_rate_sf[1][i] = 0;
|
||||||
|
|
@ -488,14 +488,14 @@ initState (dsd_state * state)
|
||||||
state->dmr_lrrp_source[1] = 0;
|
state->dmr_lrrp_source[1] = 0;
|
||||||
|
|
||||||
//initialize 12 rate superframe
|
//initialize 12 rate superframe
|
||||||
for (short i = 0; i < 84; i++)
|
for (short i = 0; i < 288; i++)
|
||||||
{
|
{
|
||||||
state->dmr_12_rate_sf[0][i] = 0;
|
state->dmr_12_rate_sf[0][i] = 0;
|
||||||
state->dmr_12_rate_sf[1][i] = 0;
|
state->dmr_12_rate_sf[1][i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//initialize 34 rate superframe
|
//initialize 34 rate superframe
|
||||||
for (short i = 0; i < 96; i++)
|
for (short i = 0; i < 288; i++)
|
||||||
{
|
{
|
||||||
state->dmr_34_rate_sf[0][i] = 0;
|
state->dmr_34_rate_sf[0][i] = 0;
|
||||||
state->dmr_34_rate_sf[1][i] = 0;
|
state->dmr_34_rate_sf[1][i] = 0;
|
||||||
|
|
@ -1042,7 +1042,7 @@ main (int argc, char **argv)
|
||||||
fprintf (stderr,"Writing + Appending decoded audio to file %s\n", opts.wav_out_file);
|
fprintf (stderr,"Writing + Appending decoded audio to file %s\n", opts.wav_out_file);
|
||||||
openWavOutFile (&opts, &state);
|
openWavOutFile (&opts, &state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'B':
|
case 'B':
|
||||||
sscanf (optarg, "%d", &opts.serial_baud);
|
sscanf (optarg, "%d", &opts.serial_baud);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue