mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-14 01:37:25 -05:00
Compare commits
95 Commits
v2.1beta
...
v.2.0_fina
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae58fabb72 | ||
|
|
e390251b9d | ||
|
|
f7ad3e638f | ||
|
|
a16c99994c | ||
|
|
7f187ff6d8 | ||
|
|
8485be965b | ||
|
|
d1e1572139 | ||
|
|
95e74c8e28 | ||
|
|
815fbb026f | ||
|
|
d1ce0121be | ||
|
|
a55db055d4 | ||
|
|
443b7c3031 | ||
|
|
4bebb361ec | ||
|
|
6f538fd166 | ||
|
|
fef36e3761 | ||
|
|
19df3dd7f1 | ||
|
|
acd2b0b134 | ||
|
|
0908baa47c | ||
|
|
c507ed229c | ||
|
|
3101bbde28 | ||
|
|
5e24ff505d | ||
|
|
4a8bf144dd | ||
|
|
d872818e03 | ||
|
|
f967b80217 | ||
|
|
f3d94ddc2a | ||
|
|
18bec720ae | ||
|
|
456687ba86 | ||
|
|
ba0e422f23 | ||
|
|
ce75acb41a | ||
|
|
68862296bf | ||
|
|
f3c0199b32 | ||
|
|
c8e8e041b7 | ||
|
|
85eea59598 | ||
|
|
304b5545ba | ||
|
|
313759333e | ||
|
|
1737c1f7e9 | ||
|
|
bd94f83318 | ||
|
|
5d7988ea0f | ||
|
|
432495c1ad | ||
|
|
9c75583323 | ||
|
|
b9389742f6 | ||
|
|
fb59406a28 | ||
|
|
339323695f | ||
|
|
d8e7c4c3aa | ||
|
|
1dc6737cc2 | ||
|
|
c1ed3fe038 | ||
|
|
d86b370a22 | ||
|
|
b7bfa98a50 | ||
|
|
da41dcd5c9 | ||
|
|
0c27de102d | ||
|
|
54c75e20c9 | ||
|
|
3102770353 | ||
|
|
477ca97830 | ||
|
|
5b51adfc95 | ||
|
|
4ab16b5935 | ||
|
|
fe5ec8b0b4 | ||
|
|
58d8ad8a8c | ||
|
|
df5d755345 | ||
|
|
9a7a836eca | ||
|
|
4243fc9692 | ||
|
|
c999c97445 | ||
|
|
569f72508a | ||
|
|
d78f516afe | ||
|
|
6e4a373d26 | ||
|
|
2f644f5ba6 | ||
|
|
37c24d0ca7 | ||
|
|
9cdbd35e51 | ||
|
|
67e28c4655 | ||
|
|
591df8657a | ||
|
|
c708ea5911 | ||
|
|
a4ecfdca30 | ||
|
|
ac1fd7897c | ||
|
|
a02f992a25 | ||
|
|
630d3f362c | ||
|
|
6666424ff8 | ||
|
|
b0fc20cea6 | ||
|
|
f61dbd4fe7 | ||
|
|
f369d645b1 | ||
|
|
7148e653e5 | ||
|
|
bb5da93fcd | ||
|
|
d2d750e920 | ||
|
|
485161f42d | ||
|
|
67661c2fb0 | ||
|
|
dcb21f2cd0 | ||
|
|
9f03bbc8a1 | ||
|
|
b4ecdf7820 | ||
|
|
35cc358101 | ||
|
|
db23968a6f | ||
|
|
9efd950b9f | ||
|
|
08461492ee | ||
|
|
b2ccd3a878 | ||
|
|
9b8a382ea5 | ||
|
|
235eeedcda | ||
|
|
0cff92101c | ||
|
|
c44e039772 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,3 +7,4 @@ build
|
|||||||
examples
|
examples
|
||||||
*.bin
|
*.bin
|
||||||
*.ans
|
*.ans
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,6 @@ SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/")
|
|||||||
set(CURSES_NEED_NCURSES TRUE)
|
set(CURSES_NEED_NCURSES TRUE)
|
||||||
set(CURSES_NEED_WIDE TRUE)
|
set(CURSES_NEED_WIDE TRUE)
|
||||||
|
|
||||||
#use cmake option -DAERO=ON to enable Aero Builds (OSS support and specific tweaks)
|
|
||||||
option(AERO
|
|
||||||
"Build for Aero Environments (Cygwin)" OFF)
|
|
||||||
if (AERO)
|
|
||||||
add_definitions(-DAERO_BUILD)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
#use cmake option -DCOLORS=OFF to disable color output
|
#use cmake option -DCOLORS=OFF to disable color output
|
||||||
option(COLORS
|
option(COLORS
|
||||||
"Build with Colors Enabled" ON)
|
"Build with Colors Enabled" ON)
|
||||||
@@ -31,11 +24,11 @@ if (PVC)
|
|||||||
add_definitions(-DPVCONVENTIONAL)
|
add_definitions(-DPVCONVENTIONAL)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
#use cmake option -DNXDN=ON to enable the old NXDN Sync Pattern
|
#use cmake option -DNXDN=ON to enable new NXDN Sync Pattern Testing
|
||||||
option(NXDN
|
option(NXDN
|
||||||
"Build with Old NXDN Sync Pattern Enabled" OFF)
|
"Build with new NXDN Sync Pattern Testing Enabled" OFF)
|
||||||
if (NXDN)
|
if (NXDN)
|
||||||
add_definitions(-DNXDNOLDSYNC)
|
add_definitions(-DNXDNTESTSYNC)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
#use cmake option -DLZ=ON to enable LimaZulu Requested NXDN Tweaks
|
#use cmake option -DLZ=ON to enable LimaZulu Requested NXDN Tweaks
|
||||||
@@ -45,20 +38,6 @@ if (LZ)
|
|||||||
add_definitions(-DLIMAZULUTWEAKS)
|
add_definitions(-DLIMAZULUTWEAKS)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
#use cmake option -DTONES to change default location of the tones.wav files (lwvmobile precompiled 'Aero' releases only)
|
|
||||||
option(NXDN
|
|
||||||
"Build with tone wav files in the dsd-fme folder and not in /usr/share/" OFF)
|
|
||||||
if (TN)
|
|
||||||
add_definitions(-DTONES)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
#use cmake option -DZDEV to change designation of this build from MAIN to zDEV
|
|
||||||
option(NXDN
|
|
||||||
"change designation of this build from MAIN to zDEV" OFF)
|
|
||||||
if (ZDEV)
|
|
||||||
add_definitions(-DZDEV_BUILD)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
include(git_revision)
|
include(git_revision)
|
||||||
git_describe(GIT_TAG)
|
git_describe(GIT_TAG)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
### Example Usage and Notes!
|
### Example Usage and Notes!
|
||||||
|
|
||||||
`dsd-fme` is all you need to run for pulse input, pulse output, and auto detect for DMR BS/MS, and P25. 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 BS/MS, and P25 (1 and 2) . 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.
|
||||||
|
|
||||||
```
|
```
|
||||||
-ft XDMA decoder class (P25 1 and 2, and DMR Stereo)
|
-ft XDMA decoder class (P25 1 and 2, and DMR Stereo)
|
||||||
@@ -12,11 +12,11 @@
|
|||||||
-fm dPMR, also may need to use -xd if inverted dPMR.
|
-fm dPMR, also may need to use -xd if inverted dPMR.
|
||||||
-fr DMR Mono, also may need to use -xr if inverted DMR.
|
-fr DMR Mono, also may need to use -xr if inverted DMR.
|
||||||
-f1 P25P1
|
-f1 P25P1
|
||||||
-f2 P25P2 (may need to specify wacn/sys/nac manually)
|
-f2 P25P2 (will need to specify wacn/sys/nac manually)
|
||||||
-fx X2-TDMA
|
-fx X2-TDMA
|
||||||
```
|
```
|
||||||
|
|
||||||
## Conventional Frequency "Fast Scanner"
|
## New -- Experimental Conventional Frequency "Fast Scanner"
|
||||||
This feature is used to allow DSD-FME to use RIGCTL or RTL input and cycle through frequencies as fast as possible to attain a frame sync.
|
This feature is used to allow DSD-FME to use RIGCTL or RTL input and cycle through frequencies as fast as possible to attain a frame sync.
|
||||||
|
|
||||||
This works almost identically to how the trunkng methods work, but instead of locking onto a control channel and tuning based on its decoding, it rapidly tunes through all loaded frequencies in a CSV file and stops when it finds a frame sync. This method is meant for loading a bunch of conventional non-trunking frequencies that signal only when voice or short data bursts are present (DMR T2, Conventional P25 P1, Conventional NXDN, etc) and decode them until the frame sync stops and then resume its scan. This method uses SDR++ RIGCTL, or RTL internal handling to go through signal. -Y is the fast scanner switch.
|
This works almost identically to how the trunkng methods work, but instead of locking onto a control channel and tuning based on its decoding, it rapidly tunes through all loaded frequencies in a CSV file and stops when it finds a frame sync. This method is meant for loading a bunch of conventional non-trunking frequencies that signal only when voice or short data bursts are present (DMR T2, Conventional P25 P1, Conventional NXDN, etc) and decode them until the frame sync stops and then resume its scan. This method uses SDR++ RIGCTL, or RTL internal handling to go through signal. -Y is the fast scanner switch.
|
||||||
@@ -27,10 +27,10 @@ To scan through a mixture of DMR and P25 Conventional, use:
|
|||||||
To scan through NXDN48 only conventional, use:
|
To scan through NXDN48 only conventional, use:
|
||||||
`dsd-fme -fi -i tcp -C channel_map.csv -Y -U 4532 -N 2> log.ans`
|
`dsd-fme -fi -i tcp -C channel_map.csv -Y -U 4532 -N 2> log.ans`
|
||||||
|
|
||||||
To scan through NXDN96 only conventional, use:
|
To scan through NXDN98 only conventional, use:
|
||||||
`dsd-fme -fn -i tcp -C channel_map.csv -Y -U 4532 -N 2> log.ans`
|
`dsd-fme -fn -i tcp -C channel_map.csv -Y -U 4532 -N 2> log.ans`
|
||||||
|
|
||||||
The Channel Map setup will be identical to any of the channel maps found for trunking systems, channel numbers do not matter and can be arbitrarily organized, and frequencies can be duplicated to be 'scanned' more frequently in larger CSV files. Scan speed by default is 1 second, and is most stable at that speed. This can be adjusted by using the `-t 2` option, for example, to specify 2 seconds of hang time per frequency. ~~If activity occurs on a frequency, an additional 2 seconds of 'hangtime' will occur on that frequency for any follow up voice activity.~~
|
The Channel Map setup will be identical to any of the channel maps found for trunking systems, channel numbers do not matter and can be arbitrarily organized, and frequencies can be duplicated to be 'scanned' more frequently in larger CSV files. Scan speed is purely set by your CPU/GPU, and also by other factors like using SDR++ server to connect to a SDR++ client, or RTL_TCP server to client, etc, so faster computers scan faster, and slower will scan slower, slower scans may require multiple duplicate entries into your scanner csv file if you make a really large one.
|
||||||
|
|
||||||
Please Note: DMR Simplex may not behave well on fast scan, I have not been able to test it as such, but given the nature of the on-off timeslot signalling on DMR Simplex, missed frame syncs and skipping/resuming scan may occur.
|
Please Note: DMR Simplex may not behave well on fast scan, I have not been able to test it as such, but given the nature of the on-off timeslot signalling on DMR Simplex, missed frame syncs and skipping/resuming scan may occur.
|
||||||
|
|
||||||
@@ -63,33 +63,26 @@ Then you can open up your pavucontrol "Pulse Audio Volume Control" or "Volume Co
|
|||||||
Wav File Input Note: Due to 96000 rate audio requiring me to double the symbol rate and center, be sure to use the -s 96000 at the very end of the startup command. Also, some NXDN48/96 may have difficulties decoding properly with wav file input.
|
Wav File Input Note: Due to 96000 rate audio requiring me to double the symbol rate and center, be sure to use the -s 96000 at the very end of the startup command. Also, some NXDN48/96 may have difficulties decoding properly with wav file input.
|
||||||
|
|
||||||
## Example Usage - RTL2832 Dongle Input
|
## Example Usage - RTL2832 Dongle Input
|
||||||
Short Setup (all default values):
|
|
||||||
|
|
||||||
`dsd-fme -i rtl`
|
|
||||||
|
|
||||||
Detailed Setup:
|
|
||||||
|
|
||||||
`dsd-fme -ft -i rtl:0:154.9875M:26:-2:8:0:6020 `
|
`dsd-fme -ft -i rtl:0:154.9875M:26:-2:8:0:6020 `
|
||||||
|
|
||||||
```
|
```
|
||||||
RTL-SDR options:
|
RTL-SDR options:
|
||||||
|
WARNING! Old CLI Switch Handling has been depreciated in favor of rtl:<parms>
|
||||||
Usage: rtl:dev:freq:gain:ppm:bw:sq:udp
|
Usage: rtl:dev:freq:gain:ppm:bw:sq:udp
|
||||||
NOTE: all arguments after rtl are optional now for trunking, but user configuration is recommended
|
|
||||||
dev <num> RTL-SDR Device Index Number
|
dev <num> RTL-SDR Device Index Number
|
||||||
freq <num> RTL-SDR Frequency (851800000 or 851.8M)
|
freq <num> RTL-SDR Frequency (851800000 or 851.8M)
|
||||||
gain <num> RTL-SDR Device Gain (0-49)(default = 0; Hardware AGC recommended)
|
gain <num> RTL-SDR Device Gain (0-49) (default = 26)(0 = Hardware AGC, not recommended)
|
||||||
ppm <num> RTL-SDR PPM Error (default = 0)
|
ppm <num> RTL-SDR PPM Error (default = 0)
|
||||||
bw <num> RTL-SDR Bandwidth kHz (default = 12)(8, 12, 16, 24)
|
bw <num> RTL-SDR VFO Bandwidth kHz (default = 12)(6, 8, 12, 24)
|
||||||
sq <num> RTL-SDR Squelch Level vs RMS Value (Optional)
|
sq <num> RTL-SDR Squelch Level (0 - Open, 25 - Little, 50 - Higher)
|
||||||
udp <num> RTL-SDR Legacy UDP Remote Port (Optional -- External Use Only)
|
udp <num> RTL-SDR UDP Remote Port (default = 6020)
|
||||||
Example: dsd-fme-zdev -fs -i rtl -C cap_plus_channel.csv -T
|
Example: dsd-fme -fp -i rtl:0:851.375M:22:-2:12:0:6021
|
||||||
Example: dsd-fme-zdev -fp -i rtl:0:851.375M:22:-2:24:0:6021
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Example Usage - Extra Payload/PDU Logging
|
## Example Usage - Extra Payload/PDU Logging
|
||||||
|
|
||||||
`dsd-fme -Z -N 2> log.ans`
|
`dsd-fme -Z -N 2>> log.ans`
|
||||||
|
|
||||||
and in a second terminal tab, same folder, run
|
and in a second terminal tab, same folder, run
|
||||||
|
|
||||||
@@ -119,11 +112,11 @@ EDACS Trunking (w/ channel map import)
|
|||||||
|
|
||||||
`dsd-fme -i tcp -T -U 4532 -N 2> log.ans`
|
`dsd-fme -i tcp -T -U 4532 -N 2> log.ans`
|
||||||
|
|
||||||
--P25 Trunking (QPSK) with P1 Control Channel (Should switch symbol rate and center on Phase 2 audio channels)
|
--P25 Trunking (CQPSK) with P1 Control Channel (Should switch symbol rate and center on Phase 2 audio channels)
|
||||||
|
|
||||||
`dsd-fme -i tcp -T -U 4532 -N -mq 2> log.ans`
|
`dsd-fme -i tcp -T -U 4532 -N -mq 2> log.ans`
|
||||||
|
|
||||||
--P25 Trunking Phase 2 TDMA Control Channel systems with QPSK (non Phase 1 systems)
|
--P25 Trunking Phase 2 TDMA Control Channel systems with CQPSK (non Phase 1 systems)
|
||||||
|
|
||||||
`dsd-fme -i tcp -T -U 4532 -N -f2 -m2 2> log.ans`
|
`dsd-fme -i tcp -T -U 4532 -N -f2 -m2 2> log.ans`
|
||||||
|
|
||||||
@@ -131,7 +124,7 @@ Trunking Note1: All samples above can also be run with the RTL input method and
|
|||||||
|
|
||||||
`dsd-fme -fp -i rtl:0:851.8M:22:-2:24:0:6020 -T -C channel_map.csv -G group.csv -N 2> log.ans`
|
`dsd-fme -fp -i rtl:0:851.8M:22:-2:24:0:6020 -T -C channel_map.csv -G group.csv -N 2> log.ans`
|
||||||
|
|
||||||
Trunking Note2: QPSK Phase 1 and Phase 2 Systems may be subceptible to LSM distortion issues, but seem to do okay, but require really good signal. Some CRC issues still occur with Phase 2 TDMA LCCH Mac Signal that can affect reliability, I believe this issue is ultimately caused by the PSK demodulation inside of FME. I also don't believe this will work on 8-level PSK, but I cannot determine that at the moment. Update: I have improved the LCCH Mac Signal decoding my increasing the QPSK decision point buffers to their maximum values.
|
Trunking Note2: CQPSK Phase 1 and Phase 2 Systems are subceptible to LSM distortion issues, but seem to do okay, but require really good signal. Some CRC issues still occur with Phase 2 TDMA LCCH Mac Signal that can affect reliability, I believe this issue is ultimately caused by the PSK demodulation inside of FME. I also don't believe this will work on 8-level PSK, but I cannot determine that at the moment. Update: I have improved the LCCH Mac Signal decoding my increasing the QPSK decision point buffers to their maximum values.
|
||||||
|
|
||||||
Trunking Note3: DMR Trunking has been coded, and some testing and tweaks have been carried out. Cap+, Con+, and TIII systems seem to do well with trunking now. Placing the frequency for the control channel at channel map 0 in your channel_map.csv file is not required now if using RIGCTL or the RTL Input, both can poll the VFO for the current frequency if it believes its on a control channel, but setting a fake channel number (i.e. 999) first with the CC frequency will result in finding the CC faster on startup if desired. If you need to map out your channels for TIII, you can observe the console output and look for channel numbers. For conveniece I have included the DSDPlus channel numbering (as best as I can figure it, but they seem consistent) into the console print so it will make it easier for users from DSDPlus to map frequencies into the channel_map.csv file. Make sure your channel numbers are the Cd (channel decimal) values from the log, and not the C+ (dsdplus) values. Notice: TIII Site ID value needs work to determine proper DMRLA values for system area and sub area.
|
Trunking Note3: DMR Trunking has been coded, and some testing and tweaks have been carried out. Cap+, Con+, and TIII systems seem to do well with trunking now. Placing the frequency for the control channel at channel map 0 in your channel_map.csv file is not required now if using RIGCTL or the RTL Input, both can poll the VFO for the current frequency if it believes its on a control channel, but setting a fake channel number (i.e. 999) first with the CC frequency will result in finding the CC faster on startup if desired. If you need to map out your channels for TIII, you can observe the console output and look for channel numbers. For conveniece I have included the DSDPlus channel numbering (as best as I can figure it, but they seem consistent) into the console print so it will make it easier for users from DSDPlus to map frequencies into the channel_map.csv file. Make sure your channel numbers are the Cd (channel decimal) values from the log, and not the C+ (dsdplus) values. Notice: TIII Site ID value needs work to determine proper DMRLA values for system area and sub area.
|
||||||
|
|
||||||
@@ -142,9 +135,9 @@ Trunking Note3: DMR Trunking has been coded, and some testing and tweaks have be
|
|||||||
|
|
||||||
Use channel 54 in your import file, which would correspond to dsdplus channels 109 and 110 (109 = TS0 / 110 = TS1).
|
Use channel 54 in your import file, which would correspond to dsdplus channels 109 and 110 (109 = TS0 / 110 = TS1).
|
||||||
|
|
||||||
For Connect Plus, enumerate your list from 1 to the last channel and add the frequency. For Capacity Plus, LSN 1 and 2 will share the same frequency, 3 and 4 will share, 5 and 6 will share, and 7-8 will share, as Capacity Plus counts each 'channel' as two seperate channels (LSN), one for each time slot. Capacity Plus Quirk: DSD-FME makes its best effort to follow the rest channel in the event that the sync is lost for longer than the hangtime, but occassionally, DSD-FME may lose the rest channel and will have to hunt through all frequencies to find it again.
|
For Connect Plus, enumerate your list from 1 to the last channel and add the frequency. For Capacity Plus, Rest Channels 1 and 2 will share the same frequency, 3 and 4 will share, 5 and 6 will share, and 7-8 will share, as Capacity Plus counts each 'channel' as two seperate channels (LSN), one for each time slot. Capacity Plus Quirk: DSD-FME makes its best effort to follow the rest channel in the event that the sync is lost for longer than the hangtime, but occassionally, DSD-FME will lose the rest channel and will have to hunt through all frequencies to find it again.
|
||||||
|
|
||||||
Trunking Note4: NXDN Trunking v1 will require a channel map. Please see the example folder for an appropriate channel map. NOTICE: NXDN trunking has been fixed on the RTL (rtl_fm) input method and works correctly now using a soft squelch value to determine when to look for frame sync. Tests show this works very well, but squelch adjustments may be required to differentiate the noise floor from the signal.
|
Trunking Note4: NXDN Trunking v1 will require a channel map. Please see the example folder for an appropriate channel map. NOTICE: NXDN trunking will not work properly with RTL input method due to the internal handling of the RTL dongle, when using squelch, it will effectively stop all processing (including trunking/tuning) until signal is regained, but squelch is required on NXDN to prevent false sync patterns.
|
||||||
|
|
||||||
NXDN Trunking Update: NXDN DFA (Direct Frequency Assignment) has been coded from the v2 documents, so using a channel map may not be required, as long as the DFA is configured with standard values, and not 'system definable' values. This will only work on trunking systems that use DFA (newer systems) in accordance to the v2 CAI document NXDN TS 1-A Version 2.0 September 2016. If the system uses 'system definable' values, then make sure to put the channels in a channel map csv file as as the 16-bit OFN values for proper tuning.
|
NXDN Trunking Update: NXDN DFA (Direct Frequency Assignment) has been coded from the v2 documents, so using a channel map may not be required, as long as the DFA is configured with standard values, and not 'system definable' values. This will only work on trunking systems that use DFA (newer systems) in accordance to the v2 CAI document NXDN TS 1-A Version 2.0 September 2016. If the system uses 'system definable' values, then make sure to put the channels in a channel map csv file as as the 16-bit OFN values for proper tuning.
|
||||||
|
|
||||||
@@ -152,7 +145,7 @@ NXDN Type-D/IDAS Update: Type-D or IDAS decoding/trunking has been coded now and
|
|||||||
|
|
||||||
Channel Map and Group CSV Note: Leave the top line of the channel_map.csv and group.csv as the label, do not delete the line, if no line is there, dsd_import skips the first line so it will not import the first channel or first group in those files if there is something there that isn't a label.
|
Channel Map and Group CSV Note: Leave the top line of the channel_map.csv and group.csv as the label, do not delete the line, if no line is there, dsd_import skips the first line so it will not import the first channel or first group in those files if there is something there that isn't a label.
|
||||||
|
|
||||||
Hytera XPT: Code has been added for XPT system slco/flco/csbk decoding and trunking. The setup will be similar to Capacity Plus trunking in the csv file, listing each LSN channel to a frequency (see examples/hytera_xpt_chan.csv). Currently, this set up is working with smaller XPT systems that I have been able to test with.
|
Hytera XPT: Experimental Code has been added for XPT system slco/flco/csbk decoding and trunking. The setup will be similar to Capacity Plus trunking in the csv file, listing each LSN channel to a frequency (see examples/hytera_xpt_chan.csv). Currently, this set up is working with smaller XPT systems that I have been able to test with.
|
||||||
|
|
||||||
## NCurses Keyboard Shortcuts ##
|
## NCurses Keyboard Shortcuts ##
|
||||||
|
|
||||||
@@ -165,8 +158,7 @@ c - toggle compact mode
|
|||||||
h - toggle call history
|
h - toggle call history
|
||||||
z - toggle console payloads
|
z - toggle console payloads
|
||||||
a - toggle call alert beep
|
a - toggle call alert beep
|
||||||
4 - force privacy/scrambler key assertion over enc identifiers (dmr and nxdn)
|
4 - force dmr privacy key assertion over fid and svc bits
|
||||||
6 - force rc4 key assertion over missing pi header/le enc identifiers (dmr)
|
|
||||||
i - toggle signal inversion on types that can't auto detect (dmr, dpmr)
|
i - toggle signal inversion on types that can't auto detect (dmr, dpmr)
|
||||||
m - toggle c4fm/qpsk 10/4 (everything but phase 2 signal)
|
m - toggle c4fm/qpsk 10/4 (everything but phase 2 signal)
|
||||||
M - toggle c4fm/qpsk 8/3 (phase 2 tdma control channel)
|
M - toggle c4fm/qpsk 8/3 (phase 2 tdma control channel)
|
||||||
@@ -174,20 +166,16 @@ R - start capturing symbol capture bin (date/time name file)
|
|||||||
r - stop capturing symbol capture bin
|
r - stop capturing symbol capture bin
|
||||||
spacebar - replay last symbol capture bin (captures must be stopped first)
|
spacebar - replay last symbol capture bin (captures must be stopped first)
|
||||||
s - stop playing symbol capture bin or wav input file
|
s - stop playing symbol capture bin or wav input file
|
||||||
P - start per call decoded wav files (Capital P)
|
P - start per call decoded wav files
|
||||||
p - stop per call decoded wav files (Lower p)
|
p - stop per call decoded wav files
|
||||||
t - toggle trunking (needs either rtl input, or rigctl connection)
|
t - toggle trunking (needs either rtl input, or rigctl connection)
|
||||||
y - toggle scanner (needs either rtl input, or rigctl connection)
|
y - toggle scanner (needs either rtl input, or rigctl connection)
|
||||||
1 - Lockout Tuning/Playback of TG in Slot 1 or Conventional -- Current Session Only if no group.csv file specified
|
1 - Lockout Tuning/Playback of TG in Slot 1 or Conventional (Current Session Only)
|
||||||
2 - Lockout Tuning/Playback of TG in Slot 2 -- Current Session Only if no group.csv file specified
|
2 - Lockout Tuning/Playback of TG in Slot 2 (Current Session Only)
|
||||||
0 - Toggle Audio Smoothing - May produce crackling if enabled on RTL/TCP or wav/bin files
|
0 - Toggle Audio Smoothing - May produce crackling if enabled on RTL/TCP or wav/bin files
|
||||||
w - Toggle Trunking/Playback White List (Allow A Groups Only) / Black List (Block B or DE groups only) Mode
|
w - Toggle Trunking/Playback White List (Allow A Groups Only) / Black List (Block B or DE groups only) Mode
|
||||||
g - Toggle Trunking Tuning to Group Calls (DMR T3, Con+, Cap+, P25, NXDN)
|
g - Toggle Trunking Tuning to Group Calls (DMR T3, Con+, Cap+, P25)
|
||||||
u - Toggle Trunking Tuning to Private Calls (DMR T3, Cap+, P25)
|
u - Toggle Trunking Tuning to Private Calls (DMR T3, P25)
|
||||||
d - Toggle Trunking Tuning to Data Calls (DMR T3, NXDN)
|
d - Toggle Trunking Tuning to Data Calls (DMR T3)
|
||||||
e - Toggle Trunking Tuning to Encrypted Calls (P25)
|
|
||||||
8 - Connect to SDR++ TCP Audio Sink with Defaults/Retry Sink Connection on Disconnect
|
|
||||||
9 - Connect to SDR++ RIGCTL Server with Defaults/Retry RIGCTL Connection
|
|
||||||
D - Reset DMR Site Parms/Call Strings, etc.
|
|
||||||
Z - Simulate NoCarrier/No VC/CC sync (capital Z)
|
|
||||||
```
|
```
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
### 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 23.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:
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ wget https://raw.githubusercontent.com/lwvmobile/dsd-fme/main/download-and-insta
|
|||||||
chmod +x download-and-install.sh
|
chmod +x download-and-install.sh
|
||||||
./download-and-install.sh
|
./download-and-install.sh
|
||||||
```
|
```
|
||||||
f
|
|
||||||
If you have dependencies already installed (i.e. need a fresh clean install on a system with DSD-FME already or using system other than Debian/Ubuntu, etc), please run this instead:
|
If you have dependencies already installed (i.e. need a fresh clean install on a system with DSD-FME already or using system other than Debian/Ubuntu, etc), please run this instead:
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -20,23 +20,18 @@ chmod +x download-and-install-nodeps.sh
|
|||||||
./download-and-install-nodeps.sh
|
./download-and-install-nodeps.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Ubuntu 18.04/LM19/Buster Note:
|
||||||
|
The above install.sh should now function on older system types. You can elect to manually follow the steps down below. Do NOT Manually build and install ITPP 4.3.1 on older systems, it is currently not wanting to build on Ubuntu 18.04 and Linux Mint 19. Install it from the repository instead.
|
||||||
|
|
||||||
## 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.
|
||||||
|
|
||||||
Debian/Mint/Ubuntu/Pi
|
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install libpulse-dev pavucontrol libsndfile1-dev libfftw3-dev liblapack-dev socat libusb-1.0-0-dev libncurses5 libncurses5-dev rtl-sdr librtlsdr-dev libusb-1.0-0-dev cmake git wget make build-essential libitpp-dev libncursesw5-dev
|
sudo apt install libpulse-dev pavucontrol libsndfile1-dev libfftw3-dev liblapack-dev socat libusb-1.0-0-dev libncurses5 libncurses5-dev rtl-sdr librtlsdr-dev libusb-1.0-0-dev cmake git wget make build-essential libitpp-dev libncursesw5-dev
|
||||||
```
|
```
|
||||||
|
## Headless
|
||||||
Fedora 36/37 -- from https://github.com/lwvmobile/dsd-fme/issues/99
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo dnf install libsndfile-devel fftw-devel lapack-devel rtl-sdr-devel pulseaudio-libs-devel libusb-devel cmake git ncurses ncurses-devel gcc wget pavucontrol gcc-c++
|
|
||||||
```
|
|
||||||
## Headless Ubuntu Server/Pi
|
|
||||||
|
|
||||||
If running headless, swap out pavucontrol for pulsemixer, and also install pulseaudio as well. Attempting to install pavucontrol in a headless environment may attempt to install a minimal desktop environment. Note: Default behavior of pulseaudio in a headless environment may be to be muted, so check by opening pulsemixer and unmuting and routing audio appropriately.
|
If running headless, swap out pavucontrol for pulsemixer, and also install pulseaudio as well. Attempting to install pavucontrol in a headless environment may attempt to install a minimal desktop environment. Note: Default behavior of pulseaudio in a headless environment may be to be muted, so check by opening pulsemixer and unmuting and routing audio appropriately.
|
||||||
|
|
||||||
@@ -98,41 +93,9 @@ sudo make install
|
|||||||
sudo ldconfig
|
sudo ldconfig
|
||||||
|
|
||||||
```
|
```
|
||||||
|
Optional 'Virtual Sinks' for routing audio from SDR++ or GQRX, Media Players, etc. into DSD-FME
|
||||||
|
|
||||||
### Windows Cygwin Builds
|
You may wish to direct sound into DSD-FME via Virtual Sinks. You may set up a Virtual Sink or two on your machine for routing audio in and out of applications to other applications using the following command, and opening up pavucontrol "PulseAudio Volume Control" in the menu (or `pulsemixer` in headless mode) to change line out of application to virtual sink, and line in of DSD-FME to monitor of virtual sink. This command will not persist past a reboot, so you will need to invoke them each time you reboot, or search for how to add this to your conf files for persistency if desired.
|
||||||
|
|
||||||
If using RTL input support, you must install libusb-win32 before proceeding with Cygwin installation. You will also need to build and compile a version of librtlsdr, but this can be tricky, and personally, I had to resort to using a much older version of the source code to get it to build at all with the rtl support in the precompiled 'Aero' builds.
|
|
||||||
|
|
||||||
Then install all dependencies available in the repo prior to building, either directly selecting them during setup with the setup-x86.exe or setup-x64.exe or by issuing a command similar to this:
|
|
||||||
|
|
||||||
```
|
|
||||||
setup-x64.exe --packages libpulse-devel,libpulse-mainloop-glib0,libpulse-simple0,libpulse0,pulseaudio,pulseaudio-debuginfo,pulseaudio-equalizer,pulseaudio-module-x11,pulseaudio-module-zeroconf,pulseaudio-utils,sox-fmt-pulseaudio,xfce-pulseaudio-plugin,libusb0,libusb1.0,libusb1.0-debuginfo,libusb1.0-devel,libncurses++w10,libncurses-devel,libncursesw10,ncurses,cmake,gcc-core,gcc-debuginfo,gcc-objc,git,make,socat,sox,sox-fmt-ao,unzip,wget,gcc-g++,libsndfile-devel
|
|
||||||
```
|
|
||||||
|
|
||||||
Then manually install ITPP and MBElib, see above install notes. Be sure to run `cp libmbe* /usr/lib` after compiling MBElib.
|
|
||||||
|
|
||||||
Then you can build and install using
|
|
||||||
|
|
||||||
```
|
|
||||||
git clone https://github.com/lwvmobile/dsd-fme
|
|
||||||
cd dsd-fme
|
|
||||||
cp tone8.wav /usr/share/
|
|
||||||
cp tone24.wav /usr/share/
|
|
||||||
cp tone48.wav /usr/share/
|
|
||||||
chmod 777 /usr/share/tone8.wav
|
|
||||||
chmod 777 /usr/share/tone24.wav
|
|
||||||
chmod 777 /usr/share/tone48.wav
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
# -DAERO=ON is optional, but recommended if you want the older OSS support as well
|
|
||||||
cmake -DAERO=ON ..
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
```
|
|
||||||
|
|
||||||
### Virtual Sinks
|
|
||||||
|
|
||||||
You may wish to direct sound into DSD-FME via Virtual Sinks. You may set up a Virtual Sink or two on your machine for routing audio in and out of applications to other applications using the following command, and opening up pavucontrol "PulseAudio Volume Control" in the menu (or `pulsemixer` in headless mode) to change line out of application to virtual sink, and line in of DSD-FME to monitor of virtual sink. This command will not persist past a reboot, so you will need to invoke them each time you reboot, or search for how to add this to your conf files for persistency if desired. Note: This setup is completely optional if using TCP Network Sink Audio and/or RTL Input.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
pactl load-module module-null-sink sink_name=virtual_sink sink_properties=device.description=Virtual_Sink
|
pactl load-module module-null-sink sink_name=virtual_sink sink_properties=device.description=Virtual_Sink
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
LSN(dec),frequency(Hz) (do not delete this line or won't import properly)
|
ChannelNumber(dec),frequency(Hz) (do not delete this line or won't import properly)
|
||||||
1,858606250
|
1,858606250
|
||||||
2,858606250
|
2,858606250
|
||||||
3,859606250
|
3,859606250
|
||||||
|
|||||||
|
@@ -1,4 +1,4 @@
|
|||||||
LSN(dec),frequency(Hz) (do not delete this line or won't import properly)
|
ChannelNumber(dec),frequency(Hz) (do not delete this line or won't import properly)
|
||||||
1,851375000
|
1,851375000
|
||||||
2,851800000
|
2,851800000
|
||||||
3,855987500
|
3,855987500
|
||||||
|
|||||||
|
@@ -1,4 +1,4 @@
|
|||||||
LSN(dec),frequency(Hz) (do not delete this line or won't import properly)
|
LSN Number(dec),frequency(Hz) (do not delete this line or won't import properly)
|
||||||
1,858606250
|
1,858606250
|
||||||
2,858606250
|
2,858606250
|
||||||
3,859606250
|
3,859606250
|
||||||
|
|||||||
|
@@ -1,4 +1,4 @@
|
|||||||
key id or tg id (dec), key number or value (dec) //NXDN Scrambler, BP, 10-char Hytera BP only
|
key id or tg id (dec), key number or value (dec) //NXDN, BP, 10-char Hytera BP only
|
||||||
2,70
|
2,70
|
||||||
1,123
|
1,123
|
||||||
100,70
|
100,70
|
||||||
|
|||||||
|
@@ -1,5 +0,0 @@
|
|||||||
key id(hex), key value (hex) //10-char Hytera BP, RC4
|
|
||||||
1,1234567890
|
|
||||||
2,ABCDEF1234
|
|
||||||
C,0B57935150
|
|
||||||
64,0B57935150
|
|
||||||
|
@@ -1,37 +1,33 @@
|
|||||||
#example trunking sh scripts (SDR++ with RIGCTL and RTL Input)
|
#example trunking sh scripts (SDR++ and RTL Input) -T = trunking
|
||||||
#make sure to put a # in front of all lines except the one you wish to use
|
#make sure to put a # in front of all lines except the one you wish to use
|
||||||
|
|
||||||
#P25 P1 FDMA CC with C4FM
|
#P25 P1 FDMA CC with C4FM
|
||||||
#dsd-fme -i tcp -U 4532 -T -N 2> log.ans
|
#dsd-fme -i tcp -U 4532 -T -N 2> log.ans
|
||||||
#dsd-fme -i rtl:0:850M:0:-2:12 -T -N 2> log.ans
|
#dsd-fme -i rtl:0:850M:26:-2:8:0:6020 -T -N 2> log.ans
|
||||||
|
|
||||||
#P25 P1 FDMA CC with QPSK (Simulcast)
|
#P25 P1 FDMA CC with QPSK (Simulcast)
|
||||||
#dsd-fme -i tcp:192.168.7.8:7355 -U 4532 -T -mq -N 2> log.ans
|
#dsd-fme -i tcp:192.168.7.8:7355 -U 4532 -T -mq -N 2> log.ans
|
||||||
#dsd-fme -i rtl:0:855.625M:0:-2:12 -T -mq -N 2> log.ans
|
#dsd-fme -i rtl:0:855.625M:26:-2:12:0:6020 -T -mq -N 2> log.ans
|
||||||
|
|
||||||
#P25 P2 TDMA CC with QPSK (Simulcast)
|
#P25 P2 TDMA CC with QPSK (Simulcast)
|
||||||
#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:26:-2:12:0:6020 -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:26:-2:8:0:6020 -T -C connect_plus_chan.csv -G group.csv -N 2> log.ans
|
||||||
|
|
||||||
#EDACS/EDACS-EA Digital Only
|
#EDACS/EDACS-EA Digital Only
|
||||||
#dsd-fme -fp -i tcp:192.168.7.5:7355 -U 4532 -T -C edacs_channel_map.csv -G group.csv -N 2> log.ans
|
#dsd-fme -fp -i tcp:192.168.7.5:7355 -U 4532 -T -C edacs_channel_map.csv -G group.csv -N 2> log.ans
|
||||||
#dsd-fme -fp -i rtl:0:850M:44:-2:24 -T -C edacs_channel_map.csv -G group.csv -N 2> log.ans
|
#dsd-fme -fp -i rtl:0:850M:26:-2:24:0:6020 -T -C edacs_channel_map.csv -G group.csv -N 2> log.ans
|
||||||
|
|
||||||
#NXDN48 Type-C or Type-D Trunking with Channel Map
|
#NXDN48 Trunking with Channel Map (Custom Channels > 800)
|
||||||
#dsd-fme -fi -i tcp -T -U 4532 -C nxdn_channel_map.csv -N 2> log.ans
|
#dsd-fme -fi -i tcp -T -U 4532 -C channel_map.csv -N 2> log.ans
|
||||||
#dsd-fme -fi -i rtl:0:855.625M:0:-2:12:100 -T -C nxdn_channel_map.csv -N 2> log.ans
|
#NOTE! NXDN Trunking will not work correctly with the RTL input method
|
||||||
|
|
||||||
#NXDN48 Type-C Trunking with DFA
|
#NXDN96 Trunking with Channel Map (Custom Channels > 800)
|
||||||
#dsd-fme -fi -i tcp -T -U 4532 -N 2> log.ans
|
#dsd-fme -fn -i tcp -T -U 4532 -C channel_map.csv -N 2> log.ans
|
||||||
#dsd-fme -fi -i rtl:0:855.625M:0:-2:12:100 -T -N 2> log.ans
|
#NOTE! NXDN Trunking will not work correctly with the RTL input method
|
||||||
|
|
||||||
#NXDN96 Trunking with Channel Map
|
|
||||||
#dsd-fme -fn -i tcp -T -U 4532 -C nxdn_channel_map.csv -N 2> log.ans
|
|
||||||
#dsd-fme -fn -i rtl -T -C nxdn_channel_map.csv -N 2> log.ans
|
|
||||||
|
|
||||||
#Notes: parameters after -i tcp can be omitted if using localhost as the default hostname to connect
|
#Notes: parameters after -i tcp can be omitted if using localhost as the default hostname to connect
|
||||||
#and 7355 as the default port number. -U is the port number for RIGCTL and will mirror the tcp hostname
|
#and 7355 as the default port number. -U is the port number for RIGCTL and will mirror the tcp hostname
|
||||||
@@ -40,6 +36,5 @@ dsd-fme -fs -i tcp -U 4532 -T -C dmr_t3_chan.csv -G group.csv -N 2> log.ans
|
|||||||
#inside of SDR++ match, i.e., change in SDR++ from 'localhost' to an IP to bind to (machine's IP address)
|
#inside of SDR++ match, i.e., change in SDR++ from 'localhost' to an IP to bind to (machine's IP address)
|
||||||
|
|
||||||
#Note2: RTL input should only be used on strong signal, the SDR++ VFO will perform much better on marginal signal
|
#Note2: RTL input should only be used on strong signal, the SDR++ VFO will perform much better on marginal signal
|
||||||
#paramters after -i rtl can also be omitted now if using the default configurations
|
|
||||||
|
|
||||||
#Having a -G group.csv is purely optional, but useful if you want to block groups, or give groups names
|
#Having a -G group.csv is purely optional, but useful if you want to block groups, or give groups names
|
||||||
|
|||||||
@@ -58,14 +58,11 @@
|
|||||||
|
|
||||||
#include "p25p1_heuristics.h"
|
#include "p25p1_heuristics.h"
|
||||||
|
|
||||||
//OSS support
|
|
||||||
#include <sys/soundcard.h>
|
|
||||||
|
|
||||||
#include <pulse/simple.h> //PULSE AUDIO
|
#include <pulse/simple.h> //PULSE AUDIO
|
||||||
#include <pulse/error.h> //PULSE AUDIO
|
#include <pulse/error.h> //PULSE AUDIO
|
||||||
|
|
||||||
#define SAMPLE_RATE_IN 48000 //48000
|
#define SAMPLE_RATE_IN 48000 //48000
|
||||||
#define SAMPLE_RATE_OUT 48000 //8000,
|
#define SAMPLE_RATE_OUT 8000 //8000,
|
||||||
|
|
||||||
#ifdef USE_RTLSDR
|
#ifdef USE_RTLSDR
|
||||||
#include <rtl-sdr.h>
|
#include <rtl-sdr.h>
|
||||||
@@ -204,7 +201,6 @@ typedef struct
|
|||||||
int audio_in_type;
|
int audio_in_type;
|
||||||
char audio_out_dev[1024];
|
char audio_out_dev[1024];
|
||||||
int audio_out_fd;
|
int audio_out_fd;
|
||||||
int audio_out_fdR; //right channel audio for OSS hack
|
|
||||||
SNDFILE *audio_out_file;
|
SNDFILE *audio_out_file;
|
||||||
SF_INFO *audio_out_file_info;
|
SF_INFO *audio_out_file_info;
|
||||||
|
|
||||||
@@ -270,7 +266,6 @@ typedef struct
|
|||||||
int rtl_udp_port;
|
int rtl_udp_port;
|
||||||
int rtl_bandwidth;
|
int rtl_bandwidth;
|
||||||
int rtl_started;
|
int rtl_started;
|
||||||
int rtl_rms;
|
|
||||||
int monitor_input_audio;
|
int monitor_input_audio;
|
||||||
int pulse_raw_rate_in;
|
int pulse_raw_rate_in;
|
||||||
int pulse_raw_rate_out;
|
int pulse_raw_rate_out;
|
||||||
@@ -373,16 +368,10 @@ typedef struct
|
|||||||
//Trunking - Tune Enc Calls (P25 only on applicable grants with svc opts)
|
//Trunking - Tune Enc Calls (P25 only on applicable grants with svc opts)
|
||||||
uint8_t trunk_tune_enc_calls;
|
uint8_t trunk_tune_enc_calls;
|
||||||
|
|
||||||
//OSS audio - slot preference
|
|
||||||
int slot_preference;
|
|
||||||
|
|
||||||
//'DSP' Format Output
|
//'DSP' Format Output
|
||||||
uint8_t use_dsp_output;
|
uint8_t use_dsp_output;
|
||||||
char dsp_out_file[2048];
|
char dsp_out_file[2048];
|
||||||
|
|
||||||
//Use P25p1 heuristics
|
|
||||||
uint8_t use_heuristics;
|
|
||||||
|
|
||||||
} dsd_opts;
|
} dsd_opts;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -694,8 +683,8 @@ typedef struct
|
|||||||
uint64_t late_entry_mi_fragment[2][7][3];
|
uint64_t late_entry_mi_fragment[2][7][3];
|
||||||
|
|
||||||
//dmr manufacturer branding and sub_branding (i.e., Motorola and Con+)
|
//dmr manufacturer branding and sub_branding (i.e., Motorola and Con+)
|
||||||
char dmr_branding[20];
|
char dmr_branding[99];
|
||||||
char dmr_branding_sub[80];
|
char dmr_branding_sub[99];
|
||||||
|
|
||||||
//Remus DMR End Call Alert Beep
|
//Remus DMR End Call Alert Beep
|
||||||
int dmr_end_alert[2]; //dmr TLC end call alert beep has already played once flag
|
int dmr_end_alert[2]; //dmr TLC end call alert beep has already played once flag
|
||||||
@@ -968,6 +957,7 @@ uint8_t ComputeCrc5Bit(uint8_t * DMRData);
|
|||||||
uint16_t ComputeCrc9Bit(uint8_t * DMRData, uint32_t NbData);
|
uint16_t ComputeCrc9Bit(uint8_t * DMRData, uint32_t NbData);
|
||||||
uint32_t ComputeCrc32Bit(uint8_t * DMRData, uint32_t NbData);
|
uint32_t ComputeCrc32Bit(uint8_t * DMRData, uint32_t NbData);
|
||||||
|
|
||||||
|
|
||||||
//new simplified dmr functions
|
//new simplified dmr functions
|
||||||
void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t databurst);
|
void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t databurst);
|
||||||
void dmr_data_sync (dsd_opts * opts, dsd_state * state);
|
void dmr_data_sync (dsd_opts * opts, dsd_state * state);
|
||||||
@@ -1012,10 +1002,8 @@ 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);
|
||||||
uint8_t crc7(uint8_t bits[], unsigned int len);
|
uint8_t crc7(uint8_t bits[], unsigned int len);
|
||||||
|
|
||||||
//LFSR and LFSRP code courtesy of https://github.com/mattames/LFSR/
|
//LFSR code courtesy of https://github.com/mattames/LFSR/
|
||||||
void LFSR(dsd_state * state);
|
void LFSR(dsd_state * state);
|
||||||
void LFSRP(dsd_state * state);
|
|
||||||
|
|
||||||
void LFSRN (char * BufferIn, char * BufferOut, dsd_state * state);
|
void LFSRN (char * BufferIn, char * BufferOut, dsd_state * state);
|
||||||
void LFSR64(dsd_state * state);
|
void LFSR64(dsd_state * state);
|
||||||
|
|
||||||
@@ -1057,7 +1045,6 @@ bool QR_16_7_6_decode(unsigned char *rxBits);
|
|||||||
|
|
||||||
void InitAllFecFunction(void);
|
void InitAllFecFunction(void);
|
||||||
void resetState (dsd_state * state);
|
void resetState (dsd_state * state);
|
||||||
void reset_dibit_buffer(dsd_state * state);
|
|
||||||
void dstar_header_decode(dsd_state * state, int radioheaderbuffer[660]);
|
void dstar_header_decode(dsd_state * state, int radioheaderbuffer[660]);
|
||||||
|
|
||||||
//P25 PDU Handler
|
//P25 PDU Handler
|
||||||
@@ -1103,8 +1090,7 @@ unsigned long long int edacs_bch (unsigned long long int message);
|
|||||||
int csvGroupImport(dsd_opts * opts, dsd_state * state);
|
int csvGroupImport(dsd_opts * opts, dsd_state * state);
|
||||||
int csvLCNImport(dsd_opts * opts, dsd_state * state);
|
int csvLCNImport(dsd_opts * opts, dsd_state * state);
|
||||||
int csvChanImport(dsd_opts * opts, dsd_state * state);
|
int csvChanImport(dsd_opts * opts, dsd_state * state);
|
||||||
int csvKeyImportDec(dsd_opts * opts, dsd_state * state);
|
int csvKeyImport(dsd_opts * opts, dsd_state * state);
|
||||||
int csvKeyImportHex(dsd_opts * opts, dsd_state * state);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -1115,9 +1101,6 @@ void open_rtlsdr_stream(dsd_opts *opts);
|
|||||||
void cleanup_rtlsdr_stream();
|
void cleanup_rtlsdr_stream();
|
||||||
void get_rtlsdr_sample(int16_t *sample, dsd_opts * opts, dsd_state * state);
|
void get_rtlsdr_sample(int16_t *sample, dsd_opts * opts, dsd_state * state);
|
||||||
void rtlsdr_sighandler();
|
void rtlsdr_sighandler();
|
||||||
void rtl_dev_tune(dsd_opts * opts, long int frequency);
|
|
||||||
int rtl_return_rms();
|
|
||||||
void rtl_clean_queue();
|
|
||||||
#endif
|
#endif
|
||||||
//DMR TRELLIS
|
//DMR TRELLIS
|
||||||
void CDMRTrellisTribitsToBits(const unsigned char* tribits, unsigned char* payload);
|
void CDMRTrellisTribitsToBits(const unsigned char* tribits, unsigned char* payload);
|
||||||
|
|||||||
@@ -776,9 +776,9 @@ void dmr_reset_blocks (dsd_opts * opts, dsd_state * state)
|
|||||||
memset (state->cap_plus_block_num, 0, sizeof(state->cap_plus_block_num));
|
memset (state->cap_plus_block_num, 0, sizeof(state->cap_plus_block_num));
|
||||||
memset (state->data_header_valid, 0, sizeof(state->data_header_valid));
|
memset (state->data_header_valid, 0, sizeof(state->data_header_valid));
|
||||||
memset (state->data_header_format, 7, sizeof(state->data_header_format));
|
memset (state->data_header_format, 7, sizeof(state->data_header_format));
|
||||||
//reset some strings -- resetting call string here causes random blink on ncurses terminal (cap+)
|
//reset some strings
|
||||||
// sprintf (state->call_string[0], "%s", " "); //21 spaces
|
sprintf (state->call_string[0], "%s", " "); //21 spaces
|
||||||
// sprintf (state->call_string[1], "%s", " "); //21 spaces
|
sprintf (state->call_string[1], "%s", " "); //21 spaces
|
||||||
sprintf (state->dmr_lrrp_gps[0], "%s", "");
|
sprintf (state->dmr_lrrp_gps[0], "%s", "");
|
||||||
sprintf (state->dmr_lrrp_gps[1], "%s", "");
|
sprintf (state->dmr_lrrp_gps[1], "%s", "");
|
||||||
}
|
}
|
||||||
42
src/dmr_bs.c
42
src/dmr_bs.c
@@ -114,7 +114,7 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
|||||||
//disabled for dmr_cach testing
|
//disabled for dmr_cach testing
|
||||||
tact_okay = 0;
|
tact_okay = 0;
|
||||||
if ( Hamming_7_4_decode (tact_bits) ) tact_okay = 1;
|
if ( Hamming_7_4_decode (tact_bits) ) tact_okay = 1;
|
||||||
if (tact_okay != 1) goto END;
|
if (tact_okay != 1) goto END; //when going to end for bad tact or emb, consider using getdibit or skipdibit to 'stash' dibits and get better return on next sync pattern? in data particularly
|
||||||
|
|
||||||
|
|
||||||
internalslot = state->currentslot = tact_bits[1];
|
internalslot = state->currentslot = tact_bits[1];
|
||||||
@@ -189,13 +189,13 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
|||||||
syncdata[(2*i)+1] = (1 & dibit); // bit 0
|
syncdata[(2*i)+1] = (1 & dibit); // bit 0
|
||||||
|
|
||||||
//embedded link control
|
//embedded link control
|
||||||
if(internalslot == 0 && vc1 > 1 && vc1 < 7) //grab on vc1 values 2-5 B C D and E
|
if(internalslot == 0 && vc1 > 1 && vc1 < 7) //grab on vc1 values 2-5 B C D and E (F for Single/RC)
|
||||||
{
|
{
|
||||||
state->dmr_embedded_signalling[internalslot][vc1-1][i*2] = (1 & (dibit >> 1)); // bit 1
|
state->dmr_embedded_signalling[internalslot][vc1-1][i*2] = (1 & (dibit >> 1)); // bit 1
|
||||||
state->dmr_embedded_signalling[internalslot][vc1-1][i*2+1] = (1 & dibit); // bit 0
|
state->dmr_embedded_signalling[internalslot][vc1-1][i*2+1] = (1 & dibit); // bit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if(internalslot == 1 && vc2 > 1 && vc2 < 7) //grab on vc2 values 2-5 B C D and E
|
if(internalslot == 1 && vc2 > 1 && vc2 < 7) //grab on vc2 values 2-5 B C D and E (F for Single/RC)
|
||||||
{
|
{
|
||||||
state->dmr_embedded_signalling[internalslot][vc2-1][i*2] = (1 & (dibit >> 1)); // bit 1
|
state->dmr_embedded_signalling[internalslot][vc2-1][i*2] = (1 & (dibit >> 1)); // bit 1
|
||||||
state->dmr_embedded_signalling[internalslot][vc2-1][i*2+1] = (1 & dibit); // bit 0
|
state->dmr_embedded_signalling[internalslot][vc2-1][i*2+1] = (1 & dibit); // bit 0
|
||||||
@@ -339,9 +339,8 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
|||||||
//process embedded link control
|
//process embedded link control
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
dmr_data_burst_handler(opts, state, (uint8_t *)dummy_bits, 0xEB);
|
dmr_data_burst_handler(opts, state, (uint8_t *)dummy_bits, 0xEB);
|
||||||
//check the single burst/reverse channel opportunity -- moved
|
//check the single burst/reverse channel opportunity
|
||||||
// dmr_sbrc (opts, state, power);
|
dmr_sbrc (opts, state, power);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (internalslot == 1 && vc2 == 6)
|
if (internalslot == 1 && vc2 == 6)
|
||||||
@@ -349,9 +348,8 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
|||||||
//process embedded link control
|
//process embedded link control
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
dmr_data_burst_handler(opts, state, (uint8_t *)dummy_bits, 0xEB);
|
dmr_data_burst_handler(opts, state, (uint8_t *)dummy_bits, 0xEB);
|
||||||
//check the single burst/reverse channel opportunity -- moved
|
//check the single burst/reverse channel opportunity
|
||||||
// dmr_sbrc (opts, state, power);
|
dmr_sbrc (opts, state, power);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts->payload == 1) fprintf (stderr, "\n"); //extra line break necessary here
|
if (opts->payload == 1) fprintf (stderr, "\n"); //extra line break necessary here
|
||||||
@@ -363,19 +361,6 @@ 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);
|
||||||
@@ -383,10 +368,6 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
|||||||
cach_err = dmr_cach (opts, state, cachdata);
|
cach_err = dmr_cach (opts, state, cachdata);
|
||||||
if (opts->payload == 0) fprintf (stderr, "\n");
|
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
|
|
||||||
if (internalslot == 0 && vc1 == 6) dmr_sbrc (opts, state, power);
|
|
||||||
if (internalslot == 1 && vc2 == 6) dmr_sbrc (opts, state, power);
|
|
||||||
|
|
||||||
// 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);
|
||||||
@@ -480,12 +461,12 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
|||||||
fprintf (stderr, "%s", KNRM);
|
fprintf (stderr, "%s", KNRM);
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
//run refresh if either slot had an active MI in it.
|
//run refresh if either slot had an active MI in it.
|
||||||
if (state->payload_algid >= 0x21)
|
if (state->payload_algid != 0)
|
||||||
{
|
{
|
||||||
state->currentslot = 0;
|
state->currentslot = 0;
|
||||||
dmr_alg_refresh (opts, state);
|
dmr_alg_refresh (opts, state);
|
||||||
}
|
}
|
||||||
if (state->payload_algidR >= 0x21)
|
if (state->payload_algidR != 0)
|
||||||
{
|
{
|
||||||
state->currentslot = 1;
|
state->currentslot = 1;
|
||||||
dmr_alg_refresh (opts, state);
|
dmr_alg_refresh (opts, state);
|
||||||
@@ -573,6 +554,7 @@ void dmrBSBootstrap (dsd_opts * opts, dsd_state * state)
|
|||||||
if ( Hamming_7_4_decode (tact_bits) ) tact_okay = 1;
|
if ( Hamming_7_4_decode (tact_bits) ) tact_okay = 1;
|
||||||
if (tact_okay != 1) goto END;
|
if (tact_okay != 1) goto END;
|
||||||
|
|
||||||
|
|
||||||
internalslot = state->currentslot = tact_bits[1];
|
internalslot = state->currentslot = tact_bits[1];
|
||||||
|
|
||||||
//Setup for first AMBE Frame
|
//Setup for first AMBE Frame
|
||||||
@@ -747,12 +729,12 @@ void dmrBSBootstrap (dsd_opts * opts, dsd_state * state)
|
|||||||
fprintf (stderr, "%s", KNRM);
|
fprintf (stderr, "%s", KNRM);
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
//run refresh if either slot had an active MI in it.
|
//run refresh if either slot had an active MI in it.
|
||||||
if (state->payload_algid >= 0x21)
|
if (state->payload_algid != 0)
|
||||||
{
|
{
|
||||||
state->currentslot = 0;
|
state->currentslot = 0;
|
||||||
dmr_alg_refresh (opts, state);
|
dmr_alg_refresh (opts, state);
|
||||||
}
|
}
|
||||||
if (state->payload_algidR >= 0x21)
|
if (state->payload_algidR != 0)
|
||||||
{
|
{
|
||||||
state->currentslot = 1;
|
state->currentslot = 1;
|
||||||
dmr_alg_refresh (opts, state);
|
dmr_alg_refresh (opts, state);
|
||||||
|
|||||||
@@ -249,15 +249,13 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
|
|||||||
dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away
|
dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away
|
||||||
}
|
}
|
||||||
|
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune (opts, state, freq);
|
||||||
rtl_dev_tune (opts, freq);
|
|
||||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away
|
dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -854,11 +852,11 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
|
|||||||
//check for private activity on LSNs 1-8
|
//check for private activity on LSNs 1-8
|
||||||
if (fl == 1 || fl == 3)
|
if (fl == 1 || fl == 3)
|
||||||
{
|
{
|
||||||
if (pdflag) //== 0x80 //testing denny's 0x80 or 0x90 flag discovery
|
if (pdflag == 0x80)
|
||||||
{
|
{
|
||||||
k = 0; //= 0
|
k = 0; //= 0
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
fprintf (stderr, " Bank One F%X Private or Data Call(s) - ", pdflag);
|
fprintf (stderr, " F%X Private or Data Call - ", pdflag);
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
pch[i] = state->cap_plus_csbk_bits[ts][i+48+(group_tally*8)];
|
pch[i] = state->cap_plus_csbk_bits[ts][i+48+(group_tally*8)];
|
||||||
@@ -878,25 +876,25 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
|
|||||||
//end private/data call check on LSNs 1-8
|
//end private/data call check on LSNs 1-8
|
||||||
|
|
||||||
//check flag for appended private and/or data calls -- flag two still needs work or testing, double checking, etc, disable if issues arise
|
//check flag for appended private and/or data calls -- flag two still needs work or testing, double checking, etc, disable if issues arise
|
||||||
pdflag2 = (uint8_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[ts][56+(group_tally*8)+(pd_b2*16)], 8); //48 -- had wrong value here (atleast in the one sample with the false positive)
|
pdflag2 = (uint8_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[ts][48+(group_tally*8)+(pd_b2*16)], 8);
|
||||||
|
|
||||||
//check for private activity on LSNs 9-16
|
//check for private activity on LSNs 9-16
|
||||||
if (fl == 1 || fl == 3)
|
if (fl == 1 || fl == 3)
|
||||||
{
|
{
|
||||||
//then check to see if this byte has a value, should be 0x80, could be other?
|
//then check to see if this byte has a value, should be 0x80, could be other?
|
||||||
//this bytes location shifts depending on level of activity -- see banks above
|
//this bytes location shifts depending on level of activity -- see banks above
|
||||||
if (pdflag2) //== 0x80 //testing denny's 0x80 or 0x90 flag discovery
|
if (pdflag2 == 0x80) //now looking to see if any appended data was added
|
||||||
{
|
{
|
||||||
k = 0;
|
k = 0;
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
fprintf (stderr, " Bank Two F%02X Private or Data Call(s) - ", pdflag2);
|
fprintf (stderr, " F%X Private or Data Call - ", pdflag2);
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
pch[i+8] = state->cap_plus_csbk_bits[ts][i+64+(group_tally*8)+(pd_b2*16)]; //56
|
pch[i+8] = state->cap_plus_csbk_bits[ts][i+56+(group_tally*8)+(pd_b2*16)]; //48
|
||||||
if (pch[i+8] == 1)
|
if (pch[i+8] == 1)
|
||||||
{
|
{
|
||||||
fprintf (stderr, " LSN %02d:", i+1);
|
fprintf (stderr, " LSN %02d:", i+1);
|
||||||
private_target = (uint16_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[ts][64+(k*16)+(group_tally*8)+(pd_b2*16)], 16); //56 -- had wrong value here (atleast in the one sample with the false positive)
|
private_target = (uint16_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[ts][64+(k*16)+(group_tally*8)+(pd_b2*16)], 16); //64
|
||||||
fprintf (stderr, " TGT %d;", private_target);
|
fprintf (stderr, " TGT %d;", private_target);
|
||||||
k++;
|
k++;
|
||||||
if (bank_two == 0) bank_two = 0xFF; //set all bits on so we can atleast parse all of them below in listing/display
|
if (bank_two == 0) bank_two = 0xFF; //set all bits on so we can atleast parse all of them below in listing/display
|
||||||
@@ -982,7 +980,7 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
|
|||||||
}
|
}
|
||||||
else if (pch[i] == 1) //private or data channels
|
else if (pch[i] == 1) //private or data channels
|
||||||
{
|
{
|
||||||
tg = (uint16_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[ts][(group_tally*8)+(x*16)+56], 16); //don't change this AGAIN!, this is correct!
|
tg = (uint16_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[ts][(group_tally*8)+(x*16)+56], 16);
|
||||||
if (tg != 0) fprintf (stderr, "%5d; ", tg);
|
if (tg != 0) fprintf (stderr, "%5d; ", tg);
|
||||||
else fprintf (stderr, " P||D; ");
|
else fprintf (stderr, " P||D; ");
|
||||||
//flag as available for tuning if data calls enabled
|
//flag as available for tuning if data calls enabled
|
||||||
@@ -1057,16 +1055,14 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
|
|||||||
j = 11; //break loop
|
j = 11; //break loop
|
||||||
}
|
}
|
||||||
|
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune (opts, state, state->trunk_chan_map[j+1]);
|
||||||
rtl_dev_tune (opts, state->trunk_chan_map[j+1]);
|
|
||||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = state->trunk_chan_map[j+1];
|
state->p25_vc_freq[0] = state->p25_vc_freq[1] = state->trunk_chan_map[j+1];
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away
|
dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away
|
||||||
j = 11; //break loop
|
j = 11; //break loop
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1202,17 +1198,15 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
|
|||||||
dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away
|
dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away
|
||||||
}
|
}
|
||||||
|
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune (opts, state, state->trunk_chan_map[lcn]);
|
||||||
rtl_dev_tune (opts, state->trunk_chan_map[lcn]);
|
|
||||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = state->trunk_chan_map[lcn];
|
state->p25_vc_freq[0] = state->p25_vc_freq[1] = state->trunk_chan_map[lcn];
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
state->is_con_plus = 1; //flag on
|
state->is_con_plus = 1; //flag on
|
||||||
state->last_vc_sync_time = time(NULL); //bugfix: set sync here so we don't immediately tune back to CC constantly.
|
state->last_vc_sync_time = time(NULL); //bugfix: set sync here so we don't immediately tune back to CC constantly.
|
||||||
dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away
|
dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1399,19 +1393,17 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
|
|||||||
j = 11; //break loop
|
j = 11; //break loop
|
||||||
}
|
}
|
||||||
|
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
|
||||||
//debug
|
//debug
|
||||||
fprintf (stderr, " - Freq: %ld", state->trunk_chan_map[j+xpt_bank+1]);
|
fprintf (stderr, " - Freq: %ld", state->trunk_chan_map[j+xpt_bank+1]);
|
||||||
|
|
||||||
rtl_dev_tune (opts, state->trunk_chan_map[j+xpt_bank+1]);
|
rtl_udp_tune (opts, state, state->trunk_chan_map[j+xpt_bank+1]);
|
||||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = state->trunk_chan_map[j+xpt_bank+1];
|
state->p25_vc_freq[0] = state->p25_vc_freq[1] = state->trunk_chan_map[j+xpt_bank+1];
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away
|
dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away
|
||||||
j = 11; //break loop
|
j = 11; //break loop
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ dmr_data_sync (dsd_opts * opts, dsd_state * state)
|
|||||||
if ( Hamming_7_4_decode (tact_bits) ) cach_okay = 1;
|
if ( Hamming_7_4_decode (tact_bits) ) cach_okay = 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
cach_okay = -1;
|
cach_okay = -1;
|
||||||
SlotTypeOk = 0;
|
SlotTypeOk = 0;
|
||||||
goto END;
|
goto END;
|
||||||
@@ -179,6 +180,7 @@ dmr_data_sync (dsd_opts * opts, dsd_state * state)
|
|||||||
dibit = (int)state->dmr_stereo_payload[65];
|
dibit = (int)state->dmr_stereo_payload[65];
|
||||||
}
|
}
|
||||||
else state->dmr_stereo_payload[65] = dibit;
|
else state->dmr_stereo_payload[65] = dibit;
|
||||||
|
|
||||||
SlotType[8] = (1 & (dibit >> 1)); // bit 1
|
SlotType[8] = (1 & (dibit >> 1)); // bit 1
|
||||||
SlotType[9] = (1 & dibit); // bit 0
|
SlotType[9] = (1 & dibit); // bit 0
|
||||||
|
|
||||||
@@ -258,7 +260,7 @@ dmr_data_sync (dsd_opts * opts, dsd_state * state)
|
|||||||
if( Golay_20_8_decode(SlotType) ) SlotTypeOk = 1;
|
if( Golay_20_8_decode(SlotType) ) SlotTypeOk = 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SlotTypeOk = -1;
|
|
||||||
SlotTypeOk = 0;
|
SlotTypeOk = 0;
|
||||||
goto END;
|
goto END;
|
||||||
}
|
}
|
||||||
@@ -336,9 +338,8 @@ dmr_data_sync (dsd_opts * opts, dsd_state * state)
|
|||||||
|
|
||||||
else if (opts->audio_in_type == 3) //rtl_fm tuning
|
else if (opts->audio_in_type == 3) //rtl_fm tuning
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
//UDP command to tune the RTL dongle
|
||||||
rtl_dev_tune(opts, state->p25_cc_freq);
|
rtl_udp_tune(opts, state, state->p25_cc_freq);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
opts->p25_is_tuned = 0;
|
opts->p25_is_tuned = 0;
|
||||||
//zero out vc frequencies
|
//zero out vc frequencies
|
||||||
|
|||||||
@@ -342,7 +342,6 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C
|
|||||||
state->payload_miR = 0;
|
state->payload_miR = 0;
|
||||||
state->payload_keyidR = 0;
|
state->payload_keyidR = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -521,7 +520,7 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C
|
|||||||
|
|
||||||
if (state->K1 != 0 && fid == 0x68 && so & 0x40)
|
if (state->K1 != 0 && fid == 0x68 && so & 0x40)
|
||||||
{
|
{
|
||||||
if (state->K2 != 0) fprintf (stderr, "\n ");
|
fprintf (stderr, "\n");
|
||||||
fprintf (stderr, "%s", KYEL);
|
fprintf (stderr, "%s", KYEL);
|
||||||
fprintf (stderr, " Key %010llX ", state->K1);
|
fprintf (stderr, " Key %010llX ", state->K1);
|
||||||
if (state->K2 != 0) fprintf (stderr, "%016llX ", state->K2);
|
if (state->K2 != 0) fprintf (stderr, "%016llX ", state->K2);
|
||||||
@@ -529,27 +528,9 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C
|
|||||||
fprintf (stderr, "%s ", KNRM);
|
fprintf (stderr, "%s ", KNRM);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slot == 0 && state->payload_algid == 0x21 && state->R != 0)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "%s", KYEL);
|
|
||||||
fprintf (stderr, "Key %010llX ", state->R);
|
|
||||||
fprintf (stderr, "%s ", KNRM);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slot == 1 && state->payload_algidR == 0x21 && state->RR != 0)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "%s", KYEL);
|
|
||||||
fprintf (stderr, "Key %010llX ", state->RR);
|
|
||||||
fprintf (stderr, "%s ", KNRM);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
END_FLCO:
|
END_FLCO:
|
||||||
|
|
||||||
//blank the call string here if its a TLC
|
|
||||||
if (type == 2) sprintf (state->call_string[slot], "%s", " "); //21 spaces
|
|
||||||
|
|
||||||
if (unk == 1 || pf == 1)
|
if (unk == 1 || pf == 1)
|
||||||
{
|
{
|
||||||
fprintf(stderr, " FLCO=0x%02X FID=0x%02X ", flco, fid);
|
fprintf(stderr, " FLCO=0x%02X FID=0x%02X ", flco, fid);
|
||||||
|
|||||||
149
src/dmr_le.c
149
src/dmr_le.c
@@ -14,23 +14,6 @@ void dmr_late_entry_mi_fragment (dsd_opts * opts, dsd_state * state, uint8_t vc,
|
|||||||
|
|
||||||
uint8_t slot = state->currentslot;
|
uint8_t slot = state->currentslot;
|
||||||
|
|
||||||
//enforce RC4 due to missing PI header, but with valid SVC Opts
|
|
||||||
//ideally, this would be handled by VC-F single burst, but its not fully reliable compared to this
|
|
||||||
//due to multiple signalling occurring inside of it, depending on system type
|
|
||||||
if (state->M == 0x21)
|
|
||||||
{
|
|
||||||
if (slot == 0 && state->dmr_so & 0x40)
|
|
||||||
{
|
|
||||||
state->payload_algid = 0x21;
|
|
||||||
state->payload_keyid = 0xFF;
|
|
||||||
}
|
|
||||||
if (slot == 1 && state->dmr_soR & 0x40)
|
|
||||||
{
|
|
||||||
state->payload_algidR = 0x21;
|
|
||||||
state->payload_keyidR = 0xFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//collect our fragments and place them into storage
|
//collect our fragments and place them into storage
|
||||||
state->late_entry_mi_fragment[slot][vc][0] = (uint64_t)ConvertBitIntoBytes(&ambe_fr[3][0], 4);
|
state->late_entry_mi_fragment[slot][vc][0] = (uint64_t)ConvertBitIntoBytes(&ambe_fr[3][0], 4);
|
||||||
state->late_entry_mi_fragment[slot][vc][1] = (uint64_t)ConvertBitIntoBytes(&ambe_fr2[3][0], 4);
|
state->late_entry_mi_fragment[slot][vc][1] = (uint64_t)ConvertBitIntoBytes(&ambe_fr2[3][0], 4);
|
||||||
@@ -200,6 +183,7 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power)
|
|||||||
|
|
||||||
//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
|
||||||
|
//unknown what the other values are (see Cap+ 0x313 and 0x643)
|
||||||
if (power == 1) //RC
|
if (power == 1) //RC
|
||||||
{
|
{
|
||||||
crc_extracted = 0;
|
crc_extracted = 0;
|
||||||
@@ -214,19 +198,17 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power)
|
|||||||
}
|
}
|
||||||
else crc_okay = 1; //SB
|
else crc_okay = 1; //SB
|
||||||
|
|
||||||
for(i = 0; i < 11; i++)
|
if (opts->payload == 1) //hide the sb/rc behind the payload printer, won't be useful to most people right now
|
||||||
{
|
|
||||||
sbrc_hex = sbrc_hex << 1;
|
|
||||||
sbrc_hex |= sbrc_return[i] & 1; //sbrc_return
|
|
||||||
}
|
|
||||||
|
|
||||||
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, "\n %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++)
|
||||||
|
{
|
||||||
|
sbrc_hex = sbrc_hex << 1;
|
||||||
|
sbrc_hex |= sbrc_return[i] & 1; //sbrc_return
|
||||||
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);
|
||||||
|
|
||||||
@@ -235,73 +217,82 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power)
|
|||||||
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);
|
if (opts->payload == 1) fprintf (stderr, " CRC EXT %02X, CRC CMP %02X", crc_extracted, crc_computed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t sbrc_opcode = sbrc_hex;
|
//Disabling the lower portion until this can be completely ironed out
|
||||||
uint8_t alg = sbrc_hex & 0x7;
|
|
||||||
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)
|
|
||||||
|
|
||||||
if (1 == 1) //opts->payload == 1
|
//sbrc_hex value of 0x313 seems to be some Cap+ Thing,
|
||||||
{
|
//also observed 0x643 on another cap+ system (site id, status? something?)
|
||||||
if (irr_err != 0) ; //fprintf (stderr, "\n %s SLOT %d SB/RC (FEC ERR) %d %s \n", KRED, slot, irr_err, KNRM);
|
// uint8_t sbrc_opcode = sbrc_hex;
|
||||||
if (irr_err == 0)
|
// uint8_t alg = sbrc_hex & 0x7;
|
||||||
{
|
// uint8_t key = (sbrc_hex >> 3) & 0xFF;
|
||||||
if (sbrc_hex == 0) ; //NULL
|
|
||||||
//else if (placeholder for future conditions)
|
//this pattern seems to fit the multiple cap+ systems I've observed
|
||||||
|
//test on site '7' to make sure (works on 1 and 4)
|
||||||
|
// uint8_t cap_site = (sbrc_hex >> 4) & 0x7;
|
||||||
|
|
||||||
|
// if (opts->payload == 1)
|
||||||
// {
|
// {
|
||||||
// placeholder for future conditions
|
// if (irr_err != 0) fprintf (stderr, "%s (FEC ERR) %d %s", KRED, irr_err, KNRM);
|
||||||
|
// if (irr_err == 0)
|
||||||
|
// {
|
||||||
|
// if (sbrc_hex == 0) ; //NULL
|
||||||
|
// else if (strcmp (state->dmr_branding_sub, "Cap+ ") == 0)
|
||||||
|
// {
|
||||||
|
// //Cap+ Site ID seems to fit here on samples I've seen with the alternate SB signalling, but no idea what signals that info and not the emb alg/key info
|
||||||
|
// fprintf (stderr, "%s ", KYEL);
|
||||||
|
// fprintf (stderr, "\n ");
|
||||||
|
// fprintf (stderr, " Capacity Plus Site %d", cap_site);
|
||||||
|
// fprintf (stderr, "%s ", KNRM);
|
||||||
// }
|
// }
|
||||||
else //Finally have a consistent set-up for this
|
// else
|
||||||
{
|
// {
|
||||||
//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 == 0 && state->errs < 3)
|
|
||||||
{
|
|
||||||
if (state->dmr_so & 0x40 && key != 0 && state->payload_keyid == 0)
|
|
||||||
{
|
|
||||||
//if we aren't forcing a particular alg or privacy key set
|
|
||||||
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, "%s ", KNRM);
|
|
||||||
|
|
||||||
state->payload_keyid = key;
|
// if (slot == 0)
|
||||||
state->payload_algid = alg + 0x20; //assuming DMRA approved alg values (moto patent)
|
// {
|
||||||
}
|
// //key and alg only present SOME times, not all,
|
||||||
|
// //also, intermixed with other signalling
|
||||||
|
// //needs more study first!
|
||||||
|
// if (state->dmr_so & 0x40 && key != 0 && state->payload_keyid == 0)
|
||||||
|
// {
|
||||||
|
// if (opts->payload == 1)
|
||||||
|
// {
|
||||||
|
// fprintf (stderr, "%s ", KYEL);
|
||||||
|
// fprintf (stderr, "\n Slot 1");
|
||||||
|
// fprintf (stderr, " DMR LE SB ALG ID: %X KEY ID: %0X", alg + 0x20, key);
|
||||||
|
// fprintf (stderr, "%s ", KNRM);
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
// //needs more study before assignment
|
||||||
}
|
// // state->payload_keyid = key;
|
||||||
|
// // state->payload_algid = alg + 0x20; //assuming DMRA approved alg values (moto patent)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
//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)
|
||||||
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 (opts->payload == 1)
|
||||||
//if we aren't forcing a particular alg or privacy key set
|
// {
|
||||||
if (state->M == 0)
|
// fprintf (stderr, "%s ", KYEL);
|
||||||
{
|
// fprintf (stderr, "\n Slot 2");
|
||||||
fprintf (stderr, "%s ", KYEL);
|
// fprintf (stderr, " DMR LE SB ALG ID: %X KEY ID: %0X", alg + 0x20, key);
|
||||||
fprintf (stderr, " Slot 1");
|
// fprintf (stderr, "%s ", KNRM);
|
||||||
fprintf (stderr, " DMR LE SB ALG ID: %X KEY ID: %0X", alg + 0x20, key);
|
// }
|
||||||
fprintf (stderr, "\n");
|
|
||||||
fprintf (stderr, "%s ", KNRM);
|
|
||||||
|
|
||||||
state->payload_keyidR = key;
|
// //needs more study before assignment
|
||||||
state->payload_algidR = alg + 0x20; //assuming DMRA approved alg values (moto patent)
|
// // state->payload_keyidR = key;
|
||||||
}
|
// // state->payload_algidR = alg + 0x20; //assuming DMRA approved alg values (moto patent)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SBRC_END:
|
SBRC_END:
|
||||||
|
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
|
|||||||
for(i = 0; i < 24; i++)
|
for(i = 0; i < 24; i++)
|
||||||
{
|
{
|
||||||
dibit = getDibit(opts, state);
|
dibit = getDibit(opts, state);
|
||||||
if(opts->inverted_dmr == 1) dibit = (dibit ^ 2);
|
if(opts->inverted_dmr == 1) dibit = (dibit ^ 2) & 3;
|
||||||
|
|
||||||
state->dmr_stereo_payload[i+66] = dibit;
|
state->dmr_stereo_payload[i+66] = dibit;
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
|
|||||||
sync[i] = (dibit | 1) + 48;
|
sync[i] = (dibit | 1) + 48;
|
||||||
|
|
||||||
// load the superframe to do embedded signal processing
|
// load the superframe to do embedded signal processing
|
||||||
if(vc > 1) //grab on vc1 values 2-5 B C D and E
|
if(vc > 1) //grab on vc1 values 2-5 B C D and E (F for Single/RC)
|
||||||
{
|
{
|
||||||
state->dmr_embedded_signalling[internalslot][vc-1][i*2] = (1 & (dibit >> 1)); // bit 1
|
state->dmr_embedded_signalling[internalslot][vc-1][i*2] = (1 & (dibit >> 1)); // bit 1
|
||||||
state->dmr_embedded_signalling[internalslot][vc-1][i*2+1] = (1 & dibit); // bit 0
|
state->dmr_embedded_signalling[internalslot][vc-1][i*2+1] = (1 & dibit); // bit 0
|
||||||
@@ -212,7 +212,6 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
|
|||||||
cc = ((EmbeddedSignalling[0] << 3) + (EmbeddedSignalling[1] << 2) + (EmbeddedSignalling[2] << 1) + EmbeddedSignalling[3]);
|
cc = ((EmbeddedSignalling[0] << 3) + (EmbeddedSignalling[1] << 2) + (EmbeddedSignalling[2] << 1) + EmbeddedSignalling[3]);
|
||||||
power = EmbeddedSignalling[4];
|
power = EmbeddedSignalling[4];
|
||||||
lcss = ((EmbeddedSignalling[5] << 1) + EmbeddedSignalling[6]);
|
lcss = ((EmbeddedSignalling[5] << 1) + EmbeddedSignalling[6]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Continue Second AMBE Frame, 18 after Sync or EmbeddedSignalling
|
//Continue Second AMBE Frame, 18 after Sync or EmbeddedSignalling
|
||||||
|
|||||||
@@ -444,18 +444,17 @@ playSynthesizedVoice (dsd_opts * opts, dsd_state * state)
|
|||||||
|
|
||||||
if (state->audio_out_idx > opts->delay)
|
if (state->audio_out_idx > opts->delay)
|
||||||
{
|
{
|
||||||
if (opts->audio_out_type == 5) //OSS
|
// output synthesized speech to sound card
|
||||||
|
if(opts->audio_out_type == 2)
|
||||||
{
|
{
|
||||||
//OSS
|
//go F yourself PA
|
||||||
result = write (opts->audio_out_fd, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2));
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Test just sending it straight on since I think I've figured out the STDIN and RTL for Stereo
|
||||||
|
pa_simple_write(opts->pulse_digi_dev_out, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2), NULL); //Yay! It works.
|
||||||
state->audio_out_idx = 0;
|
state->audio_out_idx = 0;
|
||||||
}
|
}
|
||||||
else if (opts->audio_out_type == 0)
|
|
||||||
{
|
|
||||||
pa_simple_write(opts->pulse_digi_dev_out, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2), NULL);
|
|
||||||
state->audio_out_idx = 0;
|
|
||||||
}
|
|
||||||
else state->audio_out_idx = 0; //failsafe for audio_out == 0
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -479,18 +478,15 @@ playSynthesizedVoiceR (dsd_opts * opts, dsd_state * state)
|
|||||||
if (state->audio_out_idxR > opts->delay)
|
if (state->audio_out_idxR > opts->delay)
|
||||||
{
|
{
|
||||||
// output synthesized speech to sound card
|
// output synthesized speech to sound card
|
||||||
if (opts->audio_out_type == 5) //OSS
|
if(opts->audio_out_type == 2)
|
||||||
{
|
{
|
||||||
//OSS
|
//go F yourself PA
|
||||||
result = write (opts->audio_out_fdR, (state->audio_out_buf_pR - state->audio_out_idxR), (state->audio_out_idxR * 2));
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pa_simple_write(opts->pulse_digi_dev_outR, (state->audio_out_buf_pR - state->audio_out_idxR), (state->audio_out_idxR * 2), NULL); //Yay! It works.
|
||||||
state->audio_out_idxR = 0;
|
state->audio_out_idxR = 0;
|
||||||
}
|
}
|
||||||
else if (opts->audio_out_type == 0)
|
|
||||||
{
|
|
||||||
pa_simple_write(opts->pulse_digi_dev_outR, (state->audio_out_buf_pR - state->audio_out_idxR), (state->audio_out_idxR * 2), NULL);
|
|
||||||
state->audio_out_idxR = 0;
|
|
||||||
}
|
|
||||||
else state->audio_out_idxR = 0; //failsafe for audio_out == 0
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -565,7 +561,6 @@ openAudioInDevice (dsd_opts * opts)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (strncmp(opts->audio_in_dev, "tcp", 3) == 0)
|
else if (strncmp(opts->audio_in_dev, "tcp", 3) == 0)
|
||||||
{
|
{
|
||||||
opts->audio_in_type = 8;
|
opts->audio_in_type = 8;
|
||||||
@@ -575,13 +570,13 @@ openAudioInDevice (dsd_opts * opts)
|
|||||||
opts->audio_in_file_info->seekable=0;
|
opts->audio_in_file_info->seekable=0;
|
||||||
opts->audio_in_file_info->format=SF_FORMAT_RAW|SF_FORMAT_PCM_16|SF_ENDIAN_LITTLE;
|
opts->audio_in_file_info->format=SF_FORMAT_RAW|SF_FORMAT_PCM_16|SF_ENDIAN_LITTLE;
|
||||||
opts->tcp_file_in = sf_open_fd(opts->tcp_sockfd, SFM_READ, opts->audio_in_file_info, 0);
|
opts->tcp_file_in = sf_open_fd(opts->tcp_sockfd, SFM_READ, opts->audio_in_file_info, 0);
|
||||||
|
|
||||||
if(opts->tcp_file_in == NULL)
|
if(opts->tcp_file_in == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error, couldn't open TCP with libsndfile: %s\n", sf_strerror(NULL));
|
fprintf(stderr, "Error, couldn't open TCP with libsndfile: %s\n", sf_strerror(NULL));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (strncmp(opts->audio_in_dev, "udp", 3) == 0)
|
else if (strncmp(opts->audio_in_dev, "udp", 3) == 0)
|
||||||
{
|
{
|
||||||
opts->audio_in_type = 6;
|
opts->audio_in_type = 6;
|
||||||
@@ -600,24 +595,12 @@ openAudioInDevice (dsd_opts * opts)
|
|||||||
}
|
}
|
||||||
else if(strncmp(opts->audio_in_dev, "rtl", 3) == 0)
|
else if(strncmp(opts->audio_in_dev, "rtl", 3) == 0)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
|
||||||
opts->audio_in_type = 3;
|
opts->audio_in_type = 3;
|
||||||
#elif AERO_BUILD
|
|
||||||
opts->audio_in_type = 5;
|
|
||||||
sprintf (opts->audio_in_dev, "/dev/dsp");
|
|
||||||
#else
|
|
||||||
opts->audio_in_type = 0;
|
|
||||||
sprintf (opts->audio_in_dev, "pulse");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if(strncmp(opts->audio_in_dev, "pulse", 5) == 0)
|
else if(strncmp(opts->audio_in_dev, "pulse", 5) == 0)
|
||||||
{
|
{
|
||||||
opts->audio_in_type = 0;
|
opts->audio_in_type = 0;
|
||||||
}
|
}
|
||||||
else if((strncmp(opts->audio_in_dev, "/dev/dsp", 8) == 0))
|
|
||||||
{
|
|
||||||
opts->audio_in_type = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if no extension set, treat as named pipe or extensionless wav file -- bugfix for github issue #105
|
//if no extension set, treat as named pipe or extensionless wav file -- bugfix for github issue #105
|
||||||
else if (extension == NULL)
|
else if (extension == NULL)
|
||||||
@@ -684,11 +667,9 @@ openAudioInDevice (dsd_opts * opts)
|
|||||||
|
|
||||||
}
|
}
|
||||||
//open pulse audio if no bin or wav
|
//open pulse audio if no bin or wav
|
||||||
else //seems this condition is never met
|
else
|
||||||
{
|
{
|
||||||
//opts->audio_in_type = 5; //not sure if this works or needs to openPulse here
|
opts->audio_in_type = 0; //not sure if this works or needs to openPulse here
|
||||||
fprintf(stderr, "Error, couldn't open input file.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (opts->split == 1)
|
if (opts->split == 1)
|
||||||
|
|||||||
@@ -283,11 +283,11 @@ static int digitize (dsd_opts* opts, dsd_state* state, int symbol)
|
|||||||
|
|
||||||
valid = 0;
|
valid = 0;
|
||||||
|
|
||||||
//testing again, either on Voice channels only (when tuned) or with trunk disabled
|
//disabling again, causing issues with trunking
|
||||||
if (state->synctype == 1 && (opts->p25_is_tuned == 1 || opts->p25_trunk == 0) && opts->use_heuristics == 1)
|
if (state->synctype == 1 && opts->p25_trunk == 1)
|
||||||
{
|
{
|
||||||
// Use the P25p1 heuristics if available
|
// Use the P25 heuristics if available
|
||||||
valid = estimate_symbol(state->rf_mod, &(state->inv_p25_heuristics), state->last_dibit, symbol, &dibit);
|
// valid = estimate_symbol(state->rf_mod, &(state->inv_p25_heuristics), state->last_dibit, symbol, &dibit);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid == 0)
|
if (valid == 0)
|
||||||
@@ -347,11 +347,11 @@ static int digitize (dsd_opts* opts, dsd_state* state, int symbol)
|
|||||||
|
|
||||||
valid = 0;
|
valid = 0;
|
||||||
|
|
||||||
//testing again, either on Voice channels only (when tuned) or with trunk disabled
|
//disabling again, causing issues with trunking
|
||||||
if (state->synctype == 0 && (opts->p25_is_tuned == 1 || opts->p25_trunk == 0) && opts->use_heuristics == 1)
|
if (state->synctype == 0 && opts->p25_trunk == 1)
|
||||||
{
|
{
|
||||||
// Use the P25p1 heuristics if available
|
// Use the P25 heuristics if available
|
||||||
valid = estimate_symbol(state->rf_mod, &(state->p25_heuristics), state->last_dibit, symbol, &dibit);
|
// valid = estimate_symbol(state->rf_mod, &(state->p25_heuristics), state->last_dibit, symbol, &dibit);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid == 0)
|
if (valid == 0)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ char * getTimeF(void) //get pretty hh:mm:ss timestamp
|
|||||||
}
|
}
|
||||||
|
|
||||||
char * getDateF(void) {
|
char * getDateF(void) {
|
||||||
char datename[80]; //32-bit needs this to be 80
|
char datename[120]; //bug in 32-bit Ubuntu when using date in filename, date is garbage text
|
||||||
char * curr2;
|
char * curr2;
|
||||||
struct tm * to;
|
struct tm * to;
|
||||||
time_t t;
|
time_t t;
|
||||||
|
|||||||
@@ -189,12 +189,10 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
|||||||
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
||||||
SetFreq(opts->rigctl_sockfd, state->trunk_lcn_freq[state->lcn_freq_roll]);
|
SetFreq(opts->rigctl_sockfd, state->trunk_lcn_freq[state->lcn_freq_roll]);
|
||||||
}
|
}
|
||||||
//rtl
|
//rtludp
|
||||||
if (opts->audio_in_type == 3)
|
if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune (opts, state, state->trunk_lcn_freq[state->lcn_freq_roll]);
|
||||||
rtl_dev_tune (opts, state->trunk_lcn_freq[state->lcn_freq_roll]);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (stderr, "Tuning to Frequency: %.06lf MHz\n",
|
fprintf (stderr, "Tuning to Frequency: %.06lf MHz\n",
|
||||||
@@ -448,21 +446,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
|||||||
state->minref = state->min;
|
state->minref = state->min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//if using an rtl input method, do not look for sync patterns if the rms value is lower than our 'soft squelch' level
|
|
||||||
if (opts->audio_in_type == 3 && opts->rtl_rms < opts->rtl_squelch_level) //tests show floor level around 40, and signal breaking 100, default is 100 for level
|
|
||||||
{
|
|
||||||
if (opts->frame_nxdn48 == 1 || opts->frame_nxdn96 == 1 || opts->frame_dpmr == 1)
|
|
||||||
{
|
|
||||||
//should we update min/max here? yes or no?
|
|
||||||
|
|
||||||
// state->max = ((state->max) + lmax) / 2;
|
|
||||||
// state->min = ((state->min) + lmin) / 2;
|
|
||||||
|
|
||||||
goto SYNC_TEST_END;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy (synctest, (synctest_p - 23), 24);
|
strncpy (synctest, (synctest_p - 23), 24);
|
||||||
if (opts->frame_p25p1 == 1)
|
if (opts->frame_p25p1 == 1)
|
||||||
{
|
{
|
||||||
@@ -1294,7 +1277,120 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NXDNOLDSYNC //Use FSW vs strncmperr method
|
#ifdef NXDNTESTSYNC //use experimental sync detection based on multiple factors
|
||||||
|
|
||||||
|
//NXDN FSW sync and handling - testing with more exact syncs patterns
|
||||||
|
else if ((opts->frame_nxdn96 == 1) || (opts->frame_nxdn48 == 1))
|
||||||
|
{
|
||||||
|
strncpy (synctest10, (synctest_p - 9), 10); //FSW only
|
||||||
|
strncpy (synctest19, (synctest_p - 18), 19); //Preamble + FSW
|
||||||
|
|
||||||
|
//Using Hard Coded Sync Strings with variations for the areas where the symbol
|
||||||
|
//error will occur due to the demodulation issues internally
|
||||||
|
|
||||||
|
//Preamble plus FSW, proceed right away
|
||||||
|
if (
|
||||||
|
|
||||||
|
(strcmp (synctest19, "3131133313131331131") == 0 )
|
||||||
|
|| (strcmp (synctest19, "3131133313331331131") == 0 )
|
||||||
|
|| (strcmp (synctest19, "3131133313131331111") == 0 )
|
||||||
|
|| (strcmp (synctest19, "3131133313331331111") == 0 )
|
||||||
|
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// state->carrier = 1;
|
||||||
|
state->lastsynctype = 28;
|
||||||
|
|
||||||
|
state->offset = synctest_pos;
|
||||||
|
state->max = ((state->max) + lmax) / 2;
|
||||||
|
state->min = ((state->min) + lmin) / 2;
|
||||||
|
|
||||||
|
// if (opts->payload == 1)
|
||||||
|
// fprintf (stderr, "\n +PANDF ");
|
||||||
|
// if (opts->payload == 1)
|
||||||
|
// fprintf (stderr, " %s \n", synctest19);
|
||||||
|
return (28);
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
|
||||||
|
(strcmp (synctest19, "1313311133131331131") == 0 )
|
||||||
|
|| (strcmp (synctest19, "1313311133331331131") == 0 )
|
||||||
|
|| (strcmp (synctest19, "1313311133131331111") == 0 )
|
||||||
|
|| (strcmp (synctest19, "1313311133331331111") == 0 )
|
||||||
|
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// state->carrier = 1;
|
||||||
|
state->lastsynctype = 29;
|
||||||
|
|
||||||
|
state->offset = synctest_pos;
|
||||||
|
state->max = ((state->max) + lmax) / 2;
|
||||||
|
state->min = ((state->min) + lmin) / 2;
|
||||||
|
|
||||||
|
// if (opts->payload == 1)
|
||||||
|
// fprintf (stderr, "\n -PANDF ");
|
||||||
|
// if (opts->payload == 1)
|
||||||
|
// fprintf (stderr, " %s \n", synctest19);
|
||||||
|
return (29);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (
|
||||||
|
(strcmp (synctest10, "3131331131") == 0 )
|
||||||
|
|| (strcmp (synctest10, "3331331131") == 0 )
|
||||||
|
|| (strcmp (synctest10, "3131331111") == 0 )
|
||||||
|
|| (strcmp (synctest10, "3331331111") == 0 )
|
||||||
|
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// state->carrier = 1;
|
||||||
|
state->offset = synctest_pos;
|
||||||
|
state->max = ((state->max) + lmax) / 2;
|
||||||
|
state->min = ((state->min) + lmin) / 2;
|
||||||
|
|
||||||
|
if (state->lastsynctype == 28)
|
||||||
|
{
|
||||||
|
state->lastsynctype = 28;
|
||||||
|
// if (opts->payload == 1)
|
||||||
|
// fprintf (stderr, "\n +FSW ");
|
||||||
|
// if (opts->payload == 1)
|
||||||
|
// fprintf (stderr, " %s \n", synctest10);
|
||||||
|
return (28);
|
||||||
|
}
|
||||||
|
|
||||||
|
state->lastsynctype = 28;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (
|
||||||
|
|
||||||
|
(strcmp (synctest10, "1313113313") == 0 )
|
||||||
|
|| (strcmp (synctest10, "1113113313") == 0 )
|
||||||
|
|| (strcmp (synctest10, "1313113333") == 0 )
|
||||||
|
|| (strcmp (synctest10, "1113113333") == 0 )
|
||||||
|
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// state->carrier = 1;
|
||||||
|
state->offset = synctest_pos;
|
||||||
|
state->max = ((state->max) + lmax) / 2;
|
||||||
|
state->min = ((state->min) + lmin) / 2;
|
||||||
|
|
||||||
|
if (state->lastsynctype == 29)
|
||||||
|
{
|
||||||
|
state->lastsynctype = 29;
|
||||||
|
// if (opts->payload == 1)
|
||||||
|
// fprintf (stderr, "\n -FSW ");
|
||||||
|
// if (opts->payload == 1)
|
||||||
|
// fprintf (stderr, " %s \n", synctest10);
|
||||||
|
return (29);
|
||||||
|
}
|
||||||
|
state->lastsynctype = 29;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else //use current 'more stable' NXDN Sync pattern detection
|
||||||
|
|
||||||
//NXDN FSW sync and handling - moved to very bottom of sync stack for falsing sanity
|
//NXDN FSW sync and handling - moved to very bottom of sync stack for falsing sanity
|
||||||
else if ((opts->frame_nxdn96 == 1) || (opts->frame_nxdn48 == 1))
|
else if ((opts->frame_nxdn96 == 1) || (opts->frame_nxdn48 == 1))
|
||||||
@@ -1305,7 +1401,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
|||||||
//Preamble plus FSW, proceed right away
|
//Preamble plus FSW, proceed right away
|
||||||
if ( (strncmperr (synctest19, NXDN_PANDFSW, 19, 1) == 0) )
|
if ( (strncmperr (synctest19, NXDN_PANDFSW, 19, 1) == 0) )
|
||||||
{
|
{
|
||||||
state->carrier = 1;
|
// state->carrier = 1;
|
||||||
state->offset = synctest_pos;
|
state->offset = synctest_pos;
|
||||||
state->max = ((state->max) + lmax) / 2;
|
state->max = ((state->max) + lmax) / 2;
|
||||||
state->min = ((state->min) + lmin) / 2;
|
state->min = ((state->min) + lmin) / 2;
|
||||||
@@ -1318,7 +1414,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
|||||||
|
|
||||||
else if ( (strncmperr (synctest19, INV_NXDN_PANDFSW, 19, 1) == 0) )
|
else if ( (strncmperr (synctest19, INV_NXDN_PANDFSW, 19, 1) == 0) )
|
||||||
{
|
{
|
||||||
state->carrier = 1;
|
// state->carrier = 1;
|
||||||
state->offset = synctest_pos;
|
state->offset = synctest_pos;
|
||||||
state->max = ((state->max) + lmax) / 2;
|
state->max = ((state->max) + lmax) / 2;
|
||||||
state->min = ((state->min) + lmin) / 2;
|
state->min = ((state->min) + lmin) / 2;
|
||||||
@@ -1331,7 +1427,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
|||||||
|
|
||||||
else if ( (strncmperr (synctest10, NXDN_FSW, 10, 1) == 0) )
|
else if ( (strncmperr (synctest10, NXDN_FSW, 10, 1) == 0) )
|
||||||
{
|
{
|
||||||
state->carrier = 1;
|
// state->carrier = 1;
|
||||||
state->offset = synctest_pos;
|
state->offset = synctest_pos;
|
||||||
state->max = ((state->max) + lmax) / 2;
|
state->max = ((state->max) + lmax) / 2;
|
||||||
state->min = ((state->min) + lmin) / 2;
|
state->min = ((state->min) + lmin) / 2;
|
||||||
@@ -1349,7 +1445,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
|||||||
|
|
||||||
else if ( (strncmperr (synctest10, INV_NXDN_FSW, 10, 1) == 0) )
|
else if ( (strncmperr (synctest10, INV_NXDN_FSW, 10, 1) == 0) )
|
||||||
{
|
{
|
||||||
state->carrier = 1;
|
// state->carrier = 1;
|
||||||
state->offset = synctest_pos;
|
state->offset = synctest_pos;
|
||||||
state->max = ((state->max) + lmax) / 2;
|
state->max = ((state->max) + lmax) / 2;
|
||||||
state->min = ((state->min) + lmin) / 2;
|
state->min = ((state->min) + lmin) / 2;
|
||||||
@@ -1366,125 +1462,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else //use Current FSW Pattern
|
|
||||||
|
|
||||||
//NXDN FSW sync and handling - using more exact frame sync values
|
|
||||||
else if ((opts->frame_nxdn96 == 1) || (opts->frame_nxdn48 == 1))
|
|
||||||
{
|
|
||||||
strncpy (synctest10, (synctest_p - 9), 10); //FSW only
|
|
||||||
strncpy (synctest19, (synctest_p - 18), 19); //Preamble + FSW
|
|
||||||
|
|
||||||
//Using Hard Coded Sync Strings with variations for the areas where the symbol
|
|
||||||
//error will occur due to the demodulation issues internally
|
|
||||||
|
|
||||||
//Disabling the Preamble+FSW version for now
|
|
||||||
//its nearly impossible to catch it
|
|
||||||
|
|
||||||
//Preamble plus FSW, proceed right away
|
|
||||||
// if (
|
|
||||||
|
|
||||||
// (strcmp (synctest19, "3131133313131331131") == 0 )
|
|
||||||
// || (strcmp (synctest19, "3131133313331331131") == 0 )
|
|
||||||
// || (strcmp (synctest19, "3131133313131331111") == 0 )
|
|
||||||
// || (strcmp (synctest19, "3131133313331331111") == 0 )
|
|
||||||
|
|
||||||
// )
|
|
||||||
// {
|
|
||||||
// //state->carrier = 1;
|
|
||||||
// state->offset = synctest_pos;
|
|
||||||
// state->max = ((state->max) + lmax) / 2;
|
|
||||||
// state->min = ((state->min) + lmin) / 2;
|
|
||||||
// state->lastsynctype = 28;
|
|
||||||
// state->last_cc_sync_time = time(NULL);
|
|
||||||
|
|
||||||
// // if (opts->payload == 1)
|
|
||||||
// // fprintf (stderr, "\n +PANDF ");
|
|
||||||
// // if (opts->payload == 1)
|
|
||||||
// // fprintf (stderr, " %s \n", synctest19);
|
|
||||||
// return (28);
|
|
||||||
// }
|
|
||||||
// else if (
|
|
||||||
|
|
||||||
// (strcmp (synctest19, "1313311133131331131") == 0 )
|
|
||||||
// || (strcmp (synctest19, "1313311133331331131") == 0 )
|
|
||||||
// || (strcmp (synctest19, "1313311133131331111") == 0 )
|
|
||||||
// || (strcmp (synctest19, "1313311133331331111") == 0 )
|
|
||||||
|
|
||||||
// )
|
|
||||||
// {
|
|
||||||
// // state->carrier = 1;
|
|
||||||
// state->carrier = 1;
|
|
||||||
// state->offset = synctest_pos;
|
|
||||||
// state->max = ((state->max) + lmax) / 2;
|
|
||||||
// state->min = ((state->min) + lmin) / 2;
|
|
||||||
// state->lastsynctype = 29;
|
|
||||||
// state->last_cc_sync_time = time(NULL);
|
|
||||||
|
|
||||||
// // if (opts->payload == 1)
|
|
||||||
// // fprintf (stderr, "\n -PANDF ");
|
|
||||||
// // if (opts->payload == 1)
|
|
||||||
// // fprintf (stderr, " %s \n", synctest19);
|
|
||||||
// return (29);
|
|
||||||
// }
|
|
||||||
// else if (
|
|
||||||
if (
|
|
||||||
(strcmp (synctest10, "3131331131") == 0 ) //this seems to be the most common 'correct' pattern on Type-C
|
|
||||||
|| (strcmp (synctest10, "3331331131") == 0 ) //this one hits on new sync but gives a bad lich code
|
|
||||||
|| (strcmp (synctest10, "3131331111") == 0 )
|
|
||||||
|| (strcmp (synctest10, "3331331111") == 0 )
|
|
||||||
|| (strcmp (synctest10, "3131311131") == 0 ) //First few FSW on NXDN48 Type-C seems to hit this for some reason
|
|
||||||
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
// state->carrier = 1;
|
|
||||||
state->offset = synctest_pos;
|
|
||||||
state->max = ((state->max) + lmax) / 2;
|
|
||||||
state->min = ((state->min) + lmin) / 2;
|
|
||||||
// state->last_cc_sync_time = time(NULL);
|
|
||||||
|
|
||||||
if (state->lastsynctype == 28)
|
|
||||||
{
|
|
||||||
state->last_cc_sync_time = time(NULL);
|
|
||||||
// if (opts->payload == 1)
|
|
||||||
// fprintf (stderr, "\n +FSW ");
|
|
||||||
// if (opts->payload == 1)
|
|
||||||
// fprintf (stderr, " %s \n", synctest10);
|
|
||||||
return (28);
|
|
||||||
}
|
|
||||||
state->lastsynctype = 28;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (
|
|
||||||
|
|
||||||
(strcmp (synctest10, "1313113313") == 0 )
|
|
||||||
|| (strcmp (synctest10, "1113113313") == 0 )
|
|
||||||
|| (strcmp (synctest10, "1313113333") == 0 )
|
|
||||||
|| (strcmp (synctest10, "1113113333") == 0 )
|
|
||||||
|| (strcmp (synctest10, "1313133313") == 0 ) //
|
|
||||||
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
// state->carrier = 1;
|
|
||||||
state->offset = synctest_pos;
|
|
||||||
state->max = ((state->max) + lmax) / 2;
|
|
||||||
state->min = ((state->min) + lmin) / 2;
|
|
||||||
// state->last_cc_sync_time = time(NULL);
|
|
||||||
|
|
||||||
if (state->lastsynctype == 29)
|
|
||||||
{
|
|
||||||
state->last_cc_sync_time = time(NULL);
|
|
||||||
// if (opts->payload == 1)
|
|
||||||
// fprintf (stderr, "\n -FSW ");
|
|
||||||
// if (opts->payload == 1)
|
|
||||||
// fprintf (stderr, " %s \n", synctest10);
|
|
||||||
return (29);
|
|
||||||
}
|
|
||||||
state->lastsynctype = 29;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //NXDN Sync Type Selection
|
#endif //NXDN Sync Type Selection
|
||||||
|
|
||||||
//Provoice Conventional -- Some False Positives due to shortened frame sync pattern, so use squelch if possible
|
//Provoice Conventional -- Some False Positives due to shortened frame sync pattern, so use squelch if possible
|
||||||
@@ -1574,8 +1551,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
|||||||
}
|
}
|
||||||
#endif //End Provoice Conventional
|
#endif //End Provoice Conventional
|
||||||
|
|
||||||
SYNC_TEST_END: ; //do nothing
|
|
||||||
|
|
||||||
} // t >= 10
|
} // t >= 10
|
||||||
|
|
||||||
if (exitflag == 1)
|
if (exitflag == 1)
|
||||||
|
|||||||
@@ -146,8 +146,7 @@ int csvChanImport(dsd_opts * opts, dsd_state * state) //channel map import
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Decimal Variant of Key Import
|
int csvKeyImport(dsd_opts * opts, dsd_state * state) //multi-key support
|
||||||
int csvKeyImportDec(dsd_opts * opts, dsd_state * state) //multi-key support
|
|
||||||
{
|
{
|
||||||
char filename[1024] = "filename.csv";
|
char filename[1024] = "filename.csv";
|
||||||
sprintf (filename, "%s", opts->key_in_file);
|
sprintf (filename, "%s", opts->key_in_file);
|
||||||
@@ -211,48 +210,3 @@ int csvKeyImportDec(dsd_opts * opts, dsd_state * state) //multi-key support
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Hex Variant of Key Import
|
|
||||||
int csvKeyImportHex(dsd_opts * opts, dsd_state * state) //key import for rc4 keys
|
|
||||||
{
|
|
||||||
char filename[1024] = "filename.csv";
|
|
||||||
sprintf (filename, "%s", opts->key_in_file);
|
|
||||||
char buffer[BSIZE];
|
|
||||||
FILE * fp;
|
|
||||||
fp = fopen(filename, "r");
|
|
||||||
if (fp == NULL) {
|
|
||||||
printf("Unable to open file '%s'\n", filename);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
int row_count = 0;
|
|
||||||
int field_count = 0;
|
|
||||||
unsigned long long int keynumber;
|
|
||||||
|
|
||||||
while (fgets(buffer, BSIZE, fp)) {
|
|
||||||
field_count = 0;
|
|
||||||
row_count++;
|
|
||||||
if (row_count == 1)
|
|
||||||
continue; //don't want labels
|
|
||||||
char * field = strtok(buffer, ","); //seperate by comma
|
|
||||||
while (field) {
|
|
||||||
|
|
||||||
if (field_count == 0)
|
|
||||||
{
|
|
||||||
sscanf (field, "%llX", &keynumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (field_count == 1)
|
|
||||||
{
|
|
||||||
sscanf (field, "%llX", &state->rkey_array[keynumber]);
|
|
||||||
}
|
|
||||||
|
|
||||||
field = strtok(NULL, ",");
|
|
||||||
field_count++;
|
|
||||||
}
|
|
||||||
fprintf (stderr, "Key [%04llX] [%016llX]", keynumber, state->rkey_array[keynumber]);
|
|
||||||
fprintf (stderr, "\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
fclose(fp);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|||||||
550
src/dsd_main.c
550
src/dsd_main.c
@@ -44,18 +44,6 @@ int pretty_colors()
|
|||||||
#include "p25p1_heuristics.h"
|
#include "p25p1_heuristics.h"
|
||||||
#include "pa_devs.h"
|
#include "pa_devs.h"
|
||||||
|
|
||||||
#ifdef LIMAZULUTWEAKS
|
|
||||||
char * FM_banner[9] = {
|
|
||||||
" ",
|
|
||||||
" ██████╗ ██████╗██████╗ ███╗ ███████╗",
|
|
||||||
" ██╔══██╗██╔════╝██╔══██╗ ███║ ╚════██║",
|
|
||||||
" ██║ ██║╚█████╗ ██║ ██║ Lima ███║ ███╔═╝",
|
|
||||||
" ██║ ██║ ╚═══██╗██║ ██║ Zulu ███║ ██╔══╝ ",
|
|
||||||
" ██████╔╝██████╔╝██████╔╝ Edition V ████████╗███████╗",
|
|
||||||
" ╚═════╝ ╚═════╝ ╚═════╝ ╚═══════╝╚══════╝",
|
|
||||||
" "
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
char * FM_banner[9] = {
|
char * FM_banner[9] = {
|
||||||
" ",
|
" ",
|
||||||
" ██████╗ ██████╗██████╗ ███████╗███╗ ███╗███████╗",
|
" ██████╗ ██████╗██████╗ ███████╗███╗ ███╗███████╗",
|
||||||
@@ -66,7 +54,6 @@ char * FM_banner[9] = {
|
|||||||
" ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝",
|
" ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝",
|
||||||
" "
|
" "
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
int comp (const void *a, const void *b)
|
int comp (const void *a, const void *b)
|
||||||
{
|
{
|
||||||
@@ -90,29 +77,10 @@ void
|
|||||||
noCarrier (dsd_opts * opts, dsd_state * state)
|
noCarrier (dsd_opts * opts, dsd_state * state)
|
||||||
{
|
{
|
||||||
|
|
||||||
//clear heuristics from last carrier signal
|
|
||||||
if (opts->frame_p25p1 == 1 && opts->use_heuristics == 1)
|
|
||||||
{
|
|
||||||
initialize_p25_heuristics(&state->p25_heuristics);
|
|
||||||
initialize_p25_heuristics(&state->inv_p25_heuristics);
|
|
||||||
}
|
|
||||||
|
|
||||||
//only do it here on the tweaks
|
|
||||||
#ifdef LIMAZULUTWEAKS
|
|
||||||
state->nxdn_last_ran = -1;
|
|
||||||
state->nxdn_last_rid = 0;
|
|
||||||
state->nxdn_last_tg = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//experimental conventional frequency scanner mode
|
//experimental conventional frequency scanner mode
|
||||||
if (opts->scanner_mode == 1 && ( (time(NULL) - state->last_cc_sync_time) > opts->trunk_hangtime))
|
if (opts->scanner_mode == 1 && ( (time(NULL) - state->last_cc_sync_time) > opts->trunk_hangtime))
|
||||||
{
|
{
|
||||||
|
|
||||||
//always do these -- makes sense during scanning
|
|
||||||
state->nxdn_last_ran = -1;
|
|
||||||
state->nxdn_last_rid = 0;
|
|
||||||
state->nxdn_last_tg = 0;
|
|
||||||
|
|
||||||
if (state->lcn_freq_roll >= state->lcn_freq_count)
|
if (state->lcn_freq_roll >= state->lcn_freq_count)
|
||||||
{
|
{
|
||||||
state->lcn_freq_roll = 0; //reset to zero
|
state->lcn_freq_roll = 0; //reset to zero
|
||||||
@@ -126,16 +94,13 @@ noCarrier (dsd_opts * opts, dsd_state * state)
|
|||||||
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
||||||
SetFreq(opts->rigctl_sockfd, state->trunk_lcn_freq[state->lcn_freq_roll]);
|
SetFreq(opts->rigctl_sockfd, state->trunk_lcn_freq[state->lcn_freq_roll]);
|
||||||
}
|
}
|
||||||
//rtl
|
//rtludp
|
||||||
if (opts->audio_in_type == 3)
|
if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune (opts, state, state->trunk_lcn_freq[state->lcn_freq_roll]);
|
||||||
rtl_dev_tune(opts, state->trunk_lcn_freq[state->lcn_freq_roll]);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//print here not working as it should -- not always a -1 value on lastsynctype I presume
|
if (state->lastsynctype != -1) fprintf (stderr, "Resume Scanning Mode\n");
|
||||||
// if (state->lastsynctype != -1) fprintf (stderr, "Resume Scanning Mode\n");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
state->lcn_freq_roll++;
|
state->lcn_freq_roll++;
|
||||||
@@ -164,29 +129,25 @@ noCarrier (dsd_opts * opts, dsd_state * state)
|
|||||||
SetFreq(opts->rigctl_sockfd, state->p25_cc_freq);
|
SetFreq(opts->rigctl_sockfd, state->p25_cc_freq);
|
||||||
state->dmr_rest_channel = -1; //maybe?
|
state->dmr_rest_channel = -1; //maybe?
|
||||||
}
|
}
|
||||||
//rtl
|
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3) //rtl_fm tuning
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
//UDP command to tune the RTL dongle
|
||||||
rtl_dev_tune (opts, state->p25_cc_freq);
|
rtl_udp_tune(opts, state, state->p25_cc_freq);
|
||||||
state->dmr_rest_channel = -1;
|
state->dmr_rest_channel = -1; //maybe?
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
opts->p25_is_tuned = 0;
|
opts->p25_is_tuned = 0;
|
||||||
state->edacs_tuned_lcn = -1;
|
state->edacs_tuned_lcn = -1;
|
||||||
|
|
||||||
//only for EDACS/PV
|
//only for EDACS/PV
|
||||||
if (opts->p25_trunk == 1 && opts->frame_provoice == 1 && opts->wav_out_file != NULL)
|
if (opts->frame_provoice == 1 && opts->wav_out_file != NULL)
|
||||||
{
|
{
|
||||||
closeWavOutFile(opts, state);
|
closeWavOutFile(opts, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
state->last_cc_sync_time = time(NULL);
|
state->last_cc_sync_time = time(NULL);
|
||||||
//test to switch back to 10/4 P1 QPSK for P25 FDMA CC
|
//test to switch back to 10/4 P1 QPSK for P25 FDMA CC
|
||||||
|
if (opts->mod_qpsk == 1 && state->p25_cc_is_tdma == 0)
|
||||||
//reworked to always change back to 10/4 if p25_cc_is_tdma is set to 0 or 1 (inits on 2)
|
|
||||||
if (state->p25_cc_is_tdma == 0) //is set on signal from P25 TSBK or MAC_SIGNAL
|
|
||||||
{
|
{
|
||||||
state->samplesPerSymbol = 10;
|
state->samplesPerSymbol = 10;
|
||||||
state->symbolCenter = 4;
|
state->symbolCenter = 4;
|
||||||
@@ -374,8 +335,7 @@ noCarrier (dsd_opts * opts, dsd_state * state)
|
|||||||
//unload keys when using keylaoder
|
//unload keys when using keylaoder
|
||||||
if (state->keyloader == 1)
|
if (state->keyloader == 1)
|
||||||
{
|
{
|
||||||
state->R = 0; //NXDN, or RC4 (slot 1)
|
state->R = 0; //NXDN
|
||||||
state->RR = 0; //RC4 (slot 2)
|
|
||||||
state->K = 0; //BP
|
state->K = 0; //BP
|
||||||
state->K1 = 0; //tera 10 char BP
|
state->K1 = 0; //tera 10 char BP
|
||||||
state->H = 0; //shim for above
|
state->H = 0; //shim for above
|
||||||
@@ -463,16 +423,11 @@ initOpts (dsd_opts * opts)
|
|||||||
opts->p25status = 0;
|
opts->p25status = 0;
|
||||||
opts->p25tg = 0;
|
opts->p25tg = 0;
|
||||||
opts->scoperate = 15;
|
opts->scoperate = 15;
|
||||||
#ifdef AERO_BUILD
|
|
||||||
sprintf (opts->audio_in_dev, "/dev/dsp");
|
|
||||||
sprintf (opts->audio_out_dev, "/dev/dsp");
|
|
||||||
#else
|
|
||||||
sprintf (opts->audio_in_dev, "pulse");
|
sprintf (opts->audio_in_dev, "pulse");
|
||||||
sprintf (opts->audio_out_dev, "pulse");
|
|
||||||
#endif
|
|
||||||
opts->audio_in_fd = -1;
|
opts->audio_in_fd = -1;
|
||||||
|
|
||||||
|
sprintf (opts->audio_out_dev, "pulse");
|
||||||
opts->audio_out_fd = -1;
|
opts->audio_out_fd = -1;
|
||||||
opts->audio_out_fdR = -1;
|
|
||||||
|
|
||||||
opts->split = 0;
|
opts->split = 0;
|
||||||
opts->playoffset = 0;
|
opts->playoffset = 0;
|
||||||
@@ -534,18 +489,14 @@ initOpts (dsd_opts * opts)
|
|||||||
opts->delay = 0;
|
opts->delay = 0;
|
||||||
opts->use_cosine_filter = 1;
|
opts->use_cosine_filter = 1;
|
||||||
opts->unmute_encrypted_p25 = 0;
|
opts->unmute_encrypted_p25 = 0;
|
||||||
//all RTL user options -- enabled AGC by default due to weak signal related issues
|
|
||||||
opts->rtl_dev_index = 0; //choose which device we want by index number
|
opts->rtl_dev_index = 0; //choose which device we want by index number
|
||||||
opts->rtl_gain_value = 0; //mid value, 0 - AGC - 0 to 49 acceptable values
|
opts->rtl_gain_value = 26; //mid value, 0 - AGC (not recommended) 49 highest value
|
||||||
opts->rtl_squelch_level = 100; //100 by default, but only affects NXDN and dPMR during framesync test, compared to RMS value
|
opts->rtl_squelch_level = 0; //fully open by default, want to specify level for things like NXDN with false positives
|
||||||
opts->rtl_volume_multiplier = 1; //sample multiplier; This multiplies the sample value to produce a higher 'inlvl' (probably best left unused)
|
opts->rtl_volume_multiplier = 1; //sample multiplier; 1 seems like a good value
|
||||||
opts->rtl_udp_port = 0; //set UDP port for RTL remote -- 0 by default, will be making this optional for some external/legacy use cases (edacs-fm, etc)
|
opts->rtl_udp_port = 6020; //set UDP port for RTL remote
|
||||||
opts->rtl_bandwidth = 12; //default is 12, reverted back to normal on this (no inherent benefit)
|
opts->rtl_bandwidth = 12; //changed recommended default to 12, 24 for ProVoice
|
||||||
opts->rtlsdr_ppm_error = 0; //initialize ppm with 0 value;
|
opts->rtlsdr_ppm_error = 0; //initialize ppm with 0 value; bug reported by N.
|
||||||
opts->rtlsdr_center_freq = 850000000; //set to an initial value (if user is using a channel map, then they won't need to specify anything other than -i rtl if desired)
|
|
||||||
opts->rtl_started = 0;
|
opts->rtl_started = 0;
|
||||||
opts->rtl_rms = 0; //root means square power level on rtl input signal
|
|
||||||
//end RTL user options
|
|
||||||
opts->pulse_raw_rate_in = 48000;
|
opts->pulse_raw_rate_in = 48000;
|
||||||
opts->pulse_raw_rate_out = 48000; //
|
opts->pulse_raw_rate_out = 48000; //
|
||||||
opts->pulse_digi_rate_in = 48000;
|
opts->pulse_digi_rate_in = 48000;
|
||||||
@@ -564,24 +515,14 @@ initOpts (dsd_opts * opts)
|
|||||||
opts->use_ncurses_terminal = 0;
|
opts->use_ncurses_terminal = 0;
|
||||||
opts->ncurses_compact = 0;
|
opts->ncurses_compact = 0;
|
||||||
opts->ncurses_history = 1;
|
opts->ncurses_history = 1;
|
||||||
#ifdef LIMAZULUTWEAKS
|
|
||||||
opts->ncurses_compact = 1;
|
|
||||||
#endif
|
|
||||||
opts->payload = 0;
|
opts->payload = 0;
|
||||||
opts->inverted_dpmr = 0;
|
opts->inverted_dpmr = 0;
|
||||||
opts->dmr_mono = 0;
|
opts->dmr_mono = 0;
|
||||||
opts->dmr_stereo = 1;
|
opts->dmr_stereo = 1;
|
||||||
opts->aggressive_framesync = 1;
|
opts->aggressive_framesync = 1; //more aggressive to combat wonk wonk voice decoding
|
||||||
|
//see if initializing these values causes issues elsewhere, if so, then disable.
|
||||||
//this may not matter so much, since its already checked later on
|
opts->audio_in_type = 0; //this was never initialized, causes issues on rPI 64 (bullseye) if not initialized
|
||||||
//but better safe than sorry I guess
|
opts->audio_out_type = 0; //this was never initialized, causes issues on rPI 64 (bullseye) if not initialized
|
||||||
#ifdef AERO_BUILD
|
|
||||||
opts->audio_in_type = 5;
|
|
||||||
opts->audio_out_type = 5;
|
|
||||||
#else
|
|
||||||
opts->audio_in_type = 0;
|
|
||||||
opts->audio_out_type = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
opts->lrrp_file_output = 0;
|
opts->lrrp_file_output = 0;
|
||||||
|
|
||||||
@@ -644,19 +585,10 @@ initOpts (dsd_opts * opts)
|
|||||||
|
|
||||||
opts->dPMR_next_part_of_superframe = 0;
|
opts->dPMR_next_part_of_superframe = 0;
|
||||||
|
|
||||||
//OSS audio - Slot Preference
|
|
||||||
//slot preference is used during OSS audio playback to
|
|
||||||
//prefer one tdma voice slot over another when both are playing back
|
|
||||||
//this is a fix to cygwin stuttering when both slots have voice
|
|
||||||
opts->slot_preference = 0; //default prefer slot 1 -- state->currentslot = 0;
|
|
||||||
|
|
||||||
//dsp structured file
|
//dsp structured file
|
||||||
opts->dsp_out_file[0] = 0;
|
opts->dsp_out_file[0] = 0;
|
||||||
opts->use_dsp_output = 0;
|
opts->use_dsp_output = 0;
|
||||||
|
|
||||||
//Use P25p1 heuristics
|
|
||||||
opts->use_heuristics = 0;
|
|
||||||
|
|
||||||
} //initopts
|
} //initopts
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -884,7 +816,7 @@ initState (dsd_state * state)
|
|||||||
state->p25_cc_is_tdma = 2; //init on 2, TSBK NET_STS will set 0, TDMA NET_STS will set 1. //used to determine if we need to change symbol rate when cc hunting
|
state->p25_cc_is_tdma = 2; //init on 2, TSBK NET_STS will set 0, TDMA NET_STS will set 1. //used to determine if we need to change symbol rate when cc hunting
|
||||||
|
|
||||||
//experimental symbol file capture read throttle
|
//experimental symbol file capture read throttle
|
||||||
state->symbol_throttle = 100; //throttle speed
|
state->symbol_throttle = 0; //throttle speed
|
||||||
state->use_throttle = 0; //only use throttle if set to 1
|
state->use_throttle = 0; //only use throttle if set to 1
|
||||||
|
|
||||||
state->p2_scramble_offset = 0;
|
state->p2_scramble_offset = 0;
|
||||||
@@ -894,6 +826,7 @@ initState (dsd_state * state)
|
|||||||
state->p25_chan_iden = 0;
|
state->p25_chan_iden = 0;
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
|
state->p25_chan_tdma[i] = -1; //0, or -1
|
||||||
state->p25_chan_type[i] = 0;
|
state->p25_chan_type[i] = 0;
|
||||||
state->p25_trans_off[i] = 0;
|
state->p25_trans_off[i] = 0;
|
||||||
state->p25_chan_spac[i] = 0;
|
state->p25_chan_spac[i] = 0;
|
||||||
@@ -997,7 +930,6 @@ initState (dsd_state * state)
|
|||||||
memset (state->late_entry_mi_fragment, 0, sizeof (state->late_entry_mi_fragment));
|
memset (state->late_entry_mi_fragment, 0, sizeof (state->late_entry_mi_fragment));
|
||||||
|
|
||||||
initialize_p25_heuristics(&state->p25_heuristics);
|
initialize_p25_heuristics(&state->p25_heuristics);
|
||||||
initialize_p25_heuristics(&state->inv_p25_heuristics);
|
|
||||||
|
|
||||||
state->dPMRVoiceFS2Frame.CalledIDOk = 0;
|
state->dPMRVoiceFS2Frame.CalledIDOk = 0;
|
||||||
state->dPMRVoiceFS2Frame.CallingIDOk = 0;
|
state->dPMRVoiceFS2Frame.CallingIDOk = 0;
|
||||||
@@ -1025,35 +957,17 @@ usage ()
|
|||||||
printf (" -Z Log MBE/PDU Payloads to console\n");
|
printf (" -Z Log MBE/PDU Payloads to console\n");
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf ("Input/Output options:\n");
|
printf ("Input/Output options:\n");
|
||||||
#ifdef AERO_BUILD
|
printf (" -i <device> Audio input device (default is pulse audio)\n");
|
||||||
printf (" -i <device> Audio input device (default is /dev/dsp)\n");
|
printf (" - for piped stdin\n");
|
||||||
printf (" pulse for pulse audio (will require pactl running in Cygwin)\n");
|
|
||||||
#else
|
|
||||||
printf (" -i <device> Audio input device (default is pulse)\n");
|
|
||||||
printf (" /dev/dsp for OSS audio (Depreciated: Will require padsp wrapper in Linux) \n");
|
|
||||||
#endif
|
|
||||||
printf (" rtl for rtl dongle (Default Values -- see below)\n");
|
|
||||||
printf (" rtl:dev:freq:gain:ppm:bw:sq:udp for rtl dongle (see below)\n");
|
printf (" rtl:dev:freq:gain:ppm:bw:sq:udp for rtl dongle (see below)\n");
|
||||||
printf (" tcp for tcp client SDR++/GNURadio Companion/Other (Port 7355)\n");
|
printf (" tcp for tcp client SDR++/GNURadio Companion/Other (Port 7355)\n");
|
||||||
printf (" tcp:192.168.7.5:7355 for custom address and port \n");
|
printf (" tcp:192.168.7.5:7355 for custom address and port \n");
|
||||||
printf (" filename.bin for OP25/FME capture bin files\n");
|
printf (" filename.bin for OP25/FME capture bin files\n");
|
||||||
printf (" filename.wav for 48K/1 wav files (SDR++, GQRX)\n");
|
printf (" filename.wav for 48K/1 wav files (SDR++, GQRX)\n");
|
||||||
printf (" filename.wav -s 96000 for 96K/1 wav files (DSDPlus)\n");
|
printf (" filename.wav -s 96000 for 96K/1 wav files (DSDPlus)\n");
|
||||||
#ifdef AERO_BUILD
|
|
||||||
printf (" (Use single quotes '\\directory\\audio file.wav' when directories/spaces are present)\n");
|
|
||||||
#else
|
|
||||||
printf (" (Use single quotes '/directory/audio file.wav' when directories/spaces are present)\n");
|
printf (" (Use single quotes '/directory/audio file.wav' when directories/spaces are present)\n");
|
||||||
#endif
|
|
||||||
// printf (" (Windows - '\directory\audio file.wav' backslash, not forward slash)\n");
|
|
||||||
printf (" -s <rate> Sample Rate of wav input files (48000 or 96000) Mono only!\n");
|
printf (" -s <rate> Sample Rate of wav input files (48000 or 96000) Mono only!\n");
|
||||||
#ifdef AERO_BUILD
|
printf (" -o <device> Audio output device (default is pulse audio)(null for no audio output)\n");
|
||||||
printf (" -o <device> Audio output device (default is /dev/dsp)\n");
|
|
||||||
printf (" pulse for pulse audio (will require pactl running in Cygwin)\n");
|
|
||||||
#else
|
|
||||||
printf (" -o <device> Audio output device (default is pulse)\n");
|
|
||||||
printf (" /dev/dsp for OSS audio (Depreciated: Will require padsp wrapper in Linux) \n");
|
|
||||||
#endif
|
|
||||||
printf (" null for no audio output\n");
|
|
||||||
printf (" -d <dir> Create mbe data files, use this directory (TDMA version is experimental)\n");
|
printf (" -d <dir> Create mbe data files, use this directory (TDMA version is experimental)\n");
|
||||||
printf (" -r <files> Read/Play saved mbe data from file(s)\n");
|
printf (" -r <files> Read/Play saved mbe data from file(s)\n");
|
||||||
printf (" -g <num> Audio output gain (default = 0 = auto, disable = -1)\n");
|
printf (" -g <num> Audio output gain (default = 0 = auto, disable = -1)\n");
|
||||||
@@ -1064,33 +978,31 @@ usage ()
|
|||||||
printf (" -a Enable Call Alert Beep (NCurses Terminal Only)\n");
|
printf (" -a Enable Call Alert Beep (NCurses Terminal Only)\n");
|
||||||
printf (" (Warning! Might be annoying.)\n");
|
printf (" (Warning! Might be annoying.)\n");
|
||||||
printf (" -L <file> Specify Filename for LRRP Data Output.\n");
|
printf (" -L <file> Specify Filename for LRRP Data Output.\n");
|
||||||
printf (" -Q <file> Specify Filename for OK-DMRlib Structured File Output. (placed in DSP folder)\n");
|
printf (" -Q <file> Specify Filename for DSP Structured File Output. (placed in DSP folder)\n");
|
||||||
printf (" -c <file> Output symbol capture to .bin file\n");
|
printf (" -c <file> Output symbol capture to .bin file\n");
|
||||||
printf (" -q Reverse Mute - Mute Unencrypted Voice and Unmute Encrypted Voice\n");
|
printf (" -q Reverse Mute - Mute Unencrypted Voice and Unmute Encrypted Voice\n");
|
||||||
printf (" -V Enable Audio Smoothing on Upsampled 48k/1 or 24k/2 Audio (Capital V)\n");
|
printf (" -V Enable Audio Smoothing on Upsampled 48k/1 or 24k/2 Audio (Capital V)\n");
|
||||||
printf (" (Audio Smoothing is now disabled on all upsampled output by default -- fix crackle/buzz bug)\n");
|
printf (" (Audio Smoothing is now disabled on all upsampled output by default -- fix crackle/buzz bug)\n");
|
||||||
printf (" -z Set TDMA Voice Slot Preference when using /dev/dsp audio output (prevent lag and stuttering)\n");
|
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf ("RTL-SDR options:\n");
|
printf ("RTL-SDR options:\n");
|
||||||
|
printf (" WARNING! Old CLI Switch Handling has been depreciated in favor of rtl:<parms>\n");
|
||||||
printf (" Usage: rtl:dev:freq:gain:ppm:bw:sq:udp\n");
|
printf (" Usage: rtl:dev:freq:gain:ppm:bw:sq:udp\n");
|
||||||
printf (" NOTE: all arguments after rtl are optional now for trunking, but user configuration is recommended\n");
|
|
||||||
printf (" dev <num> RTL-SDR Device Index Number\n");
|
printf (" dev <num> RTL-SDR Device Index Number\n");
|
||||||
printf (" freq <num> RTL-SDR Frequency (851800000 or 851.8M) \n");
|
printf (" freq <num> RTL-SDR Frequency (851800000 or 851.8M) \n");
|
||||||
printf (" gain <num> RTL-SDR Device Gain (0-49)(default = 0; Hardware AGC recommended)\n");
|
printf (" gain <num> RTL-SDR Device Gain (0-49)(default = 26)(0 = Hardware AGC, not recommended)\n");
|
||||||
printf (" ppm <num> RTL-SDR PPM Error (default = 0)\n");
|
printf (" ppm <num> RTL-SDR PPM Error (default = 0)\n");
|
||||||
printf (" bw <num> RTL-SDR Bandwidth kHz (default = 12)(4, 6, 8, 12, 16, 24) \n");
|
printf (" bw <num> RTL-SDR VFO Bandwidth kHz (default = 12)(6, 8, 12, 24) \n");
|
||||||
printf (" sq <num> RTL-SDR Squelch Level vs RMS Value (Optional)\n");
|
printf (" sq <num> RTL-SDR Squelch Level (0 - Open, 25 - Little, 50 - Higher)\n");
|
||||||
printf (" udp <num> RTL-SDR Legacy UDP Remote Port (Optional -- External Use Only)\n");
|
printf (" udp <num> RTL-SDR UDP Remote Port (default = 6020)\n");
|
||||||
printf (" Example: dsd-fme -fs -i rtl -C cap_plus_channel.csv -T\n");
|
printf (" Example: dsd-fme -fp -i rtl:0:851.375M:22:-2:12:0:6021\n");
|
||||||
printf (" Example: dsd-fme -fp -i rtl:0:851.375M:22:-2:24:0:6021\n");
|
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf ("Decoder options:\n");
|
printf ("Decoder options:\n");
|
||||||
printf (" -fa Legacy Auto Detection (old methods default)\n");
|
printf (" -fa Legacy Auto Detection 8k/1 (old methods default)\n");
|
||||||
printf (" -ft XDMA P25 and DMR BS/MS frame types (new default)\n");
|
printf (" -ft XDMA P25 and DMR BS/MS frame types (new default)\n");
|
||||||
printf (" -fs DMR Stereo BS and MS Simplex\n");
|
printf (" -fs DMR Stereo BS and MS Simplex\n");
|
||||||
printf (" -f1 Decode only P25 Phase 1\n");
|
printf (" -f1 Decode only P25 Phase 1\n");
|
||||||
printf (" -f2 Decode only P25 Phase 2 (6000 sps) **\n");
|
|
||||||
printf (" -fd Decode only D-STAR\n");
|
printf (" -fd Decode only D-STAR\n");
|
||||||
|
printf (" -fr Decode only DMR Mono - Single Slot Voice\n");
|
||||||
printf (" -fx Decode only X2-TDMA\n");
|
printf (" -fx Decode only X2-TDMA\n");
|
||||||
printf (" -fi Decode only NXDN48* (6.25 kHz) / IDAS*\n");
|
printf (" -fi Decode only NXDN48* (6.25 kHz) / IDAS*\n");
|
||||||
printf (" -fn Decode only NXDN96* (12.5 kHz)\n");
|
printf (" -fn Decode only NXDN96* (12.5 kHz)\n");
|
||||||
@@ -1103,7 +1015,6 @@ usage ()
|
|||||||
printf (" -xd Expect inverted ICOM dPMR signal\n");
|
printf (" -xd Expect inverted ICOM dPMR signal\n");
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf (" * denotes frame types that cannot be auto-detected.\n");
|
printf (" * denotes frame types that cannot be auto-detected.\n");
|
||||||
printf (" ** Phase 2 Single Frequency may require user to manually set WACN/SYSID/CC parameters if MAC_SIGNAL not present.\n");
|
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf ("Advanced Decoder options:\n");
|
printf ("Advanced Decoder options:\n");
|
||||||
printf (" -X <hex> Manually Set P2 Parameters (WACN, SYSID, CC/NAC)\n");
|
printf (" -X <hex> Manually Set P2 Parameters (WACN, SYSID, CC/NAC)\n");
|
||||||
@@ -1121,19 +1032,18 @@ usage ()
|
|||||||
printf (" -mc Use only C4FM modulation optimizations\n");
|
printf (" -mc Use only C4FM modulation optimizations\n");
|
||||||
printf (" -mg Use only GFSK modulation optimizations\n");
|
printf (" -mg Use only GFSK modulation optimizations\n");
|
||||||
printf (" -mq Use only QPSK modulation optimizations\n");
|
printf (" -mq Use only QPSK modulation optimizations\n");
|
||||||
printf (" -m2 Use P25p2 6000 sps QPSK modulation optimizations\n");
|
printf (" -m2 Use P25p2 6000 sps CQPSK modulation optimizations\n");
|
||||||
//printf (" (4 Level, not 8 Level LSM) (this is honestly unknown since I can't verify what local systems are using)\n");
|
//printf (" (4 Level, not 8 Level LSM) (this is honestly unknown since I can't verify what local systems are using)\n");
|
||||||
printf (" -F Relax P25 Phase 2 MAC_SIGNAL CRC Checksum Pass/Fail\n");
|
printf (" -F Relax P25 Phase 2 MAC_SIGNAL CRC Checksum Pass/Fail\n");
|
||||||
printf (" Use this feature to allow MAC_SIGNAL even if CRC errors.\n");
|
printf (" Use this feature to allow MAC_SIGNAL even if CRC errors.\n");
|
||||||
printf (" -F Relax DMR RAS/CRC CSBK/DATA Pass/Fail\n");
|
printf (" -F Relax DMR RAS/CRC CSBK/DATA Pass/Fail\n");
|
||||||
printf (" Enabling on some systems could lead to bad channel assignments/site data decoding if bad or marginal signal\n");
|
printf (" Enabling on some systems could lead to bad voice/data decoding if bad or marginal signal\n");
|
||||||
printf (" -F Relax NXDN SACCH/FACCH/CAC/F2U CRC Pass/Fail\n");
|
printf (" -F Relax NXDN SACCH/FACCH/CAC/F2U CRC Pass/Fail\n");
|
||||||
printf (" Not recommended on NXDN, but can be bypassed if desired.\n");
|
printf (" Not recommended on NXDN, but can be bypassed if desired.\n");
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf (" -b <dec> Manually Enter Basic Privacy Key (Decimal Value of Key Number)\n");
|
printf (" -K <dec> Manually Enter Basic Privacy Key (Decimal Value of Key Number)\n");
|
||||||
printf (" (NOTE: This used to be the 'K' option! \n");
|
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf (" -H <hex> Manually Enter **tera 10/32/64 Char Basic Privacy Hex Key (see example below)\n");
|
printf (" -H <hex> Manually Enter **tera 10/32/64 Char Privacy Hex Key (see example below)\n");
|
||||||
printf (" Encapulate in Single Quotation Marks; Space every 16 chars.\n");
|
printf (" Encapulate in Single Quotation Marks; Space every 16 chars.\n");
|
||||||
printf (" -H 0B57935150 \n");
|
printf (" -H 0B57935150 \n");
|
||||||
printf (" -H '736B9A9C5645288B 243AD5CB8701EF8A' \n");
|
printf (" -H '736B9A9C5645288B 243AD5CB8701EF8A' \n");
|
||||||
@@ -1141,18 +1051,10 @@ usage ()
|
|||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf (" -R <dec> Manually Enter dPMR or NXDN EHR Scrambler Key Value (Decimal Value)\n");
|
printf (" -R <dec> Manually Enter dPMR or NXDN EHR Scrambler Key Value (Decimal Value)\n");
|
||||||
printf (" \n");
|
printf (" \n");
|
||||||
printf (" -1 <hex> Manually Enter RC4 Key Value (DMR, P25) (Hex Value) \n");
|
printf (" -k <file> Import Key List from csv file.\n");
|
||||||
printf (" \n");
|
printf (" Only supports NXDN, DMR Basic Privacy and **tera 10-Char (decimal value) only. \n");
|
||||||
printf (" -k <file> Import Key List from csv file (Decimal Format) -- Lower Case 'k'.\n");
|
|
||||||
printf (" Only supports NXDN, DMR Basic Privacy (decimal value). \n");
|
|
||||||
printf (" (dPMR and **tera 32/64 char not supported, DMR uses TG value as key id -- EXPERIMENTAL!!). \n");
|
printf (" (dPMR and **tera 32/64 char not supported, DMR uses TG value as key id -- EXPERIMENTAL!!). \n");
|
||||||
printf (" \n");
|
printf (" -4 Force DMR Privacy Key over FID and SVC bits \n");
|
||||||
printf (" -K <file> Import Key List from csv file (Hexidecimal Format) -- Capital 'K'.\n");
|
|
||||||
printf (" Use for Hex Value **tera 10-char BP keys and RC4 10-Char Hex Keys. \n");
|
|
||||||
printf (" \n");
|
|
||||||
printf (" -4 Force Privacy Key over Encryption Identifiers (DMR BP and NXDN Scrambler) \n");
|
|
||||||
printf (" \n");
|
|
||||||
printf (" -0 Force RC4 Key over Missing PI header/LE Encryption Identifiers (DMR) \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");
|
||||||
@@ -1164,19 +1066,19 @@ usage ()
|
|||||||
printf (" Experimental -- Can only scan for sync with enabled decoders, don't mix NXDN and DMR/P25!\n");
|
printf (" Experimental -- Can only scan for sync with enabled decoders, don't mix NXDN and DMR/P25!\n");
|
||||||
printf (" This is not a Trunking Feature, just scans through conventional frequencies fast!\n");
|
printf (" This is not a Trunking Feature, just scans through conventional frequencies fast!\n");
|
||||||
printf (" -W Use Imported Group List as a Trunking Allow/White List -- Only Tune with Mode A\n");
|
printf (" -W Use Imported Group List as a Trunking Allow/White List -- Only Tune with Mode A\n");
|
||||||
printf (" -p Disable Tune to Private Calls (DMR TIII, P25, NXDN Type-C and Type-D)\n");
|
printf (" -p Disable Tune to Private Calls (DMR TIII and P25)\n");
|
||||||
printf (" -E Disable Tune to Group Calls (DMR TIII, Con+, Cap+, P25, NXDN Type-C, and Type-D)\n");
|
printf (" -E Disable Tune to Group Calls (DMR TIII, Con+, Cap+ and P25)\n");
|
||||||
printf (" -e Enable Tune to Data Calls (DMR TIII, Cap+, NXDN Type-C)\n");
|
printf (" (NOTE: NXDN and EDACS, simply disable trunking if desired) \n");
|
||||||
printf (" (NOTE: No Clear Distinction between Cap+ Private Voice Calls and Data Calls -- Both enabled with Data Calls \n");
|
printf (" -e Enable Tune to Data Calls (DMR TIII)\n");
|
||||||
printf (" (NOTE: P25 Data Channels Not Enabled (no handling) \n");
|
printf (" (NOTE: P25 Data Channels Not Enabled (no handling) \n");
|
||||||
printf (" -U <port> Enable RIGCTL/TCP; Set TCP Port for RIGCTL. (4532 on SDR++)\n");
|
printf (" -U <port> Enable RIGCTL/TCP; Set TCP Port for RIGCTL. (4532 on SDR++)\n");
|
||||||
printf (" -B <Hertz> Set RIGCTL Setmod Bandwidth in Hertz (0 - default - OFF)\n");
|
printf (" -B <Hertz> Set RIGCTL Setmod Bandwidth in Hertz (0 - default - OFF)\n");
|
||||||
printf (" P25 - 7000-12000; P25 (QPSK) - 12000; NXDN48 - 7000; NXDN96: 9000; DMR - 7000; EDACS/PV - 12500;\n");
|
printf (" P25 - 7000-12000; P25 (QPSK) - 12000; NXDN48 - 4000; DMR - 7000; EDACS/PV - 12500;\n");
|
||||||
printf (" May vary based on system stregnth, etc.\n");
|
printf (" May vary based on system stregnth, etc.\n");
|
||||||
printf (" -t <secs> Set Trunking or Fast Scan VC/sync loss hangtime in seconds. (default = 1 second)\n");
|
printf (" -t <secs> Set Trunking or Fast Scan VC/sync loss hangtime in seconds. (default = 1 second) (decimal values permitted) \n");
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf (" Trunking Example TCP: dsd-fme -fs -i tcp -U 4532 -T -C dmr_t3_chan.csv -G group.csv -N 2> log.ans\n");
|
printf (" Trunking Example TCP: dsd-fme -fs -i tcp -U 4532 -T -C dmr_t3_chan.csv -G group.csv -N 2> log.ans\n");
|
||||||
printf (" Trunking Example RTL: dsd-fme -fs -i rtl:0:450M:26:-2:8 -T -C connect_plus_chan.csv -G group.csv -N 2> log.ans\n");
|
printf (" Trunking Example RTL: dsd-fme -fs -i rtl:0:450M:26:-2:8:0:6020 -T -C connect_plus_chan.csv -G group.csv -N 2> log.ans\n");
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
exit (0);
|
exit (0);
|
||||||
}
|
}
|
||||||
@@ -1212,9 +1114,9 @@ if (opts->audio_in_type == 1)
|
|||||||
{
|
{
|
||||||
opts->pulse_digi_rate_out = 24000; //rtl needs 24000 by 2 channel for DMR TDMA Stereo output
|
opts->pulse_digi_rate_out = 24000; //rtl needs 24000 by 2 channel for DMR TDMA Stereo output
|
||||||
opts->pulse_digi_out_channels = 2; //minimal crackling 'may' be observed, not sure, can't test to see on DMR with RTL
|
opts->pulse_digi_out_channels = 2; //minimal crackling 'may' be observed, not sure, can't test to see on DMR with RTL
|
||||||
// fprintf (stderr, "RTL Audio Rate Out set to 24000 Khz/2 Channel \n");
|
fprintf (stderr, "RTL Audio Rate Out set to 24000 Khz/2 Channel \n");
|
||||||
}
|
}
|
||||||
// else fprintf (stderr, "RTL Audio Rate Out set to 48000 Khz/1 Channel \n");
|
else fprintf (stderr, "RTL Audio Rate Out set to 48000 Khz/1 Channel \n");
|
||||||
opts->pulse_raw_rate_out = 48000;
|
opts->pulse_raw_rate_out = 48000;
|
||||||
opts->pulse_raw_out_channels = 1;
|
opts->pulse_raw_out_channels = 1;
|
||||||
|
|
||||||
@@ -1235,7 +1137,6 @@ if (opts->audio_in_type == 0)
|
|||||||
|
|
||||||
if (opts->audio_out_type == 0)
|
if (opts->audio_out_type == 0)
|
||||||
{
|
{
|
||||||
// openPulseInput(opts); //test to see if we still randomly hang up in ncurses and tcp input if we open this and leave it opened
|
|
||||||
openPulseOutput(opts);
|
openPulseOutput(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1355,21 +1256,15 @@ main (int argc, char **argv)
|
|||||||
char versionstr[25];
|
char versionstr[25];
|
||||||
mbe_printVersion (versionstr);
|
mbe_printVersion (versionstr);
|
||||||
|
|
||||||
#ifdef LIMAZULUTWEAKS
|
|
||||||
fprintf (stderr," Digital Speech Decoder: LimaZulu Edition IV\n");
|
|
||||||
#else
|
|
||||||
fprintf (stderr," Digital Speech Decoder: Florida Man Edition\n");
|
fprintf (stderr," Digital Speech Decoder: Florida Man Edition\n");
|
||||||
#endif
|
for (short int i = 1; i < 8; i++) {
|
||||||
for (short int i = 1; i < 7; i++) {
|
//fprintf (stderr,"%s%s \n", FM_banner[i], KGRN); //cyan/blue text
|
||||||
fprintf (stderr,"%s\n", FM_banner[i]);
|
fprintf (stderr,"%s\n", FM_banner[i]); //cyan/blue tex
|
||||||
}
|
}
|
||||||
|
//fprintf (stderr,"%s", KNRM); //change back to normal
|
||||||
|
|
||||||
#ifdef AERO_BUILD
|
fprintf (stderr, "Github Build Version: %s \n", GIT_TAG);
|
||||||
fprintf (stderr, "Build Version: v2.1 Beta \n");
|
fprintf (stderr,"MBElib version %s\n", versionstr);
|
||||||
#else
|
|
||||||
fprintf (stderr, "Build Version: %s \n", GIT_TAG);
|
|
||||||
#endif
|
|
||||||
fprintf (stderr,"MBElib Version: %s\n", versionstr);
|
|
||||||
|
|
||||||
initOpts (&opts);
|
initOpts (&opts);
|
||||||
initState (&state);
|
initState (&state);
|
||||||
@@ -1378,7 +1273,7 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
exitflag = 0;
|
exitflag = 0;
|
||||||
|
|
||||||
while ((c = getopt (argc, argv, "haepPqs:t:v:z:i:o:d:c:g:nw:B:C:R:f:m:u:x:A:S:M:G:D:L:VU:YK:b:H:X:NQ:WrlZTF01:2:345:6:7:89:Ek:")) != -1)
|
while ((c = getopt (argc, argv, "haepPqs:t:v:zi:o:d:c:g:nw:B:C:R:f:m:u:x:A:S:M:G:D:L:VU:YK:H:X:NQ:WrlZTF01:2:345:6:7:89:Ek:")) != -1)
|
||||||
{
|
{
|
||||||
opterr = 0;
|
opterr = 0;
|
||||||
switch (c)
|
switch (c)
|
||||||
@@ -1386,51 +1281,23 @@ main (int argc, char **argv)
|
|||||||
case 'h':
|
case 'h':
|
||||||
usage ();
|
usage ();
|
||||||
exit (0);
|
exit (0);
|
||||||
|
|
||||||
case 'a':
|
case 'a':
|
||||||
opts.call_alert = 1;
|
opts.call_alert = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Free'd up switches include: I, J, j, n, O, v, y
|
//Free'd up switches include z
|
||||||
//all numerals have reclaimed, except for 4 and 0,1 (rc4 enforcement and single key)
|
|
||||||
|
|
||||||
//make sure to put a colon : after each if they need an argument
|
//make sure to put a colon : after each if they need an argument
|
||||||
//or remove colon if no argument required
|
//or remove colon if no argument required
|
||||||
|
|
||||||
//NOTE: The 'K' option for single BP key has been swapped to 'b'
|
|
||||||
//'K' is now used for hexidecimal key.csv imports
|
|
||||||
|
|
||||||
//rc4 enforcement on DMR (due to missing the PI header)
|
|
||||||
case '0':
|
|
||||||
state.M = 0x21;
|
|
||||||
fprintf (stderr,"Force RC4 Key over Missing PI header/LE Encryption Identifiers (DMR)\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
//load single rc4 key
|
|
||||||
case '1':
|
|
||||||
sscanf (optarg, "%llX", &state.R);
|
|
||||||
state.RR = state.R; //put key on both sides
|
|
||||||
fprintf (stderr, "RC4 Encryption Key Value set to 0x%llX \n", state.R);
|
|
||||||
opts.unmute_encrypted_p25 = 0;
|
|
||||||
state.keyloader = 0; //turn off keyloader
|
|
||||||
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
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'k': //multi-key loader (dec)
|
case 'k': //multi-key loader
|
||||||
strncpy(opts.key_in_file, optarg, 1023);
|
strncpy(opts.key_in_file, optarg, 1023);
|
||||||
opts.key_in_file[1023] = '\0';
|
opts.key_in_file[1023] = '\0';
|
||||||
csvKeyImportDec(&opts, &state);
|
csvKeyImport(&opts, &state);
|
||||||
state.keyloader = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'K': //multi-key loader (hex)
|
|
||||||
strncpy(opts.key_in_file, optarg, 1023);
|
|
||||||
opts.key_in_file[1023] = '\0';
|
|
||||||
csvKeyImportHex(&opts, &state);
|
|
||||||
state.keyloader = 1;
|
state.keyloader = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1451,14 +1318,8 @@ main (int argc, char **argv)
|
|||||||
opts.use_dsp_output = 1;
|
opts.use_dsp_output = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'z':
|
|
||||||
sscanf (optarg, "%d", &opts.slot_preference);
|
|
||||||
if (opts.slot_preference > 0) opts.slot_preference--; //user inputs 1 or 2, internally we want 0 and 1
|
|
||||||
if (opts.slot_preference > 1) opts.slot_preference = 1;
|
|
||||||
fprintf (stderr, "TDMA (DMR and P2) Slot Voice Preference is Slot %d. \n", opts.slot_preference+1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
//Enable Audio Smoothing for Upsampled Audio
|
//Enable Audio Smoothing for Upsampled Audio
|
||||||
|
case '0':
|
||||||
case 'V':
|
case 'V':
|
||||||
state.audio_smoothing = 1;
|
state.audio_smoothing = 1;
|
||||||
break;
|
break;
|
||||||
@@ -1496,23 +1357,28 @@ main (int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'C': //new letter assignment for Channel import, flow down to allow temp numbers
|
case 'C': //new letter assignment for Channel import, flow down to allow temp numbers
|
||||||
|
case '1': //LCN to Frequency CSV Import <--> flow down to chanimport now, tell users to use a channel map for edacs
|
||||||
|
case '7': //Channel Map Frequency CSV Import
|
||||||
strncpy(opts.chan_in_file, optarg, 1023);
|
strncpy(opts.chan_in_file, optarg, 1023);
|
||||||
opts.chan_in_file[1023] = '\0';
|
opts.chan_in_file[1023] = '\0';
|
||||||
csvChanImport (&opts, &state);
|
csvChanImport (&opts, &state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'G': //new letter assignment for group import, flow down to allow temp numbers
|
case 'G': //new letter assignment for group import, flow down to allow temp numbers
|
||||||
|
case '2': //Group CSV Import
|
||||||
strncpy(opts.group_in_file, optarg, 1023);
|
strncpy(opts.group_in_file, optarg, 1023);
|
||||||
opts.group_in_file[1023] = '\0';
|
opts.group_in_file[1023] = '\0';
|
||||||
csvGroupImport(&opts, &state);
|
csvGroupImport(&opts, &state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'T': //new letter assignment for trunking, flow down to allow temp numbers
|
case 'T': //new letter assignment for trunking, flow down to allow temp numbers
|
||||||
|
case '3':
|
||||||
opts.p25_trunk = 1;
|
opts.p25_trunk = 1;
|
||||||
opts.scanner_mode = 0; //turn off scanner mode if user enabled it
|
opts.scanner_mode = 0; //turn off scanner mode if user enabled it
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'U': //New letter assignment for RIGCTL TCP port, flow down to allow temp numbers
|
case 'U': //New letter assignment for RIGCTL TCP port, flow down to allow temp numbers
|
||||||
|
case '5': //RIGCTL TCP port
|
||||||
sscanf (optarg, "%d", &opts.rigctlportno);
|
sscanf (optarg, "%d", &opts.rigctlportno);
|
||||||
if (opts.rigctlportno != 0) opts.use_rigctl = 1;
|
if (opts.rigctlportno != 0) opts.use_rigctl = 1;
|
||||||
break;
|
break;
|
||||||
@@ -1522,16 +1388,19 @@ main (int argc, char **argv)
|
|||||||
//may change to a different return on sync times and this will matter!
|
//may change to a different return on sync times and this will matter!
|
||||||
|
|
||||||
case 't': //New letter assignment for Trunk Hangtime, flow down to allow temp numbers
|
case 't': //New letter assignment for Trunk Hangtime, flow down to allow temp numbers
|
||||||
|
case '6': //hangtime in seconds, default is 1;
|
||||||
sscanf (optarg, "%f", &opts.trunk_hangtime); //updated for float/decimal values
|
sscanf (optarg, "%f", &opts.trunk_hangtime); //updated for float/decimal values
|
||||||
fprintf (stderr, "Trunking or Fast Scanner Hang Time set to: %.02f sec\n", opts.trunk_hangtime);
|
fprintf (stderr, "Trunking or Fast Scanner Hang Time set to: %.02f sec\n", opts.trunk_hangtime);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'q': //New letter assignment for Reverse Mute, flow down to allow temp numbers
|
case 'q': //New letter assignment for Reverse Mute, flow down to allow temp numbers
|
||||||
|
case '8':
|
||||||
opts.reverse_mute = 1;
|
opts.reverse_mute = 1;
|
||||||
fprintf (stderr, "Reverse Mute\n");
|
fprintf (stderr, "Reverse Mute\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'B': //New letter assignment for RIGCTL SetMod BW, flow down to allow temp numbers
|
case 'B': //New letter assignment for RIGCTL SetMod BW, flow down to allow temp numbers
|
||||||
|
case '9': //rigctl setmod bandwidth;
|
||||||
sscanf (optarg, "%d", &opts.setmod_bw);
|
sscanf (optarg, "%d", &opts.setmod_bw);
|
||||||
if (opts.setmod_bw > 25000) opts.setmod_bw = 25000; //not too high
|
if (opts.setmod_bw > 25000) opts.setmod_bw = 25000; //not too high
|
||||||
break;
|
break;
|
||||||
@@ -1543,15 +1412,15 @@ main (int argc, char **argv)
|
|||||||
state.symbolCenter = state.symbolCenter * opts.wav_interpolator;
|
state.symbolCenter = state.symbolCenter * opts.wav_interpolator;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case 'v':
|
case 'v':
|
||||||
// sscanf (optarg, "%d", &opts.verbose);
|
sscanf (optarg, "%d", &opts.verbose);
|
||||||
// break;
|
break;
|
||||||
|
|
||||||
// case 'n': //disable or reclaim?
|
case 'n': //disable or reclaim?
|
||||||
// state.use_throttle = 1;
|
state.use_throttle = 1;
|
||||||
// break;
|
break;
|
||||||
|
|
||||||
case 'b': //formerly Capital 'K'
|
case 'K':
|
||||||
sscanf (optarg, "%lld", &state.K);
|
sscanf (optarg, "%lld", &state.K);
|
||||||
if (state.K > 256)
|
if (state.K > 256)
|
||||||
{
|
{
|
||||||
@@ -1595,7 +1464,7 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
case '4':
|
case '4':
|
||||||
state.M = 1;
|
state.M = 1;
|
||||||
fprintf (stderr,"Force Privacy Key over Encryption Identifiers (DMR BP and NXDN Scrambler) \n");
|
fprintf (stderr,"Force Privacy Key Priority over FID and SVC bits.\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//manually set Phase 2 TDMA WACN/SYSID/CC
|
//manually set Phase 2 TDMA WACN/SYSID/CC
|
||||||
@@ -1650,8 +1519,7 @@ main (int argc, char **argv)
|
|||||||
case 'F':
|
case 'F':
|
||||||
opts.aggressive_framesync = 0;
|
opts.aggressive_framesync = 0;
|
||||||
fprintf (stderr, "%s", KYEL);
|
fprintf (stderr, "%s", KYEL);
|
||||||
//fprintf (stderr,"DMR Stereo Aggressive Resync Disabled!\n");
|
fprintf (stderr, "Relax P25 Phase 2 MAC_SIGNAL CRC Pass/Fail\n");
|
||||||
fprintf (stderr, "Relax P25 Phase 2 MAC_SIGNAL CRC Checksum Pass/Fail\n");
|
|
||||||
fprintf (stderr, "Relax DMR RAS/CRC CSBK/DATA Pass/Fail\n");
|
fprintf (stderr, "Relax DMR RAS/CRC CSBK/DATA Pass/Fail\n");
|
||||||
fprintf (stderr, "Relax NXDN SACCH/FACCH/CAC/F2U CRC Pass/Fail\n");
|
fprintf (stderr, "Relax NXDN SACCH/FACCH/CAC/F2U CRC Pass/Fail\n");
|
||||||
fprintf (stderr, "%s", KNRM);
|
fprintf (stderr, "%s", KNRM);
|
||||||
@@ -1678,7 +1546,7 @@ main (int argc, char **argv)
|
|||||||
// fprintf (stderr,"Writing mbe data temporarily disabled!\n");
|
// fprintf (stderr,"Writing mbe data temporarily disabled!\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'c':
|
case 'c': //now is symbol capture bin output like FME Lite
|
||||||
strncpy(opts.symbol_out_file, optarg, 1023);
|
strncpy(opts.symbol_out_file, optarg, 1023);
|
||||||
opts.symbol_out_file[1023] = '\0';
|
opts.symbol_out_file[1023] = '\0';
|
||||||
fprintf (stderr,"Writing + Appending symbol capture to file %s\n", opts.symbol_out_file);
|
fprintf (stderr,"Writing + Appending symbol capture to file %s\n", opts.symbol_out_file);
|
||||||
@@ -1729,10 +1597,10 @@ main (int argc, char **argv)
|
|||||||
opts.frame_dpmr = 0;
|
opts.frame_dpmr = 0;
|
||||||
opts.frame_provoice = 0;
|
opts.frame_provoice = 0;
|
||||||
opts.frame_ysf = 0;
|
opts.frame_ysf = 0;
|
||||||
opts.pulse_digi_rate_out = 48000; // /dev/dsp does need this set to 48000 to properly process the upsampling
|
opts.pulse_digi_rate_out = 8000;
|
||||||
opts.pulse_digi_out_channels = 1;
|
opts.pulse_digi_out_channels = 1;
|
||||||
opts.dmr_stereo = 1; //switching in 'stereo' for 'mono'
|
opts.dmr_stereo = 0;
|
||||||
opts.dmr_mono = 0;
|
opts.dmr_mono = 1;
|
||||||
state.dmr_stereo = 0;
|
state.dmr_stereo = 0;
|
||||||
// opts.setmod_bw = 7000;
|
// opts.setmod_bw = 7000;
|
||||||
sprintf (opts.output_name, "Legacy Auto");
|
sprintf (opts.output_name, "Legacy Auto");
|
||||||
@@ -1805,9 +1673,6 @@ main (int argc, char **argv)
|
|||||||
sprintf (opts.output_name, "EDACS/PV");
|
sprintf (opts.output_name, "EDACS/PV");
|
||||||
fprintf (stderr,"Setting symbol rate to 9600 / second\n");
|
fprintf (stderr,"Setting symbol rate to 9600 / second\n");
|
||||||
fprintf (stderr,"Decoding only ProVoice frames.\n");
|
fprintf (stderr,"Decoding only ProVoice frames.\n");
|
||||||
//rtl specific tweaks
|
|
||||||
opts.rtl_bandwidth = 24;
|
|
||||||
// opts.rtl_gain_value = 36;
|
|
||||||
}
|
}
|
||||||
else if (optarg[0] == '1')
|
else if (optarg[0] == '1')
|
||||||
{
|
{
|
||||||
@@ -1834,8 +1699,7 @@ main (int argc, char **argv)
|
|||||||
// opts.setmod_bw = 12000;
|
// opts.setmod_bw = 12000;
|
||||||
opts.ssize = 36; //128 current default, fall back to old default on P1 only systems
|
opts.ssize = 36; //128 current default, fall back to old default on P1 only systems
|
||||||
opts.msize = 15; //1024 current default, fall back to old default on P1 only systems
|
opts.msize = 15; //1024 current default, fall back to old default on P1 only systems
|
||||||
opts.use_heuristics = 1; //enable for Phase 1 only
|
sprintf (opts.output_name, "P25P1");
|
||||||
sprintf (opts.output_name, "P25p1");
|
|
||||||
fprintf (stderr,"Decoding only P25 Phase 1 frames.\n");
|
fprintf (stderr,"Decoding only P25 Phase 1 frames.\n");
|
||||||
}
|
}
|
||||||
else if (optarg[0] == 'i')
|
else if (optarg[0] == 'i')
|
||||||
@@ -1906,8 +1770,8 @@ main (int argc, char **argv)
|
|||||||
opts.frame_dpmr = 0;
|
opts.frame_dpmr = 0;
|
||||||
opts.frame_provoice = 0;
|
opts.frame_provoice = 0;
|
||||||
opts.frame_ysf = 0;
|
opts.frame_ysf = 0;
|
||||||
state.samplesPerSymbol = 8;
|
state.samplesPerSymbol = 10;
|
||||||
state.symbolCenter = 3;
|
state.symbolCenter = 4;
|
||||||
opts.mod_c4fm = 1;
|
opts.mod_c4fm = 1;
|
||||||
opts.mod_qpsk = 0;
|
opts.mod_qpsk = 0;
|
||||||
opts.mod_gfsk = 0;
|
opts.mod_gfsk = 0;
|
||||||
@@ -1916,8 +1780,8 @@ main (int argc, char **argv)
|
|||||||
state.dmr_stereo = 0;
|
state.dmr_stereo = 0;
|
||||||
opts.dmr_mono = 0;
|
opts.dmr_mono = 0;
|
||||||
// opts.setmod_bw = 12000;
|
// opts.setmod_bw = 12000;
|
||||||
sprintf (opts.output_name, "P25p2");
|
sprintf (opts.output_name, "P25P2");
|
||||||
fprintf (stderr,"Decoding 6000 sps P25p2 frames only!\n");
|
fprintf (stderr,"Decoding P25-P2 frames C4FM or OP25 Symbol Captures!\n");
|
||||||
}
|
}
|
||||||
else if (optarg[0] == 's')
|
else if (optarg[0] == 's')
|
||||||
{
|
{
|
||||||
@@ -1942,7 +1806,6 @@ main (int argc, char **argv)
|
|||||||
opts.pulse_digi_rate_out = 24000;
|
opts.pulse_digi_rate_out = 24000;
|
||||||
opts.pulse_digi_out_channels = 2;
|
opts.pulse_digi_out_channels = 2;
|
||||||
sprintf (opts.output_name, "DMR Stereo");
|
sprintf (opts.output_name, "DMR Stereo");
|
||||||
|
|
||||||
fprintf (stderr,"Decoding DMR Stereo BS/MS Simplex\n");
|
fprintf (stderr,"Decoding DMR Stereo BS/MS Simplex\n");
|
||||||
}
|
}
|
||||||
else if (optarg[0] == 't')
|
else if (optarg[0] == 't')
|
||||||
@@ -2013,16 +1876,15 @@ main (int argc, char **argv)
|
|||||||
opts.mod_qpsk = 0;
|
opts.mod_qpsk = 0;
|
||||||
opts.mod_gfsk = 0; //
|
opts.mod_gfsk = 0; //
|
||||||
state.rf_mod = 0; //
|
state.rf_mod = 0; //
|
||||||
opts.pulse_digi_rate_out = 24000;
|
opts.pulse_digi_rate_out = 48000;
|
||||||
opts.pulse_digi_out_channels = 2;
|
opts.pulse_digi_out_channels = 1;
|
||||||
opts.dmr_mono = 0;
|
opts.dmr_mono = 1;
|
||||||
opts.dmr_stereo = 1;
|
opts.dmr_stereo = 0;
|
||||||
state.dmr_stereo = 0; //0
|
state.dmr_stereo = 0; //0
|
||||||
// opts.setmod_bw = 7000;
|
// opts.setmod_bw = 7000;
|
||||||
sprintf (opts.output_name, "DMR Stereo");
|
sprintf (opts.output_name, "DMR Mono");
|
||||||
fprintf (stderr,"-fr / DMR Mono switch has been deprecated.\n");
|
fprintf(stderr, "Notice: DMR cannot autodetect polarity. \n Use -xr option if Inverted Signal expected.\n");
|
||||||
fprintf (stderr,"Decoding DMR Stereo BS/MS Simplex\n");
|
fprintf (stderr,"Decoding only DMR Mono. \nUsing DMR Stereo or XDMA is highly encouraged.\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (optarg[0] == 'm')
|
else if (optarg[0] == 'm')
|
||||||
{
|
{
|
||||||
@@ -2096,7 +1958,7 @@ main (int argc, char **argv)
|
|||||||
state.samplesPerSymbol = 8;
|
state.samplesPerSymbol = 8;
|
||||||
state.symbolCenter = 3;
|
state.symbolCenter = 3;
|
||||||
// opts.setmod_bw = 12000;
|
// opts.setmod_bw = 12000;
|
||||||
fprintf (stderr,"Enabling 6000 sps P25p2 QPSK.\n");
|
fprintf (stderr,"Enabling 6000 sps P25p2 CQPSK.\n");
|
||||||
}
|
}
|
||||||
//test
|
//test
|
||||||
else if (optarg[0] == '3')
|
else if (optarg[0] == '3')
|
||||||
@@ -2232,25 +2094,19 @@ main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
opts.audio_in_type = 8;
|
opts.audio_in_type = 8;
|
||||||
state.audio_smoothing = 0; //disable smoothing to prevent random crackling/buzzing
|
state.audio_smoothing = 0; //disable smoothing to prevent random crackling/buzzing
|
||||||
fprintf (stderr, "TCP Connection Success!\n");
|
|
||||||
// openAudioInDevice(&opts); //do this to see if it makes it work correctly
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef AERO_BUILD
|
|
||||||
sprintf (opts.audio_in_dev, "%s", "/dev/dsp");
|
|
||||||
opts.audio_in_type = 5;
|
|
||||||
#else
|
|
||||||
sprintf (opts.audio_in_dev, "%s", "pulse");
|
|
||||||
fprintf (stderr, "TCP Connection Failure - Using %s Audio Input.\n", opts.audio_in_dev);
|
|
||||||
opts.audio_in_type = 0;
|
opts.audio_in_type = 0;
|
||||||
#endif
|
fprintf (stderr, "TCP Connection Failure - Using Pulse Audio Input.\n");
|
||||||
|
sprintf (opts.audio_in_dev, "%s", "pulse");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.use_rigctl == 1)
|
if (opts.use_rigctl == 1)
|
||||||
{
|
{
|
||||||
|
// opts.rigctl_sockfd = Connect(opts.rigctlhostname, opts.rigctlportno);
|
||||||
opts.rigctl_sockfd = Connect(opts.rigctlhostname, opts.rigctlportno);
|
opts.rigctl_sockfd = Connect(opts.rigctlhostname, opts.rigctlportno);
|
||||||
if (opts.rigctl_sockfd != 0) opts.use_rigctl = 1;
|
if (opts.rigctl_sockfd != 0) opts.use_rigctl = 1;
|
||||||
else
|
else
|
||||||
@@ -2293,12 +2149,12 @@ main (int argc, char **argv)
|
|||||||
int bw = 0;
|
int bw = 0;
|
||||||
bw = atoi (curr);
|
bw = atoi (curr);
|
||||||
//check for proper values (6,8,12,24)
|
//check for proper values (6,8,12,24)
|
||||||
if (bw == 4 || bw == 6 || bw == 8 || bw == 12 || bw == 16 || bw == 24) //testing 4 and 16 as well for weak and/or nxdn48 systems
|
if (bw == 6 || bw == 8 || bw == 12 || bw == 24)
|
||||||
{
|
{
|
||||||
opts.rtl_bandwidth = bw;
|
opts.rtl_bandwidth = bw;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
opts.rtl_bandwidth = 12; //safe default -- provides best performance on most systems
|
opts.rtl_bandwidth = 12; //safe default
|
||||||
}
|
}
|
||||||
else goto RTLEND;
|
else goto RTLEND;
|
||||||
|
|
||||||
@@ -2323,149 +2179,63 @@ main (int argc, char **argv)
|
|||||||
rtl_ok = 1;
|
rtl_ok = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef AERO_BUILD
|
|
||||||
if (rtl_ok == 0) //not set, means rtl support isn't compiled/available
|
if (rtl_ok == 0) //not set, means rtl support isn't compiled/available
|
||||||
{
|
{
|
||||||
fprintf (stderr, "RTL Support not enabled/compiled, falling back to OSS /dev/dsp Audio Input.\n");
|
fprintf (stderr, "RTL Support not enabled/compiled, falling back to Pulse Audio Input.\n");
|
||||||
sprintf (opts.audio_in_dev, "%s", "/dev/dsp");
|
|
||||||
opts.audio_in_type = 5;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (rtl_ok == 0) //not set, means rtl support isn't compiled/available
|
|
||||||
{
|
|
||||||
fprintf (stderr, "RTL Support not enabled/compiled, falling back to Pulse Audio Audio Input.\n");
|
|
||||||
sprintf (opts.audio_in_dev, "%s", "pulse");
|
sprintf (opts.audio_in_dev, "%s", "pulse");
|
||||||
opts.audio_in_type = 0;
|
opts.audio_in_type = 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//doesn't work correctly, so just going to reroute to /dev/dsp instead
|
//still need to work out why I can't use this
|
||||||
// if((strncmp(opts.audio_in_dev, "udp", 3) == 0)) //udp socket input from SDR++, GQRX, and others
|
//issues with samples received, may be using UDP DGRAMS incorrectly, incorrect procedure?
|
||||||
// {
|
if((strncmp(opts.audio_in_dev, "udp", 3) == 0)) //udp socket input from SDR++, GQRX, and others
|
||||||
// fprintf (stderr, "UDP Input not working, falling back to OSS /dev/dsp Audio Input.\n");
|
|
||||||
// sprintf (opts.audio_in_dev, "%s", "/dev/dsp");
|
|
||||||
// opts.audio_in_type = 5;
|
|
||||||
// }
|
|
||||||
|
|
||||||
int fmt;
|
|
||||||
int speed = 48000;
|
|
||||||
|
|
||||||
//NOTE: Both /dev/audio AND /dev/dsp randomly open multiple input streams in Linux under padsp wrapper
|
|
||||||
if((strncmp(opts.audio_in_dev, "/dev/audio", 10) == 0))
|
|
||||||
{
|
{
|
||||||
sprintf (opts.audio_in_dev, "%s", "/dev/dsp");
|
//also still needs err handling
|
||||||
fprintf (stderr, "Switching to /dev/dsp.\n");
|
opts.udp_sockfd = UDPBind(opts.udp_hostname, opts.udp_portno);
|
||||||
}
|
opts.audio_in_type = 6;
|
||||||
|
|
||||||
if((strncmp(opts.audio_in_dev, "pa", 2) == 0))
|
|
||||||
{
|
|
||||||
sprintf (opts.audio_in_dev, "%s", "/dev/dsp");
|
|
||||||
fprintf (stderr, "Switching to /dev/dsp.\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if((strncmp(opts.audio_in_dev, "/dev/dsp", 8) == 0))
|
if((strncmp(opts.audio_in_dev, "/dev/dsp", 8) == 0))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "OSS Input %s.\n", opts.audio_in_dev);
|
sprintf (opts.audio_in_dev, "%s", "pulse");
|
||||||
opts.audio_in_fd = open (opts.audio_in_dev, O_RDWR);
|
fprintf (stderr, "OSS and PA Handling Disabled; Using Pulse Audio.\n");
|
||||||
if (opts.audio_in_fd == -1)
|
opts.audio_in_type = 0;
|
||||||
{
|
|
||||||
fprintf (stderr, "Error, couldn't open %s\n", opts.audio_in_dev);
|
|
||||||
opts.audio_out = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt = 0;
|
if((strncmp(opts.audio_in_dev, "/dev/audio", 10) == 0))
|
||||||
if (ioctl (opts.audio_in_fd, SNDCTL_DSP_RESET) < 0)
|
|
||||||
{
|
{
|
||||||
fprintf (stderr, "ioctl reset error \n");
|
sprintf (opts.audio_in_dev, "%s", "pulse");
|
||||||
}
|
fprintf (stderr, "OSS and PA Handling Disabled; Using Pulse Audio.\n");
|
||||||
fmt = speed;
|
opts.audio_in_type = 0;
|
||||||
if (ioctl (opts.audio_in_fd, SNDCTL_DSP_SPEED, &fmt) < 0)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "ioctl speed error \n");
|
|
||||||
}
|
|
||||||
fmt = 0;
|
|
||||||
if (ioctl (opts.audio_in_fd, SNDCTL_DSP_STEREO, &fmt) < 0)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "ioctl stereo error \n");
|
|
||||||
}
|
|
||||||
fmt = AFMT_S16_LE;
|
|
||||||
if (ioctl (opts.audio_in_fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "ioctl setfmt error \n");
|
|
||||||
}
|
|
||||||
|
|
||||||
opts.audio_in_type = 5; //5 will become OSS input type
|
|
||||||
}
|
|
||||||
|
|
||||||
if((strncmp(opts.audio_out_dev, "/dev/audio", 10) == 0))
|
|
||||||
{
|
|
||||||
sprintf (opts.audio_out_dev, "%s", "/dev/dsp");
|
|
||||||
fprintf (stderr, "Switching to /dev/dsp.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if((strncmp(opts.audio_out_dev, "pa", 2) == 0))
|
|
||||||
{
|
|
||||||
sprintf (opts.audio_out_dev, "%s", "/dev/dsp");
|
|
||||||
fprintf (stderr, "Switching to /dev/dsp.\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if((strncmp(opts.audio_out_dev, "/dev/dsp", 8) == 0))
|
if((strncmp(opts.audio_out_dev, "/dev/dsp", 8) == 0))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "OSS Output %s.\n", opts.audio_out_dev);
|
sprintf (opts.audio_out_dev, "%s", "pulse");
|
||||||
opts.audio_out_fd = open (opts.audio_out_dev, O_RDWR); //O_WRONLY
|
fprintf (stderr, "OSS and PA Handling Disabled; Using Pulse Audio.\n");
|
||||||
opts.audio_out_fdR = open (opts.audio_out_dev, O_RDWR);
|
opts.audio_out_type = 0;
|
||||||
if (opts.audio_out_fd == -1)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "Error, couldn't open #1 %s\n", opts.audio_out_dev);
|
|
||||||
opts.audio_out = 0;
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.audio_out_fdR == -1)
|
if((strncmp(opts.audio_out_dev, "/dev/audio", 10) == 0))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Error, couldn't open #2 %s\n", opts.audio_out_dev);
|
sprintf (opts.audio_out_dev, "%s", "pulse");
|
||||||
opts.audio_out = 0;
|
fprintf (stderr, "OSS and PA Handling Disabled; Using Pulse Audio.\n");
|
||||||
exit(1);
|
opts.audio_out_type = 0;
|
||||||
}
|
|
||||||
fmt = 0;
|
|
||||||
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_RESET) < 0)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "ioctl reset error \n");
|
|
||||||
}
|
|
||||||
if (ioctl (opts.audio_out_fdR, SNDCTL_DSP_RESET) < 0)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "ioctl reset error \n");
|
|
||||||
}
|
|
||||||
fmt = speed;
|
|
||||||
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_SPEED, &fmt) < 0)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "ioctl speed error \n");
|
|
||||||
}
|
|
||||||
if (ioctl (opts.audio_out_fdR, SNDCTL_DSP_SPEED, &fmt) < 0)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "ioctl speed error \n");
|
|
||||||
}
|
|
||||||
fmt = 0;
|
|
||||||
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_STEREO, &fmt) < 0)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "ioctl stereo error \n");
|
|
||||||
}
|
|
||||||
if (ioctl (opts.audio_out_fdR, SNDCTL_DSP_STEREO, &fmt) < 0)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "ioctl stereo error \n");
|
|
||||||
}
|
|
||||||
fmt = AFMT_S16_LE;
|
|
||||||
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "ioctl setfmt error \n");
|
|
||||||
}
|
|
||||||
if (ioctl (opts.audio_out_fdR, SNDCTL_DSP_SETFMT, &fmt) < 0)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "ioctl setfmt error \n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
opts.audio_out_type = 5; //5 will become OSS output type
|
if((strncmp(opts.audio_out_dev, "pa", 2) == 0))
|
||||||
|
{
|
||||||
|
sprintf (opts.audio_out_dev, "%s", "pulse");
|
||||||
|
fprintf (stderr, "OSS and PA Handling Disabled; Using Pulse Audio.\n");
|
||||||
|
opts.audio_out_type = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((strncmp(opts.audio_in_dev, "pa", 2) == 0))
|
||||||
|
{
|
||||||
|
sprintf (opts.audio_in_dev, "%s", "pulse");
|
||||||
|
fprintf (stderr, "OSS and PA Handling Disabled; Using Pulse Audio.\n");
|
||||||
|
opts.audio_out_type = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((strncmp(opts.audio_in_dev, "pulse", 5) == 0))
|
if((strncmp(opts.audio_in_dev, "pulse", 5) == 0))
|
||||||
@@ -2490,50 +2260,50 @@ main (int argc, char **argv)
|
|||||||
opts.playoffset = 0;
|
opts.playoffset = 0;
|
||||||
opts.playoffsetR = 0;
|
opts.playoffsetR = 0;
|
||||||
opts.delay = 0;
|
opts.delay = 0;
|
||||||
|
if (strlen(opts.wav_out_file) > 0 && opts.dmr_stereo_wav == 0)
|
||||||
//open wav file should be handled directly by the -w switch now
|
{
|
||||||
// if (strlen(opts.wav_out_file) > 0 && opts.dmr_stereo_wav == 0)
|
openWavOutFile (&opts, &state);
|
||||||
// {
|
}
|
||||||
// openWavOutFile (&opts, &state);
|
else
|
||||||
// }
|
{
|
||||||
|
openAudioOutDevice (&opts, SAMPLE_RATE_OUT);
|
||||||
opts.pulse_digi_rate_out = 48000;
|
}
|
||||||
opts.pulse_digi_out_channels = 1;
|
|
||||||
if (opts.audio_out_type == 0) openPulseOutput(&opts);
|
|
||||||
if (opts.audio_out_type == 5) openAudioOutDevice (&opts, SAMPLE_RATE_OUT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//this particular if-elseif-else could be rewritten to be a lot neater and simpler
|
|
||||||
else if (strcmp (opts.audio_in_dev, opts.audio_out_dev) != 0)
|
else if (strcmp (opts.audio_in_dev, opts.audio_out_dev) != 0)
|
||||||
{
|
{
|
||||||
opts.split = 1;
|
opts.split = 1;
|
||||||
opts.playoffset = 0;
|
opts.playoffset = 0;
|
||||||
opts.playoffsetR = 0;
|
opts.playoffsetR = 0;
|
||||||
opts.delay = 0;
|
opts.delay = 0;
|
||||||
|
if (strlen(opts.wav_out_file) > 0 && opts.dmr_stereo_wav == 0)
|
||||||
//open wav file should be handled directly by the -w switch now
|
{
|
||||||
// if (strlen(opts.wav_out_file) > 0 && opts.dmr_stereo_wav == 0)
|
openWavOutFile (&opts, &state);
|
||||||
// openWavOutFile (&opts, &state);
|
}
|
||||||
|
else
|
||||||
// else
|
{
|
||||||
|
openAudioOutDevice (&opts, SAMPLE_RATE_OUT);
|
||||||
|
}
|
||||||
openAudioInDevice (&opts);
|
openAudioInDevice (&opts);
|
||||||
|
|
||||||
// fprintf (stderr,"Press CTRL + C to close.\n");
|
|
||||||
|
fprintf (stderr,"Press CTRL + C to close.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
opts.split = 0;
|
opts.split = 0;
|
||||||
opts.playoffset = 0; //not sure what the playoffset actually does for us
|
opts.playoffset = 25;
|
||||||
opts.playoffsetR = 0;
|
opts.playoffsetR = 25;
|
||||||
opts.delay = 0;
|
opts.delay = 0;
|
||||||
openAudioInDevice (&opts);
|
openAudioInDevice (&opts);
|
||||||
// opts.audio_out_fd = opts.audio_in_fd; //not sure that this really does much anymore, other than cause problems
|
opts.audio_out_fd = opts.audio_in_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.playfiles == 1)
|
if (opts.playfiles == 1)
|
||||||
{
|
{
|
||||||
|
opts.pulse_digi_rate_out = 48000;
|
||||||
|
opts.pulse_digi_out_channels = 1;
|
||||||
|
openPulseOutput(&opts); //need to open it up for output
|
||||||
state.aout_gain = 25; //BUGFIX: No audio output when playing back .amb/.imb files
|
state.aout_gain = 25; //BUGFIX: No audio output when playing back .amb/.imb files
|
||||||
playMbeFiles (&opts, &state, argc, argv);
|
playMbeFiles (&opts, &state, argc, argv);
|
||||||
}
|
}
|
||||||
|
|||||||
470
src/dsd_mbe.c
470
src/dsd_mbe.c
@@ -17,56 +17,6 @@
|
|||||||
|
|
||||||
#include "dsd.h"
|
#include "dsd.h"
|
||||||
|
|
||||||
//test for potential clashing with other key loading mechanisms (bp key loading on tgid, nxdn key loading, etc)
|
|
||||||
void keyring(dsd_opts * opts, dsd_state * state)
|
|
||||||
{
|
|
||||||
//keys now loaded from csv files with the -K key.csv file (capital K)
|
|
||||||
if (state->currentslot == 0)
|
|
||||||
state->R = state->rkey_array[state->payload_keyid];
|
|
||||||
|
|
||||||
if (state->currentslot == 1)
|
|
||||||
state->RR = state->rkey_array[state->payload_keyidR];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void RC4(int drop, uint8_t keylength, uint8_t messagelength, uint8_t key[], uint8_t cipher[], uint8_t plain[])
|
|
||||||
{
|
|
||||||
int i, j, count;
|
|
||||||
uint8_t t, b;
|
|
||||||
|
|
||||||
//init Sbox
|
|
||||||
uint8_t S[256];
|
|
||||||
for(int i = 0; i < 256; i++) S[i] = i;
|
|
||||||
|
|
||||||
//Key Scheduling
|
|
||||||
j = 0;
|
|
||||||
for(i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
j = (j + S[i] + key[i % keylength]) % 256;
|
|
||||||
t = S[i];
|
|
||||||
S[i] = S[j];
|
|
||||||
S[j] = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Drop Bytes and Cipher Byte XOR
|
|
||||||
i = j = 0;
|
|
||||||
for(count = 0; count < (messagelength + drop); count++)
|
|
||||||
{
|
|
||||||
i = (i + 1) % 256;
|
|
||||||
j = (j + S[i]) % 256;
|
|
||||||
t = S[i];
|
|
||||||
S[i] = S[j];
|
|
||||||
S[j] = t;
|
|
||||||
b = S[(S[i] + S[j]) % 256];
|
|
||||||
|
|
||||||
//return mbe payload byte here
|
|
||||||
if (count >= drop)
|
|
||||||
plain[count - drop] = b^cipher[count - drop];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int Pr[256] = {
|
int Pr[256] = {
|
||||||
0x0000, 0x1F00, 0xE300, 0xFC00, 0x2503, 0x3A03, 0xC603, 0xD903,
|
0x0000, 0x1F00, 0xE300, 0xFC00, 0x2503, 0x3A03, 0xC603, 0xD903,
|
||||||
0x4A05, 0x5505, 0xA905, 0xB605, 0x6F06, 0x7006, 0x8C06, 0x9306,
|
0x4A05, 0x5505, 0xA905, 0xB605, 0x6F06, 0x7006, 0x8C06, 0x9306,
|
||||||
@@ -190,21 +140,11 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
|||||||
unsigned long long int k;
|
unsigned long long int k;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
//these conditions should ensure no clashing with the BP/HBP/Scrambler key loading machanisms already coded in
|
|
||||||
if (state->currentslot == 0 && state->payload_algid != 0 && state->payload_algid != 0x80 && state->payload_keyid != 0 && state->keyloader == 1)
|
|
||||||
keyring (opts, state);
|
|
||||||
|
|
||||||
if (state->currentslot == 1 && state->payload_algidR != 0 && state->payload_algidR != 0x80 && state->payload_keyidR != 0 && state->keyloader == 1)
|
|
||||||
keyring (opts, state);
|
|
||||||
|
|
||||||
//24-bit TG to 16-bit hash
|
//24-bit TG to 16-bit hash
|
||||||
uint32_t hash = 0;
|
uint32_t hash = 0;
|
||||||
uint8_t hash_bits[24];
|
uint8_t hash_bits[24];
|
||||||
memset (hash_bits, 0, sizeof(hash_bits));
|
memset (hash_bits, 0, sizeof(hash_bits));
|
||||||
|
|
||||||
int preempt = 0; //TDMA dual voice slot preemption(when using OSS output)
|
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < 88; i++)
|
for (i = 0; i < 88; i++)
|
||||||
{
|
{
|
||||||
imbe_d[i] = 0;
|
imbe_d[i] = 0;
|
||||||
@@ -249,73 +189,7 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
|||||||
mbe_demodulateImbe7200x4400Data (imbe_fr);
|
mbe_demodulateImbe7200x4400Data (imbe_fr);
|
||||||
state->errs2 = mbe_eccImbe7200x4400Data (imbe_fr, imbe_d);
|
state->errs2 = mbe_eccImbe7200x4400Data (imbe_fr, imbe_d);
|
||||||
|
|
||||||
//P25p1 RC4 Handling
|
|
||||||
if (state->payload_algid == 0xAA && state->R != 0)
|
|
||||||
{
|
|
||||||
uint8_t cipher[11] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
uint8_t plain[11] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
uint8_t rckey[13] = {0x00, 0x00, 0x00, 0x00, 0x00, // <- RC4 Key
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, // <- MI
|
|
||||||
0x00, 0x00, 0x00}; // <- MI cont.
|
|
||||||
|
|
||||||
//easier to manually load up rather than make a loop
|
|
||||||
rckey[0] = ((state->R & 0xFF00000000) >> 32);
|
|
||||||
rckey[1] = ((state->R & 0xFF000000) >> 24);
|
|
||||||
rckey[2] = ((state->R & 0xFF0000) >> 16);
|
|
||||||
rckey[3] = ((state->R & 0xFF00) >> 8);
|
|
||||||
rckey[4] = ((state->R & 0xFF) >> 0);
|
|
||||||
|
|
||||||
// load valid MI from state->payload_miP
|
|
||||||
rckey[5] = ((state->payload_miP & 0xFF00000000000000) >> 56);
|
|
||||||
rckey[6] = ((state->payload_miP & 0xFF000000000000) >> 48);
|
|
||||||
rckey[7] = ((state->payload_miP & 0xFF0000000000) >> 40);
|
|
||||||
rckey[8] = ((state->payload_miP & 0xFF00000000) >> 32);
|
|
||||||
rckey[9] = ((state->payload_miP & 0xFF000000) >> 24);
|
|
||||||
rckey[10] = ((state->payload_miP & 0xFF0000) >> 16);
|
|
||||||
rckey[11] = ((state->payload_miP & 0xFF00) >> 8);
|
|
||||||
rckey[12] = ((state->payload_miP & 0xFF) >> 0);
|
|
||||||
|
|
||||||
// if (state->p25vc == 0)
|
|
||||||
// {
|
|
||||||
// fprintf (stderr, "%s", KYEL);
|
|
||||||
// fprintf (stderr, "\n RC4K ");
|
|
||||||
// for (short o = 0; o < 13; o++)
|
|
||||||
// {
|
|
||||||
// fprintf (stderr, "%02X", rckey[o]);
|
|
||||||
// }
|
|
||||||
// fprintf (stderr, "%s", KNRM);
|
|
||||||
// }
|
|
||||||
|
|
||||||
//load imbe_d into imbe_cipher octets
|
|
||||||
int z = 0;
|
|
||||||
for (i = 0; i < 11; i++)
|
|
||||||
{
|
|
||||||
cipher[i] = 0;
|
|
||||||
plain[i] = 0;
|
|
||||||
for (short int j = 0; j < 8; j++)
|
|
||||||
{
|
|
||||||
cipher[i] = cipher[i] << 1;
|
|
||||||
cipher[i] = cipher[i] + imbe_d[z];
|
|
||||||
imbe_d[z] = 0;
|
|
||||||
z++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RC4(state->dropL, 13, 11, rckey, cipher, plain);
|
|
||||||
state->dropL += 11;
|
|
||||||
|
|
||||||
z = 0;
|
|
||||||
for (short p = 0; p < 11; p++)
|
|
||||||
{
|
|
||||||
for (short o = 0; o < 8; o++)
|
|
||||||
{
|
|
||||||
imbe_d[z] = (plain[p] & 0x80) >> 7;
|
|
||||||
plain[p] = plain[p] << 1;
|
|
||||||
z++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
mbe_processImbe4400Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str,
|
mbe_processImbe4400Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str,
|
||||||
imbe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
imbe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||||
@@ -422,8 +296,8 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
|||||||
|
|
||||||
//EXPERIMENTAL!!
|
//EXPERIMENTAL!!
|
||||||
//load basic privacy key number from array by the tg value (if not forced)
|
//load basic privacy key number from array by the tg value (if not forced)
|
||||||
//currently only Moto BP and Hytera 10 Char BP
|
//currently only Moto BP and Hytera 10 Char BP (converted to decimal)
|
||||||
if (state->M == 0 && state->payload_algid == 0)
|
if (state->M == 0)
|
||||||
{
|
{
|
||||||
//see if we need to hash a value larger than 16-bits
|
//see if we need to hash a value larger than 16-bits
|
||||||
hash = state->lasttg & 0xFFFFFF;
|
hash = state->lasttg & 0xFFFFFF;
|
||||||
@@ -523,155 +397,6 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
|||||||
state->DMRvcL++;
|
state->DMRvcL++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//DMR RC4, Slot 1
|
|
||||||
if (state->currentslot == 0 && state->payload_algid == 0x21 && state->R != 0)
|
|
||||||
{
|
|
||||||
uint8_t cipher[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
uint8_t plain[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
uint8_t rckey[9] = {0x00, 0x00, 0x00, 0x00, 0x00, // <- RC4 Key
|
|
||||||
0x00, 0x00, 0x00, 0x00}; // <- MI
|
|
||||||
|
|
||||||
//easier to manually load up rather than make a loop
|
|
||||||
rckey[0] = ((state->R & 0xFF00000000) >> 32);
|
|
||||||
rckey[1] = ((state->R & 0xFF000000) >> 24);
|
|
||||||
rckey[2] = ((state->R & 0xFF0000) >> 16);
|
|
||||||
rckey[3] = ((state->R & 0xFF00) >> 8);
|
|
||||||
rckey[4] = ((state->R & 0xFF) >> 0);
|
|
||||||
rckey[5] = ((state->payload_mi & 0xFF000000) >> 24);
|
|
||||||
rckey[6] = ((state->payload_mi & 0xFF0000) >> 16);
|
|
||||||
rckey[7] = ((state->payload_mi & 0xFF00) >> 8);
|
|
||||||
rckey[8] = ((state->payload_mi & 0xFF) >> 0);
|
|
||||||
|
|
||||||
// if (opts->payload == 1)
|
|
||||||
// {
|
|
||||||
// fprintf (stderr, "%s", KYEL);
|
|
||||||
// fprintf (stderr, " RC4K ");
|
|
||||||
// for (short o = 0; o < 9; o++)
|
|
||||||
// {
|
|
||||||
// fprintf (stderr, "%02X", rckey[o]);
|
|
||||||
// }
|
|
||||||
// fprintf (stderr, "%s", KNRM);
|
|
||||||
// fprintf (stderr, "\n");
|
|
||||||
// }
|
|
||||||
|
|
||||||
short k = 0;
|
|
||||||
for (short o = 0; o < 7; o++)
|
|
||||||
{
|
|
||||||
short b = 0;
|
|
||||||
for (short p = 0; p < 8; p++)
|
|
||||||
{
|
|
||||||
b = b << 1;
|
|
||||||
b = b + ambe_d[k];
|
|
||||||
k++;
|
|
||||||
if (k == 49)
|
|
||||||
{
|
|
||||||
cipher[6] = ((b << 3) & 0x80); //set 7th octet/bit 49 accordingly
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cipher[o] = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
RC4(state->dropL, 9, 7, rckey, cipher, plain);
|
|
||||||
state->dropL += 7;
|
|
||||||
|
|
||||||
short z = 0;
|
|
||||||
for (short p = 0; p < 6; p++)
|
|
||||||
{
|
|
||||||
//convert bytes back to bits and load into ambe_d array.
|
|
||||||
short b = 0; //reset b to use again
|
|
||||||
for (short o = 0; o < 8; o++)
|
|
||||||
{
|
|
||||||
b = (( (plain[p] << o) & 0x80) >> 7);
|
|
||||||
ambe_d[z] = b;
|
|
||||||
z++;
|
|
||||||
if (z == 49)
|
|
||||||
{
|
|
||||||
ambe_d[48] = ( (plain[p] << o) & 0x80);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//P25p2 RC4 Handling, VCH 0
|
|
||||||
if (state->currentslot == 0 && state->payload_algid == 0xAA && state->R != 0 && ((state->synctype == 35) || (state->synctype == 36)))
|
|
||||||
{
|
|
||||||
uint8_t cipher[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
uint8_t plain[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
uint8_t rckey[13] = {0x00, 0x00, 0x00, 0x00, 0x00, // <- RC4 Key
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, // <- MI
|
|
||||||
0x00, 0x00, 0x00}; // <- MI cont.
|
|
||||||
|
|
||||||
//easier to manually load up rather than make a loop
|
|
||||||
rckey[0] = ((state->R & 0xFF00000000) >> 32);
|
|
||||||
rckey[1] = ((state->R & 0xFF000000) >> 24);
|
|
||||||
rckey[2] = ((state->R & 0xFF0000) >> 16);
|
|
||||||
rckey[3] = ((state->R & 0xFF00) >> 8);
|
|
||||||
rckey[4] = ((state->R & 0xFF) >> 0);
|
|
||||||
|
|
||||||
// load valid MI from state->payload_miP
|
|
||||||
rckey[5] = ((state->payload_miP & 0xFF00000000000000) >> 56);
|
|
||||||
rckey[6] = ((state->payload_miP & 0xFF000000000000) >> 48);
|
|
||||||
rckey[7] = ((state->payload_miP & 0xFF0000000000) >> 40);
|
|
||||||
rckey[8] = ((state->payload_miP & 0xFF00000000) >> 32);
|
|
||||||
rckey[9] = ((state->payload_miP & 0xFF000000) >> 24);
|
|
||||||
rckey[10] = ((state->payload_miP & 0xFF0000) >> 16);
|
|
||||||
rckey[11] = ((state->payload_miP & 0xFF00) >> 8);
|
|
||||||
rckey[12] = ((state->payload_miP & 0xFF) >> 0);
|
|
||||||
|
|
||||||
// if (opts->payload == 1)
|
|
||||||
// {
|
|
||||||
// fprintf (stderr, "%s", KYEL);
|
|
||||||
// fprintf (stderr, " RC4K ");
|
|
||||||
// for (short o = 0; o < 13; o++)
|
|
||||||
// {
|
|
||||||
// fprintf (stderr, "%02X", rckey[o]);
|
|
||||||
// }
|
|
||||||
// fprintf (stderr, "%s", KNRM);
|
|
||||||
// fprintf (stderr, "\n");
|
|
||||||
// }
|
|
||||||
|
|
||||||
short k = 0;
|
|
||||||
for (short o = 0; o < 7; o++)
|
|
||||||
{
|
|
||||||
short b = 0;
|
|
||||||
for (short p = 0; p < 8; p++)
|
|
||||||
{
|
|
||||||
b = b << 1;
|
|
||||||
b = b + ambe_d[k];
|
|
||||||
k++;
|
|
||||||
if (k == 49)
|
|
||||||
{
|
|
||||||
cipher[6] = ((b << 3) & 0x80); //set 7th octet/bit 49 accordingly
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cipher[o] = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
RC4(state->dropL, 13, 7, rckey, cipher, plain);
|
|
||||||
state->dropL += 7;
|
|
||||||
|
|
||||||
short z = 0;
|
|
||||||
for (short p = 0; p < 6; p++)
|
|
||||||
{
|
|
||||||
//convert bytes back to bits and load into ambe_d array.
|
|
||||||
short b = 0; //reset b to use again
|
|
||||||
for (short o = 0; o < 8; o++)
|
|
||||||
{
|
|
||||||
b = (( (plain[p] << o) & 0x80) >> 7);
|
|
||||||
ambe_d[z] = b;
|
|
||||||
z++;
|
|
||||||
if (z == 49)
|
|
||||||
{
|
|
||||||
ambe_d[48] = ( (plain[p] << o) & 0x80);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mbe_processAmbe2450Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str,
|
mbe_processAmbe2450Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str,
|
||||||
ambe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
ambe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||||
|
|
||||||
@@ -701,8 +426,8 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
|||||||
|
|
||||||
//EXPERIMENTAL!!
|
//EXPERIMENTAL!!
|
||||||
//load basic privacy key number from array by the tg value (if not forced)
|
//load basic privacy key number from array by the tg value (if not forced)
|
||||||
//currently only Moto BP and Hytera 10 Char BP
|
//currently only Moto BP and Hytera 10 Char BP (converted to decimal)
|
||||||
if (state->M == 0 && state->payload_algidR == 0)
|
if (state->M == 0)
|
||||||
{
|
{
|
||||||
//see if we need to hash a value larger than 16-bits
|
//see if we need to hash a value larger than 16-bits
|
||||||
hash = state->lasttgR & 0xFFFFFF;
|
hash = state->lasttgR & 0xFFFFFF;
|
||||||
@@ -802,155 +527,6 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
|||||||
state->DMRvcR++;
|
state->DMRvcR++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//DMR RC4, Slot 2
|
|
||||||
if (state->currentslot == 1 && state->payload_algidR == 0x21 && state->RR != 0)
|
|
||||||
{
|
|
||||||
uint8_t cipher[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
uint8_t plain[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
uint8_t rckey[9] = {0x00, 0x00, 0x00, 0x00, 0x00, // <- RC4 Key
|
|
||||||
0x00, 0x00, 0x00, 0x00}; // <- MI
|
|
||||||
|
|
||||||
//easier to manually load up rather than make a loop
|
|
||||||
rckey[0] = ((state->RR & 0xFF00000000) >> 32);
|
|
||||||
rckey[1] = ((state->RR & 0xFF000000) >> 24);
|
|
||||||
rckey[2] = ((state->RR & 0xFF0000) >> 16);
|
|
||||||
rckey[3] = ((state->RR & 0xFF00) >> 8);
|
|
||||||
rckey[4] = ((state->RR & 0xFF) >> 0);
|
|
||||||
rckey[5] = ((state->payload_miR & 0xFF000000) >> 24);
|
|
||||||
rckey[6] = ((state->payload_miR & 0xFF0000) >> 16);
|
|
||||||
rckey[7] = ((state->payload_miR & 0xFF00) >> 8);
|
|
||||||
rckey[8] = ((state->payload_miR & 0xFF) >> 0);
|
|
||||||
|
|
||||||
// if (opts->payload == 1)
|
|
||||||
// {
|
|
||||||
// fprintf (stderr, "%s", KYEL);
|
|
||||||
// fprintf (stderr, " RC4K ");
|
|
||||||
// for (short o = 0; o < 9; o++)
|
|
||||||
// {
|
|
||||||
// fprintf (stderr, "%02X", rckey[o]);
|
|
||||||
// }
|
|
||||||
// fprintf (stderr, "%s", KNRM);
|
|
||||||
// fprintf (stderr, "\n");
|
|
||||||
// }
|
|
||||||
|
|
||||||
short k = 0;
|
|
||||||
for (short o = 0; o < 7; o++)
|
|
||||||
{
|
|
||||||
short b = 0;
|
|
||||||
for (short p = 0; p < 8; p++)
|
|
||||||
{
|
|
||||||
b = b << 1;
|
|
||||||
b = b + ambe_d[k];
|
|
||||||
k++;
|
|
||||||
if (k == 49)
|
|
||||||
{
|
|
||||||
cipher[6] = ((b << 3) & 0x80); //set 7th octet/bit 49 accordingly
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cipher[o] = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
RC4(state->dropR, 9, 7, rckey, cipher, plain);
|
|
||||||
state->dropR += 7;
|
|
||||||
|
|
||||||
short z = 0;
|
|
||||||
for (short p = 0; p < 6; p++)
|
|
||||||
{
|
|
||||||
//convert bytes back to bits and load into ambe_d array.
|
|
||||||
short b = 0; //reset b to use again
|
|
||||||
for (short o = 0; o < 8; o++)
|
|
||||||
{
|
|
||||||
b = (( (plain[p] << o) & 0x80) >> 7);
|
|
||||||
ambe_d[z] = b;
|
|
||||||
z++;
|
|
||||||
if (z == 49)
|
|
||||||
{
|
|
||||||
ambe_d[48] = ( (plain[p] << o) & 0x80);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//P25p2 RC4 Handling, VCH 1
|
|
||||||
if (state->currentslot == 1 && state->payload_algidR == 0xAA && state->RR != 0 && ((state->synctype == 35) || (state->synctype == 36)))
|
|
||||||
{
|
|
||||||
uint8_t cipher[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
uint8_t plain[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
uint8_t rckey[13] = {0x00, 0x00, 0x00, 0x00, 0x00, // <- RC4 Key
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, // <- MI
|
|
||||||
0x00, 0x00, 0x00}; // <- MI cont.
|
|
||||||
|
|
||||||
//easier to manually load up rather than make a loop
|
|
||||||
rckey[0] = ((state->RR & 0xFF00000000) >> 32);
|
|
||||||
rckey[1] = ((state->RR & 0xFF000000) >> 24);
|
|
||||||
rckey[2] = ((state->RR & 0xFF0000) >> 16);
|
|
||||||
rckey[3] = ((state->RR & 0xFF00) >> 8);
|
|
||||||
rckey[4] = ((state->RR & 0xFF) >> 0);
|
|
||||||
|
|
||||||
//state->payload_miN for VCH1/slot 2
|
|
||||||
rckey[5] = ((state->payload_miN & 0xFF00000000000000) >> 56);
|
|
||||||
rckey[6] = ((state->payload_miN & 0xFF000000000000) >> 48);
|
|
||||||
rckey[7] = ((state->payload_miN & 0xFF0000000000) >> 40);
|
|
||||||
rckey[8] = ((state->payload_miN & 0xFF00000000) >> 32);
|
|
||||||
rckey[9] = ((state->payload_miN & 0xFF000000) >> 24);
|
|
||||||
rckey[10] = ((state->payload_miN & 0xFF0000) >> 16);
|
|
||||||
rckey[11] = ((state->payload_miN & 0xFF00) >> 8);
|
|
||||||
rckey[12] = ((state->payload_miN & 0xFF) >> 0);
|
|
||||||
|
|
||||||
// if (opts->payload == 1)
|
|
||||||
// {
|
|
||||||
// fprintf (stderr, "%s", KYEL);
|
|
||||||
// fprintf (stderr, " RC4K ");
|
|
||||||
// for (short o = 0; o < 13; o++)
|
|
||||||
// {
|
|
||||||
// fprintf (stderr, "%02X", rckey[o]);
|
|
||||||
// }
|
|
||||||
// fprintf (stderr, "%s", KNRM);
|
|
||||||
// fprintf (stderr, "\n");
|
|
||||||
// }
|
|
||||||
|
|
||||||
short k = 0;
|
|
||||||
for (short o = 0; o < 7; o++)
|
|
||||||
{
|
|
||||||
short b = 0;
|
|
||||||
for (short p = 0; p < 8; p++)
|
|
||||||
{
|
|
||||||
b = b << 1;
|
|
||||||
b = b + ambe_d[k];
|
|
||||||
k++;
|
|
||||||
if (k == 49)
|
|
||||||
{
|
|
||||||
cipher[6] = ((b << 3) & 0x80); //set 7th octet/bit 49 accordingly
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cipher[o] = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
RC4(state->dropR, 13, 7, rckey, cipher, plain);
|
|
||||||
state->dropR += 7;
|
|
||||||
|
|
||||||
short z = 0;
|
|
||||||
for (short p = 0; p < 6; p++)
|
|
||||||
{
|
|
||||||
//convert bytes back to bits and load into ambe_d array.
|
|
||||||
short b = 0; //reset b to use again
|
|
||||||
for (short o = 0; o < 8; o++)
|
|
||||||
{
|
|
||||||
b = (( (plain[p] << o) & 0x80) >> 7);
|
|
||||||
ambe_d[z] = b;
|
|
||||||
z++;
|
|
||||||
if (z == 49)
|
|
||||||
{
|
|
||||||
ambe_d[48] = ( (plain[p] << o) & 0x80);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mbe_processAmbe2450Dataf (state->audio_out_temp_bufR, &state->errsR, &state->errs2R, state->err_strR,
|
mbe_processAmbe2450Dataf (state->audio_out_temp_bufR, &state->errsR, &state->errs2R, state->err_strR,
|
||||||
ambe_d, state->cur_mp2, state->prev_mp2, state->prev_mp_enhanced2, opts->uvquality);
|
ambe_d, state->cur_mp2, state->prev_mp2, state->prev_mp_enhanced2, opts->uvquality);
|
||||||
|
|
||||||
@@ -1005,10 +581,7 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
|||||||
}
|
}
|
||||||
else state->dmr_encL = 0;
|
else state->dmr_encL = 0;
|
||||||
|
|
||||||
//check for available R key
|
//second checkdown for P25-2 WACN, SYSID, and CC set
|
||||||
if (state->R != 0) state->dmr_encL = 0;
|
|
||||||
|
|
||||||
//second checkdown for P25p2 WACN, SYSID, and CC set
|
|
||||||
if (state->synctype == 35 || state->synctype == 36)
|
if (state->synctype == 35 || state->synctype == 36)
|
||||||
{
|
{
|
||||||
if (state->p2_wacn == 0 || state->p2_sysid == 0 || state->p2_cc == 0)
|
if (state->p2_wacn == 0 || state->p2_sysid == 0 || state->p2_cc == 0)
|
||||||
@@ -1035,17 +608,6 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
|||||||
}
|
}
|
||||||
//end reverse mute test
|
//end reverse mute test
|
||||||
|
|
||||||
#ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
|
|
||||||
//OSS Specific Voice Preemption if dual voices on TDMA and one slot has preference over the other
|
|
||||||
if (opts->slot_preference == 1 && opts->audio_out_type == 5 && opts->audio_out == 1 && (state->dmrburstR == 16 || state->dmrburstR == 21) )
|
|
||||||
{
|
|
||||||
opts->audio_out = 0;
|
|
||||||
preempt = 1;
|
|
||||||
if (opts->payload == 0)
|
|
||||||
fprintf (stderr, " *MUTED*");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (state->dmr_encL == 0 || opts->dmr_mute_encL == 0)
|
if (state->dmr_encL == 0 || opts->dmr_mute_encL == 0)
|
||||||
{
|
{
|
||||||
state->debug_audio_errors += state->errs2;
|
state->debug_audio_errors += state->errs2;
|
||||||
@@ -1075,10 +637,7 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
|||||||
}
|
}
|
||||||
else state->dmr_encR = 0;
|
else state->dmr_encR = 0;
|
||||||
|
|
||||||
//check for available RR key
|
//second checkdown for P25-2 WACN, SYSID, and CC set
|
||||||
if (state->RR != 0) state->dmr_encR = 0;
|
|
||||||
|
|
||||||
//second checkdown for P25p2 WACN, SYSID, and CC set
|
|
||||||
if (state->synctype == 35 || state->synctype == 36)
|
if (state->synctype == 35 || state->synctype == 36)
|
||||||
{
|
{
|
||||||
if (state->p2_wacn == 0 || state->p2_sysid == 0 || state->p2_cc == 0)
|
if (state->p2_wacn == 0 || state->p2_sysid == 0 || state->p2_cc == 0)
|
||||||
@@ -1105,17 +664,6 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
|||||||
}
|
}
|
||||||
//end reverse mute test
|
//end reverse mute test
|
||||||
|
|
||||||
#ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
|
|
||||||
//OSS Specific Voice Preemption if dual voices on TDMA and one slot has preference over the other
|
|
||||||
if (opts->slot_preference == 0 && opts->audio_out_type == 5 && opts->audio_out == 1 && (state->dmrburstL == 16 || state->dmrburstL == 21) )
|
|
||||||
{
|
|
||||||
opts->audio_out = 0;
|
|
||||||
preempt = 1;
|
|
||||||
if (opts->payload == 0)
|
|
||||||
fprintf (stderr, " *MUTED*");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (state->dmr_encR == 0 || opts->dmr_mute_encR == 0)
|
if (state->dmr_encR == 0 || opts->dmr_mute_encR == 0)
|
||||||
{
|
{
|
||||||
state->debug_audio_errorsR += state->errs2R;
|
state->debug_audio_errorsR += state->errs2R;
|
||||||
@@ -1170,12 +718,6 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preempt == 1)
|
|
||||||
{
|
|
||||||
opts->audio_out = 1;
|
|
||||||
preempt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//reset audio out flag for next repitition
|
//reset audio out flag for next repitition
|
||||||
if (strcmp(mode, "B") == 0) opts->audio_out = 1;
|
if (strcmp(mode, "B") == 0) opts->audio_out = 1;
|
||||||
//restore flag for null output type
|
//restore flag for null output type
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
146
src/dsd_reset.c
146
src/dsd_reset.c
@@ -2,59 +2,26 @@
|
|||||||
#include "dsd.h"
|
#include "dsd.h"
|
||||||
#include "p25p1_heuristics.h"
|
#include "p25p1_heuristics.h"
|
||||||
|
|
||||||
//fixed the memory leak, but now random segfaults occur -- double free or corruption (out) or (!prev)
|
void
|
||||||
void resetState (dsd_state * state)
|
resetState (dsd_state * state)
|
||||||
{
|
{
|
||||||
|
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
//Dibit Buffer -- Free Allocated Memory
|
|
||||||
// free (state->dibit_buf);
|
|
||||||
|
|
||||||
//Dibit Buffer -- Memset/Init/Allocate Memory
|
|
||||||
// state->dibit_buf = malloc (sizeof (int) * 1000000);
|
// state->dibit_buf = malloc (sizeof (int) * 1000000);
|
||||||
|
// state->dibit_buf_p = state->dibit_buf + 200;
|
||||||
state->dibit_buf_p = state->dibit_buf + 200;
|
// memset (state->dibit_buf, 0, sizeof (int) * 200);
|
||||||
memset (state->dibit_buf, 0, sizeof (int) * 200);
|
state->repeat = 0; //not sure yet
|
||||||
state->repeat = 0; //repeat frame?
|
//state->audio_out_buf = malloc (sizeof (short) * 1000000);
|
||||||
|
//memset (state->audio_out_buf, 0, 100 * sizeof (short));
|
||||||
//Audio Buffer -- Free Allocated Memory
|
//state->audio_out_buf_p = state->audio_out_buf + 100;
|
||||||
free (state->audio_out_buf);
|
//state->audio_out_float_buf = malloc (sizeof (float) * 1000000);
|
||||||
free (state->audio_out_float_buf);
|
//memset (state->audio_out_float_buf, 0, 100 * sizeof (float));
|
||||||
free (state->audio_out_bufR);
|
//state->audio_out_float_buf_p = state->audio_out_float_buf + 100;
|
||||||
free (state->audio_out_float_bufR);
|
//state->audio_out_idx = 0;
|
||||||
|
//state->audio_out_idx2 = 0;
|
||||||
//Audio Buffer -- Memset/Init/Allocate Memory per slot
|
//state->audio_out_temp_buf_p = state->audio_out_temp_buf;
|
||||||
|
//state->wav_out_bytes = 0;
|
||||||
//slot 1
|
|
||||||
state->audio_out_float_buf = malloc (sizeof (float) * 1000000);
|
|
||||||
state->audio_out_buf = malloc (sizeof (short) * 1000000);
|
|
||||||
|
|
||||||
memset (state->audio_out_buf, 0, 100 * sizeof (short));
|
|
||||||
state->audio_out_buf_p = state->audio_out_buf + 100;
|
|
||||||
|
|
||||||
memset (state->audio_out_float_buf, 0, 100 * sizeof (float));
|
|
||||||
state->audio_out_float_buf_p = state->audio_out_float_buf + 100;
|
|
||||||
|
|
||||||
state->audio_out_idx = 0;
|
|
||||||
state->audio_out_idx2 = 0;
|
|
||||||
state->audio_out_temp_buf_p = state->audio_out_temp_buf;
|
|
||||||
|
|
||||||
//slot 2
|
|
||||||
state->audio_out_bufR = malloc (sizeof (short) * 1000000);
|
|
||||||
state->audio_out_float_bufR = malloc (sizeof (float) * 1000000);
|
|
||||||
|
|
||||||
memset (state->audio_out_bufR, 0, 100 * sizeof (short));
|
|
||||||
state->audio_out_buf_pR = state->audio_out_bufR + 100;
|
|
||||||
|
|
||||||
memset (state->audio_out_float_bufR, 0, 100 * sizeof (float));
|
|
||||||
state->audio_out_float_buf_pR = state->audio_out_float_bufR + 100;
|
|
||||||
|
|
||||||
state->audio_out_idxR = 0;
|
|
||||||
state->audio_out_idx2R = 0;
|
|
||||||
state->audio_out_temp_buf_pR = state->audio_out_temp_bufR;
|
|
||||||
|
|
||||||
//Sync
|
|
||||||
state->center = 0;
|
state->center = 0;
|
||||||
state->jitter = -1;
|
state->jitter = -1;
|
||||||
state->synctype = -1;
|
state->synctype = -1;
|
||||||
@@ -64,7 +31,6 @@ void resetState (dsd_state * state)
|
|||||||
state->umid = 0;
|
state->umid = 0;
|
||||||
state->minref = -12000;
|
state->minref = -12000;
|
||||||
state->maxref = 12000;
|
state->maxref = 12000;
|
||||||
|
|
||||||
state->lastsample = 0;
|
state->lastsample = 0;
|
||||||
for (i = 0; i < 128; i++)
|
for (i = 0; i < 128; i++)
|
||||||
{
|
{
|
||||||
@@ -79,58 +45,62 @@ void resetState (dsd_state * state)
|
|||||||
{
|
{
|
||||||
state->minbuf[i] = -15000;
|
state->minbuf[i] = -15000;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->midx = 0;
|
state->midx = 0;
|
||||||
|
state->err_str[0] = 0;
|
||||||
|
sprintf (state->fsubtype, " ");
|
||||||
|
sprintf (state->ftype, " ");
|
||||||
state->symbolcnt = 0;
|
state->symbolcnt = 0;
|
||||||
|
state->rf_mod = 0;
|
||||||
state->numflips = 0;
|
state->numflips = 0;
|
||||||
state->lastsynctype = -1;
|
state->lastsynctype = -1;
|
||||||
state->lastp25type = 0;
|
state->lastp25type = 0;
|
||||||
state->offset = 0;
|
state->offset = 0;
|
||||||
state->carrier = 0;
|
state->carrier = 0;
|
||||||
|
for (i = 0; i < 25; i++)
|
||||||
//Reset Voice Errors in C0 and C1 (or remaining Codewords in IMBE)
|
{
|
||||||
|
for (j = 0; j < 16; j++)
|
||||||
|
{
|
||||||
|
state->tg[i][j] = 48;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state->tgcount = 0;
|
||||||
|
state->lasttg = 0;
|
||||||
|
state->lastsrc = 0;
|
||||||
|
state->nac = 0;
|
||||||
state->errs = 0;
|
state->errs = 0;
|
||||||
state->errs2 = 0;
|
state->errs2 = 0;
|
||||||
state->errsR = 0;
|
state->mbe_file_type = -1;
|
||||||
state->errs2R = 0;
|
|
||||||
|
|
||||||
//Misc -- may not be needed
|
|
||||||
state->optind = 0;
|
state->optind = 0;
|
||||||
state->numtdulc = 0;
|
state->numtdulc = 0;
|
||||||
state->firstframe = 0;
|
state->firstframe = 0;
|
||||||
|
sprintf (state->slot0light, " slot0 ");
|
||||||
|
sprintf (state->slot1light, " slot1 ");
|
||||||
|
state->aout_gain = 25;
|
||||||
|
memset (state->aout_max_buf, 0, sizeof (float) * 200);
|
||||||
|
state->aout_max_buf_p = state->aout_max_buf;
|
||||||
|
state->aout_max_buf_idx = 0;
|
||||||
|
state->samplesPerSymbol = 10;
|
||||||
|
state->symbolCenter = 4;
|
||||||
|
sprintf (state->algid, "________");
|
||||||
|
sprintf (state->keyid, "________________");
|
||||||
|
state->currentslot = 0;
|
||||||
|
state->cur_mp = malloc (sizeof (mbe_parms));
|
||||||
|
state->prev_mp = malloc (sizeof (mbe_parms));
|
||||||
|
state->prev_mp_enhanced = malloc (sizeof (mbe_parms));
|
||||||
|
mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced);
|
||||||
|
state->p25kid = 0;
|
||||||
|
|
||||||
//unsure if these are still used or ever were used,
|
state->debug_audio_errors = 0;
|
||||||
// memset (state->aout_max_buf, 0, sizeof (float) * 200);
|
state->debug_header_errors = 0;
|
||||||
// state->aout_max_buf_p = state->aout_max_buf;
|
state->debug_header_critical_errors = 0;
|
||||||
// state->aout_max_buf_idx = 0;
|
|
||||||
|
|
||||||
// //MBE Specific
|
state->nxdn_last_ran = 0;
|
||||||
// //free the memory before allocating it again -- may not use this
|
// state->payload_algid = 0;
|
||||||
// free (state->cur_mp);
|
// state->payload_algidR = 0;
|
||||||
// free (state->prev_mp);
|
state->dmr_encL = 0;
|
||||||
// free (state->prev_mp_enhanced);
|
state->dmr_encR = 0;
|
||||||
|
|
||||||
// //memory allocation and init on mbe -- may not use this
|
//each time you run this, it increses memory use by 4MB, massive memory leak
|
||||||
// state->cur_mp = malloc (sizeof (mbe_parms));
|
//need to revisit this sometime and look into only resetting only the necesary items to let P25 switch between signals (C4FM or Wide) without needing a restart
|
||||||
// state->prev_mp = malloc (sizeof (mbe_parms));
|
initialize_p25_heuristics(&state->p25_heuristics); //see if we want to re-init this or not, currently seems to cause memory leak when running over and over, mitigated with a reset flag
|
||||||
// state->prev_mp_enhanced = malloc (sizeof (mbe_parms));
|
|
||||||
// mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced);
|
|
||||||
|
|
||||||
//rest the heurestics, we want to do this on each tune, each RF frequency can deviate quite a bit in strength
|
|
||||||
initialize_p25_heuristics(&state->p25_heuristics);
|
|
||||||
initialize_p25_heuristics(&state->inv_p25_heuristics);
|
|
||||||
}
|
|
||||||
|
|
||||||
//simple function to reset the dibit buffer
|
|
||||||
void reset_dibit_buffer(dsd_state * state)
|
|
||||||
{
|
|
||||||
//Dibit Buffer -- Free Allocated Memory
|
|
||||||
// free (state->dibit_buf);
|
|
||||||
|
|
||||||
//Dibit Buffer -- Memset/Init/Allocate Memory
|
|
||||||
// state->dibit_buf = malloc (sizeof (int) * 1000000);
|
|
||||||
|
|
||||||
state->dibit_buf_p = state->dibit_buf + 200;
|
|
||||||
memset (state->dibit_buf, 0, sizeof (int) * 200);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -250,7 +250,6 @@ int UDPBind (char *hostname, int portno)
|
|||||||
return sockfd;
|
return sockfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
//going to leave this function available, even if completely switched over to rtl_dev_tune now, may be useful in the future
|
|
||||||
void rtl_udp_tune(dsd_opts * opts, dsd_state * state, long int frequency)
|
void rtl_udp_tune(dsd_opts * opts, dsd_state * state, long int frequency)
|
||||||
{
|
{
|
||||||
int handle;
|
int handle;
|
||||||
@@ -275,5 +274,8 @@ void rtl_udp_tune(dsd_opts * opts, dsd_state * state, long int frequency)
|
|||||||
address.sin_port = htons(udp_port);
|
address.sin_port = htons(udp_port);
|
||||||
sendto(handle, data, 5, 0, (const struct sockaddr * ) & address, sizeof(struct sockaddr_in));
|
sendto(handle, data, 5, 0, (const struct sockaddr * ) & address, sizeof(struct sockaddr_in));
|
||||||
|
|
||||||
|
//BUGFIX: This was causing an indefinite number of UDP sockets to stay open on each tune request
|
||||||
|
//we open a new socket with each request, so we need to close the socket after writing to it
|
||||||
|
//this would cause the tuning to stop after x number of tune attempts (few hours? on a busy system)
|
||||||
close (handle); //close socket after sending.
|
close (handle); //close socket after sending.
|
||||||
}
|
}
|
||||||
159
src/dsd_symbol.c
159
src/dsd_symbol.c
@@ -82,24 +82,35 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read the new sample from the input
|
// Read the new sample from the input
|
||||||
if(opts->audio_in_type == 0) //pulse audio
|
if(opts->audio_in_type == 0) // && state->menuopen == 0 still not quite working
|
||||||
{
|
{
|
||||||
pa_simple_read(opts->pulse_digi_dev_in, &sample, 2, NULL );
|
pa_simple_read(opts->pulse_digi_dev_in, &sample, 2, NULL );
|
||||||
}
|
//look into how processAudio handles playback, not sure if latency issues, or garbage sample values crash pulse when written
|
||||||
|
// if (opts->monitor_input_audio == 1 && state->lastsynctype == -1 && sample < 32767 && sample > -32767)
|
||||||
else if (opts->audio_in_type == 5) //OSS
|
if (opts->monitor_input_audio == 1 && state->lastsynctype == -1 && sample != 0)
|
||||||
{
|
{
|
||||||
read (opts->audio_in_fd, &sample, 2);
|
state->pulse_raw_out_buffer = sample; //steal raw out buffer sample here?
|
||||||
|
pa_simple_write(opts->pulse_raw_dev_out, (void*)&state->pulse_raw_out_buffer, 2, NULL);
|
||||||
|
}
|
||||||
|
//playback is wrong, depends on samples_per_symbol, maybe make a buffer and store first?
|
||||||
|
//making buffer might also fix raw audio monitoring as well
|
||||||
|
if (opts->wav_out_file_raw[0] != 0) //if set for recording sample raw files
|
||||||
|
{
|
||||||
|
//writeRawSample (opts, state, sample);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
//stdin only, wav files moving to new number
|
//stdin only, wav files moving to new number
|
||||||
else if (opts->audio_in_type == 1) //won't work in windows, needs posix pipe (mintty)
|
else if (opts->audio_in_type == 1)
|
||||||
{
|
{
|
||||||
result = sf_read_short(opts->audio_in_file, &sample, 1);
|
result = sf_read_short(opts->audio_in_file, &sample, 1);
|
||||||
if(result == 0)
|
if(result == 0)
|
||||||
{
|
{
|
||||||
|
//cleanupAndExit (opts, state);
|
||||||
sf_close(opts->audio_in_file);
|
sf_close(opts->audio_in_file);
|
||||||
cleanupAndExit (opts, state);
|
opts->audio_in_type = 0; //set input type
|
||||||
|
openPulseInput(opts); //open pulse inpput
|
||||||
|
sample = 0; //send zero sample
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//wav files, same but using seperate value so we can still manipulate ncurses menu
|
//wav files, same but using seperate value so we can still manipulate ncurses menu
|
||||||
@@ -111,19 +122,10 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
|
|||||||
{
|
{
|
||||||
|
|
||||||
sf_close(opts->audio_in_file);
|
sf_close(opts->audio_in_file);
|
||||||
fprintf (stderr, "\n\nEnd of .wav file.\n");
|
|
||||||
//open pulse input if we are pulse output AND using ncurses terminal
|
|
||||||
if (opts->audio_out_type == 0 && opts->use_ncurses_terminal == 1)
|
|
||||||
{
|
|
||||||
opts->audio_in_type = 0; //set input type
|
opts->audio_in_type = 0; //set input type
|
||||||
openPulseInput(opts); //open pulse input
|
openPulseInput(opts); //open pulse inpput
|
||||||
}
|
sample = 0; //send zero sample
|
||||||
//else cleanup and exit
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (opts->use_ncurses_terminal == 1) ncursesClose(opts);
|
|
||||||
cleanupAndExit(opts, state);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
@@ -137,72 +139,13 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
|
|||||||
state->pulse_raw_out_buffer = sample; //steal raw out buffer sample here?
|
state->pulse_raw_out_buffer = sample; //steal raw out buffer sample here?
|
||||||
pa_simple_write(opts->pulse_raw_dev_out, (void*)&state->pulse_raw_out_buffer, 2, NULL);
|
pa_simple_write(opts->pulse_raw_dev_out, (void*)&state->pulse_raw_out_buffer, 2, NULL);
|
||||||
}
|
}
|
||||||
opts->rtl_rms = rtl_return_rms();
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//tcp socket input from SDR++ -- now with 1 retry if connection is broken
|
//tcp socket input from SDR++
|
||||||
else if (opts->audio_in_type == 8)
|
else if (opts->audio_in_type == 8)
|
||||||
{
|
{
|
||||||
#ifdef AERO_BUILD
|
|
||||||
result = sf_read_short(opts->tcp_file_in, &sample, 1);
|
|
||||||
if(result == 0) {
|
|
||||||
fprintf (stderr, "\nConnection to TCP Server Interrupted. Trying again in 3 seconds.\n");
|
|
||||||
sample = 0;
|
|
||||||
sf_close(opts->tcp_file_in); //close current connection on this end
|
|
||||||
sleep (3); //halt all processing and wait 3 seconds
|
|
||||||
|
|
||||||
//attempt to reconnect to socket
|
|
||||||
opts->tcp_sockfd = 0;
|
|
||||||
opts->tcp_sockfd = Connect(opts->tcp_hostname, opts->tcp_portno);
|
|
||||||
if (opts->tcp_sockfd != 0)
|
|
||||||
{
|
|
||||||
//reset audio input stream
|
|
||||||
opts->audio_in_file_info = calloc(1, sizeof(SF_INFO));
|
|
||||||
opts->audio_in_file_info->samplerate=opts->wav_sample_rate;
|
|
||||||
opts->audio_in_file_info->channels=1;
|
|
||||||
opts->audio_in_file_info->seekable=0;
|
|
||||||
opts->audio_in_file_info->format=SF_FORMAT_RAW|SF_FORMAT_PCM_16|SF_ENDIAN_LITTLE;
|
|
||||||
opts->tcp_file_in = sf_open_fd(opts->tcp_sockfd, SFM_READ, opts->audio_in_file_info, 0);
|
|
||||||
|
|
||||||
if(opts->tcp_file_in == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error, couldn't Reconnect to TCP with libsndfile: %s\n", sf_strerror(NULL));
|
|
||||||
}
|
|
||||||
else fprintf (stderr, "TCP Socket Reconnected Successfully.\n");
|
|
||||||
}
|
|
||||||
else fprintf (stderr, "TCP Socket Connection Error.\n");
|
|
||||||
|
|
||||||
//now retry reading sample
|
|
||||||
result = sf_read_short(opts->tcp_file_in, &sample, 1);
|
|
||||||
if (result == 0) {
|
|
||||||
sf_close(opts->tcp_file_in);
|
|
||||||
opts->audio_in_type = 0; //set input type
|
|
||||||
opts->tcp_sockfd = 0; //added this line so we will know if it connected when using ncurses terminal keyboard shortcut
|
|
||||||
//openPulseInput(opts); //open pulse inpput
|
|
||||||
sample = 0; //zero sample on bad result, keep the ball rolling
|
|
||||||
//open pulse input if we are pulse output AND using ncurses terminal
|
|
||||||
if (opts->audio_out_type == 0 && opts->use_ncurses_terminal == 1)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "Connection to TCP Server Disconnected.\n");
|
|
||||||
fprintf (stderr, "Opening Pulse Audio Input.\n");
|
|
||||||
opts->audio_in_type = 0; //set input type
|
|
||||||
openPulseInput(opts); //open pulse input
|
|
||||||
}
|
|
||||||
//else cleanup and exit
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf (stderr, "Connection to TCP Server Disconnected.\n");
|
|
||||||
fprintf (stderr, "Closing DSD-FME.\n");
|
|
||||||
if (opts->use_ncurses_terminal == 1) ncursesClose(opts);
|
|
||||||
cleanupAndExit(opts, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
result = sf_read_short(opts->tcp_file_in, &sample, 1);
|
result = sf_read_short(opts->tcp_file_in, &sample, 1);
|
||||||
if(result == 0) {
|
if(result == 0) {
|
||||||
fprintf (stderr, "\nConnection to TCP Server Interrupted. Trying again in 3 seconds.\n");
|
fprintf (stderr, "\nConnection to TCP Server Interrupted. Trying again in 3 seconds.\n");
|
||||||
@@ -243,37 +186,18 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//tcp socket input from SDR++ -- old method to open pulse or quit right away
|
|
||||||
// else if (opts->audio_in_type == 8)
|
|
||||||
// {
|
|
||||||
// result = sf_read_short(opts->tcp_file_in, &sample, 1);
|
|
||||||
// if(result == 0) {
|
|
||||||
|
|
||||||
// fprintf (stderr, "Connection to TCP Server Disconnected.\n");
|
|
||||||
// //open pulse input if we are pulse output AND using ncurses terminal
|
|
||||||
// if (opts->audio_out_type == 0 && opts->use_ncurses_terminal == 1)
|
|
||||||
// {
|
|
||||||
// opts->audio_in_type = 0; //set input type
|
|
||||||
// openPulseInput(opts); //open pulse input
|
|
||||||
// }
|
|
||||||
// //else cleanup and exit
|
|
||||||
// else cleanupAndExit(opts, state);
|
|
||||||
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
//UDP Socket input...not working correct. Reads samples, but no sync
|
//UDP Socket input...not working correct. Reads samples, but no sync
|
||||||
// else if (opts->audio_in_type == 6)
|
else if (opts->audio_in_type == 6)
|
||||||
// {
|
{
|
||||||
//I think this doesn't get the entire dgram when we run sf_read_short on the udp dgram
|
//I think this doesn't get the entire dgram when we run sf_read_short on the udp dgram
|
||||||
// result = sf_read_short(opts->udp_file_in, &sample, 1);
|
result = sf_read_short(opts->udp_file_in, &sample, 1);
|
||||||
// if (sample != 0)
|
// if (sample != 0)
|
||||||
// fprintf (stderr, "Result = %d Sample = %d \n", result, sample);
|
// fprintf (stderr, "Result = %d Sample = %d \n", result, sample);
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (opts->use_cosine_filter)
|
if (opts->use_cosine_filter)
|
||||||
{
|
{
|
||||||
@@ -492,12 +416,6 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//test throttle on wav input files
|
|
||||||
if (opts->audio_in_type == 2)
|
|
||||||
{
|
|
||||||
if (state->use_throttle == 1) usleep(.003); //very environment specific, tuning to cygwin
|
|
||||||
}
|
|
||||||
|
|
||||||
//read op25/fme symbol bin files
|
//read op25/fme symbol bin files
|
||||||
if (opts->audio_in_type == 4)
|
if (opts->audio_in_type == 4)
|
||||||
{
|
{
|
||||||
@@ -514,27 +432,14 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
|
|||||||
useconds_t stime = state->symbol_throttle;
|
useconds_t stime = state->symbol_throttle;
|
||||||
if (state->use_throttle == 1)
|
if (state->use_throttle == 1)
|
||||||
{
|
{
|
||||||
// usleep(stime);
|
usleep(stime);
|
||||||
usleep(.003); //very environment specific, tuning to cygwin
|
|
||||||
}
|
}
|
||||||
//fprintf(stderr, "%d", state->symbolc);
|
//fprintf(stderr, "%d", state->symbolc);
|
||||||
if( feof(opts->symbolfile) )
|
if( feof(opts->symbolfile) )
|
||||||
{
|
{
|
||||||
// opts->audio_in_type = 0; //switch to pulse after playback, ncurses terminal can initiate replay if wanted
|
opts->audio_in_type = 0; //switch to pulse after playback, ncurses terminal can initiate replay if wanted
|
||||||
fclose(opts->symbolfile);
|
fclose(opts->symbolfile);
|
||||||
fprintf (stderr, "\n\nEnd of .bin file\n");
|
openPulseInput(opts);
|
||||||
//open pulse input if we are pulse output AND using ncurses terminal
|
|
||||||
if (opts->audio_out_type == 0 && opts->use_ncurses_terminal == 1)
|
|
||||||
{
|
|
||||||
opts->audio_in_type = 0; //set input type
|
|
||||||
openPulseInput(opts); //open pulse input
|
|
||||||
}
|
|
||||||
//else cleanup and exit
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (opts->use_ncurses_terminal == 1) ncursesClose(opts);
|
|
||||||
cleanupAndExit(opts, state);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//assign symbol/dibit values based on modulation type
|
//assign symbol/dibit values based on modulation type
|
||||||
|
|||||||
@@ -298,11 +298,9 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||||||
|
|
||||||
if (opts->audio_in_type == 3) //rtl dongle
|
if (opts->audio_in_type == 3) //rtl dongle
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune(opts, state, state->trunk_lcn_freq[lcn-1]);
|
||||||
rtl_dev_tune (opts, state->trunk_lcn_freq[lcn-1]);
|
|
||||||
state->edacs_tuned_lcn = lcn;
|
state->edacs_tuned_lcn = lcn;
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -430,11 +428,9 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
|||||||
|
|
||||||
if (opts->audio_in_type == 3) //rtl dongle
|
if (opts->audio_in_type == 3) //rtl dongle
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune(opts, state, state->trunk_lcn_freq[lcn-1]);
|
||||||
rtl_dev_tune (opts, state->trunk_lcn_freq[lcn-1]);
|
|
||||||
state->edacs_tuned_lcn = lcn;
|
state->edacs_tuned_lcn = lcn;
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,23 +121,26 @@ void nxdn_deperm_facch(dsd_opts * opts, dsd_state * state, uint8_t bits[144])
|
|||||||
check = check | trellis_buf[84+i]; //80
|
check = check | trellis_buf[84+i]; //80
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (crc != check)
|
||||||
|
{
|
||||||
|
fprintf (stderr, " FACCH");
|
||||||
|
fprintf (stderr, "%s", KRED);
|
||||||
|
fprintf (stderr, " (CRC ERR)");
|
||||||
|
fprintf (stderr, "%s", KNRM);
|
||||||
|
}
|
||||||
|
|
||||||
if (crc == check) NXDN_Elements_Content_decode(opts, state, 1, trellis_buf);
|
if (crc == check) NXDN_Elements_Content_decode(opts, state, 1, trellis_buf);
|
||||||
else if (opts->aggressive_framesync == 0) NXDN_Elements_Content_decode(opts, state, 0, trellis_buf);
|
else if (opts->aggressive_framesync == 0) NXDN_Elements_Content_decode(opts, state, 0, trellis_buf);
|
||||||
|
|
||||||
if (opts->payload == 1)
|
if (opts->payload == 1)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
fprintf (stderr, " FACCH1 Payload ");
|
fprintf (stderr, " FACCH Payload ");
|
||||||
for (int i = 0; i < 12; i++)
|
for (int i = 0; i < 12; i++)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "[%02X]", m_data[i]);
|
fprintf (stderr, "[%02X]", m_data[i]);
|
||||||
}
|
}
|
||||||
if (crc != check && opts->payload == 1)
|
// fprintf (stderr, " - %03X %03X", check, crc);
|
||||||
{
|
|
||||||
fprintf (stderr, "%s", KRED);
|
|
||||||
fprintf (stderr, " (CRC ERR)");
|
|
||||||
fprintf (stderr, "%s", KNRM);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -248,14 +251,16 @@ void nxdn_deperm_sacch(dsd_opts * opts, dsd_state * state, uint8_t bits[60])
|
|||||||
state->nxdn_last_ran = ran;
|
state->nxdn_last_ran = ran;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (stderr, "PF 1/1");
|
|
||||||
|
|
||||||
if (crc == check) NXDN_Elements_Content_decode(opts, state, 1, nsf_sacch);
|
if (crc == check) NXDN_Elements_Content_decode(opts, state, 1, nsf_sacch);
|
||||||
// else if (opts->aggressive_framesync == 0) NXDN_Elements_Content_decode(opts, state, 0, nsf_sacch);
|
else if (opts->aggressive_framesync == 0) NXDN_Elements_Content_decode(opts, state, 0, nsf_sacch);
|
||||||
|
|
||||||
//I'm placing this here, my observation is that SACCH NSF
|
if (crc != check)
|
||||||
//is almost always, if not always, just IDLE
|
{
|
||||||
else fprintf (stderr, " IDLE");
|
fprintf (stderr, " SACCH NSF");
|
||||||
|
fprintf (stderr, "%s", KRED);
|
||||||
|
fprintf (stderr, " (CRC ERR)");
|
||||||
|
fprintf (stderr, "%s", KNRM);
|
||||||
|
}
|
||||||
|
|
||||||
if (opts->payload == 1)
|
if (opts->payload == 1)
|
||||||
{
|
{
|
||||||
@@ -264,15 +269,7 @@ void nxdn_deperm_sacch(dsd_opts * opts, dsd_state * state, uint8_t bits[60])
|
|||||||
{
|
{
|
||||||
fprintf (stderr, "[%02X]", m_data[i]);
|
fprintf (stderr, "[%02X]", m_data[i]);
|
||||||
}
|
}
|
||||||
|
// if (crc != check) fprintf (stderr, " CRC ERR - %02X %02X", check, crc);
|
||||||
if (crc != check)
|
|
||||||
{
|
|
||||||
|
|
||||||
fprintf (stderr, "%s", KRED);
|
|
||||||
fprintf (stderr, " (CRC ERR)");
|
|
||||||
fprintf (stderr, "%s", KNRM);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//reset the sacch field -- Github Issue #118
|
//reset the sacch field -- Github Issue #118
|
||||||
@@ -299,10 +296,9 @@ void nxdn_deperm_sacch(dsd_opts * opts, dsd_state * state, uint8_t bits[60])
|
|||||||
else fprintf (stderr, " ");
|
else fprintf (stderr, " ");
|
||||||
fprintf (stderr, "%s", KNRM);
|
fprintf (stderr, "%s", KNRM);
|
||||||
|
|
||||||
fprintf (stderr, "PF %d/4", part_of_frame+1);
|
|
||||||
|
|
||||||
if (crc != check)
|
if (crc != check)
|
||||||
{
|
{
|
||||||
|
fprintf (stderr, " SACCH SF%d", sf);
|
||||||
fprintf (stderr, "%s", KRED);
|
fprintf (stderr, "%s", KRED);
|
||||||
fprintf (stderr, " (CRC ERR)");
|
fprintf (stderr, " (CRC ERR)");
|
||||||
fprintf (stderr, "%s", KNRM);
|
fprintf (stderr, "%s", KNRM);
|
||||||
@@ -336,17 +332,16 @@ void nxdn_deperm_sacch(dsd_opts * opts, dsd_state * state, uint8_t bits[60])
|
|||||||
NXDN_SACCH_Full_decode (opts, state);
|
NXDN_SACCH_Full_decode (opts, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (opts->payload == 1)
|
if (opts->payload == 1)
|
||||||
// {
|
{
|
||||||
// fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
// fprintf (stderr, " SACCH SF Segment #%d ", part_of_frame+1);
|
fprintf (stderr, " SACCH SF Segment #%d ", part_of_frame+1);
|
||||||
// for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
// {
|
{
|
||||||
// fprintf (stderr, "[%02X]", m_data[i]);
|
fprintf (stderr, "[%02X]", m_data[i]);
|
||||||
// }
|
}
|
||||||
// // if (crc != check) fprintf (stderr, " CRC ERR - %02X %02X", crc, check);
|
// if (crc != check) fprintf (stderr, " CRC ERR - %02X %02X", crc, check);
|
||||||
// }
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -433,10 +428,15 @@ void nxdn_deperm_facch2_udch(dsd_opts * opts, dsd_state * state, uint8_t bits[34
|
|||||||
check = check | trellis_buf[i+184];
|
check = check | trellis_buf[i+184];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (crc != check)
|
||||||
|
{
|
||||||
fprintf (stderr, "%s", KYEL);
|
fprintf (stderr, "%s", KYEL);
|
||||||
if (type == 0) fprintf (stderr, " UDCH");
|
if (type == 0) fprintf (stderr, " UDCH");
|
||||||
if (type == 1) fprintf (stderr, " FACCH2");
|
if (type == 1) fprintf (stderr, " FACCH2");
|
||||||
|
fprintf (stderr, "%s", KRED);
|
||||||
|
fprintf (stderr, " (CRC ERR)");
|
||||||
fprintf (stderr, "%s", KNRM);
|
fprintf (stderr, "%s", KNRM);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t f2u_message_buffer[400]; //199
|
uint8_t f2u_message_buffer[400]; //199
|
||||||
memset (f2u_message_buffer, 0, sizeof(f2u_message_buffer));
|
memset (f2u_message_buffer, 0, sizeof(f2u_message_buffer));
|
||||||
@@ -470,14 +470,6 @@ void nxdn_deperm_facch2_udch(dsd_opts * opts, dsd_state * state, uint8_t bits[34
|
|||||||
if (i == 13) fprintf (stderr, "\n ");
|
if (i == 13) fprintf (stderr, "\n ");
|
||||||
fprintf (stderr, "[%02X]", m_data[i]);
|
fprintf (stderr, "[%02X]", m_data[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crc != check)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "%s", KRED);
|
|
||||||
fprintf (stderr, " (CRC ERR)");
|
|
||||||
fprintf (stderr, "%s", KNRM);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (crc != check) fprintf (stderr, " CRC ERR ");
|
// if (crc != check) fprintf (stderr, " CRC ERR ");
|
||||||
|
|
||||||
if (type == 0)
|
if (type == 0)
|
||||||
@@ -732,6 +724,12 @@ void nxdn_deperm_scch(dsd_opts * opts, dsd_state * state, uint8_t bits[60], uint
|
|||||||
|
|
||||||
//NOTE: scch has its own message format, and thus, doesn't go to content element decoding
|
//NOTE: scch has its own message format, and thus, doesn't go to content element decoding
|
||||||
//like everything else does
|
//like everything else does
|
||||||
|
if (crc != check)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s", KRED);
|
||||||
|
fprintf (stderr, " (CRC ERR)");
|
||||||
|
fprintf (stderr, "%s", KNRM);
|
||||||
|
}
|
||||||
|
|
||||||
if (crc == check) NXDN_decode_scch (opts, state, trellis_buf, direction);
|
if (crc == check) NXDN_decode_scch (opts, state, trellis_buf, direction);
|
||||||
else if (opts->aggressive_framesync == 0) NXDN_decode_scch (opts, state, trellis_buf, direction);
|
else if (opts->aggressive_framesync == 0) NXDN_decode_scch (opts, state, trellis_buf, direction);
|
||||||
@@ -745,13 +743,7 @@ void nxdn_deperm_scch(dsd_opts * opts, dsd_state * state, uint8_t bits[60], uint
|
|||||||
{
|
{
|
||||||
fprintf (stderr, "[%02X]", m_data[i]);
|
fprintf (stderr, "[%02X]", m_data[i]);
|
||||||
}
|
}
|
||||||
|
// if (crc != check) fprintf (stderr, " CRC ERR - %02X %02X", check, crc);
|
||||||
if (crc != check)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "%s", KRED);
|
|
||||||
fprintf (stderr, " (CRC ERR)");
|
|
||||||
fprintf (stderr, "%s", KNRM);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (stderr, "%s", KNRM);
|
fprintf (stderr, "%s", KNRM);
|
||||||
@@ -841,11 +833,14 @@ void nxdn_deperm_facch3_udch2(dsd_opts * opts, dsd_state * state, uint8_t bits[2
|
|||||||
for (int i = 0; i < 12; i++) f3_udch2_bytes[i+(j*12)] = m_data[i];
|
for (int i = 0; i < 12; i++) f3_udch2_bytes[i+(j*12)] = m_data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (stderr, "%s", KYEL);
|
if (crc[0] != check[0] || crc[1] != check[1])
|
||||||
|
{
|
||||||
if (type == 0) fprintf (stderr, " UDCH2");
|
if (type == 0) fprintf (stderr, " UDCH2");
|
||||||
if (type == 1) fprintf (stderr, " FACCH3");
|
if (type == 1) fprintf (stderr, " FACCH3");
|
||||||
|
fprintf (stderr, "%s", KRED);
|
||||||
|
fprintf (stderr, " (CRC ERR)");
|
||||||
fprintf (stderr, "%s", KNRM);
|
fprintf (stderr, "%s", KNRM);
|
||||||
|
}
|
||||||
|
|
||||||
if (crc[0] == check[0] && crc[1] == check[1])
|
if (crc[0] == check[0] && crc[1] == check[1])
|
||||||
{
|
{
|
||||||
@@ -869,17 +864,8 @@ void nxdn_deperm_facch3_udch2(dsd_opts * opts, dsd_state * state, uint8_t bits[2
|
|||||||
if (i == 12) fprintf (stderr, "\n ");
|
if (i == 12) fprintf (stderr, "\n ");
|
||||||
fprintf (stderr, "[%02X]", f3_udch2_bytes[i]);
|
fprintf (stderr, "[%02X]", f3_udch2_bytes[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (crc[0] != check[0] || crc[1] != check[1]) && opts->payload == 1)
|
|
||||||
{
|
|
||||||
|
|
||||||
fprintf (stderr, "%s", KRED);
|
|
||||||
fprintf (stderr, " (CRC ERR)");
|
|
||||||
fprintf (stderr, "%s", KNRM);
|
|
||||||
|
|
||||||
// fprintf (stderr, " - %03X %03X", check[0], crc[0]);
|
// fprintf (stderr, " - %03X %03X", check[0], crc[0]);
|
||||||
// fprintf (stderr, " - %03X %03X", check[1], crc[1]);
|
// fprintf (stderr, " - %03X %03X", check[1], crc[1]);
|
||||||
}
|
|
||||||
|
|
||||||
if (type == 0)
|
if (type == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,13 +15,10 @@
|
|||||||
void NXDN_SACCH_Full_decode(dsd_opts * opts, dsd_state * state)
|
void NXDN_SACCH_Full_decode(dsd_opts * opts, dsd_state * state)
|
||||||
{
|
{
|
||||||
uint8_t SACCH[400]; //72
|
uint8_t SACCH[400]; //72
|
||||||
uint8_t sacch_bytes[10];
|
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint8_t CrcCorrect = 1;
|
uint8_t CrcCorrect = 1;
|
||||||
|
|
||||||
memset (SACCH, 0, sizeof (SACCH));
|
memset (SACCH, 0, sizeof (SACCH));
|
||||||
memset (sacch_bytes, 0, sizeof (sacch_bytes));
|
|
||||||
|
|
||||||
/* Consider all SACCH CRC parts as correct */
|
/* Consider all SACCH CRC parts as correct */
|
||||||
CrcCorrect = 1;
|
CrcCorrect = 1;
|
||||||
@@ -44,17 +41,6 @@ void NXDN_SACCH_Full_decode(dsd_opts * opts, dsd_state * state)
|
|||||||
memset (state->nxdn_sacch_frame_segment, 1, sizeof(state->nxdn_sacch_frame_segment));
|
memset (state->nxdn_sacch_frame_segment, 1, sizeof(state->nxdn_sacch_frame_segment));
|
||||||
memset (state->nxdn_sacch_frame_segcrc, 1, sizeof(state->nxdn_sacch_frame_segcrc));
|
memset (state->nxdn_sacch_frame_segcrc, 1, sizeof(state->nxdn_sacch_frame_segcrc));
|
||||||
|
|
||||||
if (opts->payload == 1)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "\n");
|
|
||||||
fprintf (stderr, " Full SACCH Payload ");
|
|
||||||
for (i = 0; i < 9; i++)
|
|
||||||
{
|
|
||||||
sacch_bytes[i] = (uint8_t)ConvertBitIntoBytes(&SACCH[i*8], 8);
|
|
||||||
fprintf (stderr, "[%02X]", sacch_bytes[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} /* End NXDN_SACCH_Full_decode() */
|
} /* End NXDN_SACCH_Full_decode() */
|
||||||
|
|
||||||
@@ -74,8 +60,6 @@ void NXDN_Elements_Content_decode(dsd_opts * opts, dsd_state * state,
|
|||||||
MessageType |= (ElementsContent[6] & 1) << 1;
|
MessageType |= (ElementsContent[6] & 1) << 1;
|
||||||
MessageType |= (ElementsContent[7] & 1) << 0;
|
MessageType |= (ElementsContent[7] & 1) << 0;
|
||||||
|
|
||||||
nxdn_message_type (opts, state, MessageType);
|
|
||||||
|
|
||||||
/* Save the "F1" and "F2" flags */
|
/* Save the "F1" and "F2" flags */
|
||||||
state->NxdnElementsContent.F1 = ElementsContent[0];
|
state->NxdnElementsContent.F1 = ElementsContent[0];
|
||||||
state->NxdnElementsContent.F2 = ElementsContent[1];
|
state->NxdnElementsContent.F2 = ElementsContent[1];
|
||||||
@@ -159,20 +143,16 @@ void NXDN_Elements_Content_decode(dsd_opts * opts, dsd_state * state,
|
|||||||
SetFreq(opts->rigctl_sockfd, state->p25_cc_freq);
|
SetFreq(opts->rigctl_sockfd, state->p25_cc_freq);
|
||||||
|
|
||||||
}
|
}
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
|
||||||
//extra safeguards due to sync issues with NXDN
|
//extra safeguards due to sync issues with NXDN
|
||||||
memset (state->nxdn_sacch_frame_segment, 1, sizeof(state->nxdn_sacch_frame_segment));
|
memset (state->nxdn_sacch_frame_segment, 1, sizeof(state->nxdn_sacch_frame_segment));
|
||||||
memset (state->nxdn_sacch_frame_segcrc, 1, sizeof(state->nxdn_sacch_frame_segcrc));
|
memset (state->nxdn_sacch_frame_segcrc, 1, sizeof(state->nxdn_sacch_frame_segcrc));
|
||||||
memset(state->active_channel, 0, sizeof(state->active_channel));
|
memset(state->active_channel, 0, sizeof(state->active_channel));
|
||||||
opts->p25_is_tuned = 0;
|
opts->p25_is_tuned = 0;
|
||||||
rtl_dev_tune (opts, state->p25_cc_freq);
|
rtl_udp_tune (opts, state, state->p25_cc_freq);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state->last_cc_sync_time = time(NULL); //allow tuners a second to catch up, particularly rtl input
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -193,6 +173,8 @@ void NXDN_Elements_Content_decode(dsd_opts * opts, dsd_state * state,
|
|||||||
}
|
}
|
||||||
} /* End switch(MessageType) */
|
} /* End switch(MessageType) */
|
||||||
|
|
||||||
|
nxdn_message_type (opts, state, MessageType);
|
||||||
|
|
||||||
} /* End NXDN_Elements_Content_decode() */
|
} /* End NXDN_Elements_Content_decode() */
|
||||||
|
|
||||||
//externalize multiple sub-element handlers
|
//externalize multiple sub-element handlers
|
||||||
@@ -588,10 +570,9 @@ void NXDN_decode_VCALL_ASSGN(dsd_opts * opts, dsd_state * state, uint8_t * Messa
|
|||||||
}
|
}
|
||||||
if (state->M == 1) state->nxdn_cipher_type = 0x1;
|
if (state->M == 1) state->nxdn_cipher_type = 0x1;
|
||||||
}
|
}
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
|
||||||
//extra safeguards due to sync issues with NXDN
|
//extra safeguards due to sync issues with NXDN
|
||||||
memset (state->nxdn_sacch_frame_segment, 1, sizeof(state->nxdn_sacch_frame_segment));
|
memset (state->nxdn_sacch_frame_segment, 1, sizeof(state->nxdn_sacch_frame_segment));
|
||||||
memset (state->nxdn_sacch_frame_segcrc, 1, sizeof(state->nxdn_sacch_frame_segcrc));
|
memset (state->nxdn_sacch_frame_segcrc, 1, sizeof(state->nxdn_sacch_frame_segcrc));
|
||||||
@@ -600,7 +581,7 @@ void NXDN_decode_VCALL_ASSGN(dsd_opts * opts, dsd_state * state, uint8_t * Messa
|
|||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
//
|
//
|
||||||
|
|
||||||
rtl_dev_tune (opts, freq);
|
rtl_udp_tune (opts, state, freq);
|
||||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
|
|
||||||
@@ -618,7 +599,6 @@ void NXDN_decode_VCALL_ASSGN(dsd_opts * opts, dsd_state * state, uint8_t * Messa
|
|||||||
fprintf (stderr, " Key Loaded: %lld", state->rkey_array[DestinationID]);
|
fprintf (stderr, " Key Loaded: %lld", state->rkey_array[DestinationID]);
|
||||||
}
|
}
|
||||||
if (state->M == 1) state->nxdn_cipher_type = 0x1;
|
if (state->M == 1) state->nxdn_cipher_type = 0x1;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -811,7 +791,7 @@ void NXDN_decode_srv_info(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
|||||||
|
|
||||||
//poll for current frequency, will always be the control channel
|
//poll for current frequency, will always be the control channel
|
||||||
//this PDU is constantly pumped out on the CC CAC Message
|
//this PDU is constantly pumped out on the CC CAC Message
|
||||||
if (opts->p25_trunk == 1 && opts->p25_is_tuned == 0) //changed this so the rtl tuning lag doesn't set RTCH frequency after tuning but before landing
|
if (opts->p25_trunk == 1)
|
||||||
{
|
{
|
||||||
long int ccfreq = 0;
|
long int ccfreq = 0;
|
||||||
//if using rigctl, we can poll for the current frequency
|
//if using rigctl, we can poll for the current frequency
|
||||||
@@ -821,7 +801,7 @@ void NXDN_decode_srv_info(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
|||||||
if (ccfreq != 0) state->p25_cc_freq = ccfreq;
|
if (ccfreq != 0) state->p25_cc_freq = ccfreq;
|
||||||
}
|
}
|
||||||
//if using rtl input, we can ask for the current frequency tuned
|
//if using rtl input, we can ask for the current frequency tuned
|
||||||
else if (opts->audio_in_type == 3) //after changing to rtl_dev_tune, this may lag a bit due to delay in sample delivery?
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
ccfreq = (long int)opts->rtlsdr_center_freq;
|
ccfreq = (long int)opts->rtlsdr_center_freq;
|
||||||
if (ccfreq != 0) state->p25_cc_freq = ccfreq;
|
if (ccfreq != 0) state->p25_cc_freq = ccfreq;
|
||||||
@@ -1145,9 +1125,56 @@ void NXDN_decode_VCALL(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
|||||||
if (state->rkey_array[KeyID] != 0) state->R = state->rkey_array[KeyID];
|
if (state->rkey_array[KeyID] != 0) state->R = state->rkey_array[KeyID];
|
||||||
else if (state->rkey_array[DestinationID] != 0) state->R = state->rkey_array[DestinationID];
|
else if (state->rkey_array[DestinationID] != 0) state->R = state->rkey_array[DestinationID];
|
||||||
|
|
||||||
|
// #ifdef LIMAZULUTWEAKS
|
||||||
|
|
||||||
|
// //LimaZulu specific tweak, load keys from frequency value, if avalable -- untested
|
||||||
|
|
||||||
|
// long int freq = 0;
|
||||||
|
// uint8_t hash_bits[24];
|
||||||
|
// memset (hash_bits, 0, sizeof(hash_bits));
|
||||||
|
// uint16_t limazulu = 0;
|
||||||
|
|
||||||
|
// //if not available, then poll rigctl if its available
|
||||||
|
// if (opts->use_rigctl == 1)
|
||||||
|
// freq = GetCurrentFreq (opts->rigctl_sockfd);
|
||||||
|
|
||||||
|
// //if using rtl input, we can ask for the current frequency tuned
|
||||||
|
// else if (opts->audio_in_type == 3)
|
||||||
|
// freq = (long int)opts->rtlsdr_center_freq;
|
||||||
|
|
||||||
|
// //freq = 167831250; //hardset for testing
|
||||||
|
|
||||||
|
// //since a frequency value will be larger than the 16-bit max, we need to hash it first
|
||||||
|
// //the hash has to be run the same way as the import, so at a 24-bit depth, which hopefully
|
||||||
|
// //will not lead to any duplicate key loads due to multiple CRC16 collisions on a larger value?
|
||||||
|
// for (int i = 0; i < 24; i++)
|
||||||
|
// hash_bits[i] = ((freq << i) & 0x800000) >> 23; //load into array for CRC16
|
||||||
|
|
||||||
|
// if (freq) limazulu = ComputeCrcCCITT16d (hash_bits, 24);
|
||||||
|
// limazulu = limazulu & 0xFFFF; //make sure no larger than 16-bits
|
||||||
|
|
||||||
|
// fprintf (stderr, "%s", KCYN);
|
||||||
|
// if (freq) fprintf (stderr, "\n Freq: %ld - Freq Hash: %d", freq, limazulu);
|
||||||
|
// if (state->rkey_array[limazulu] != 0) fprintf (stderr, " - Key Loaded: %lld", state->rkey_array[limazulu]);
|
||||||
|
// fprintf (stderr, "%s", KNRM);
|
||||||
|
|
||||||
|
// if (state->rkey_array[limazulu] != 0)
|
||||||
|
// state->R = state->rkey_array[limazulu];
|
||||||
|
|
||||||
|
// #endif //end LIMAZULUTWEAKS
|
||||||
|
|
||||||
//Don't zero key if no keyloader
|
//Don't zero key if no keyloader
|
||||||
if (CipherType != 0x1 && state->keyloader == 1) state->R = 0;
|
if (CipherType != 0x1 && state->keyloader == 1) state->R = 0;
|
||||||
|
|
||||||
|
//NOTE: Broadcast Call appears to have values that aren't typical for VCALL,
|
||||||
|
//so not applying any settings below if CallType == 0 (BC Call)
|
||||||
|
|
||||||
|
//NOTE: Above note may be in error; its possible that the issues I was having
|
||||||
|
//was from not resetting the entire SACCH superframe after reading it, and
|
||||||
|
//the samples in question having interwoven ALIAS and VCALL, and bad settings
|
||||||
|
//coming from a missed SF Part of Frame, if not reset, we could skip a SF POF
|
||||||
|
//and still believe we have a good decode -- will need further testing #118
|
||||||
|
|
||||||
/* Print the "Cipher Type" */
|
/* Print the "Cipher Type" */
|
||||||
if(CipherType != 0 && MessageType == 0x1)
|
if(CipherType != 0 && MessageType == 0x1)
|
||||||
{
|
{
|
||||||
@@ -1276,7 +1303,6 @@ void NXDN_decode_scch(dsd_opts * opts, dsd_state * state, uint8_t * Message, uin
|
|||||||
if (opcode == 0x4 || opcode == 0x0) //INFO 4
|
if (opcode == 0x4 || opcode == 0x0) //INFO 4
|
||||||
{
|
{
|
||||||
//clear stale active channel listing -- consider best placement for this (NXDN Type D Trunking -- inside a particular OSM Message?)
|
//clear stale active channel listing -- consider best placement for this (NXDN Type D Trunking -- inside a particular OSM Message?)
|
||||||
//may not be entirely necessary here in this context
|
|
||||||
if ( (time(NULL) - state->last_active_time) > 3 )
|
if ( (time(NULL) - state->last_active_time) > 3 )
|
||||||
{
|
{
|
||||||
memset (state->active_channel, 0, sizeof(state->active_channel));
|
memset (state->active_channel, 0, sizeof(state->active_channel));
|
||||||
@@ -1357,8 +1383,8 @@ void NXDN_decode_scch(dsd_opts * opts, dsd_state * state, uint8_t * Message, uin
|
|||||||
//add current active to display string -- may need tweaking on if to use rep1 (active ch), or rep2 (home prefix)
|
//add current active to display string -- may need tweaking on if to use rep1 (active ch), or rep2 (home prefix)
|
||||||
if (rep1 != 0 && rep1 != 31)
|
if (rep1 != 0 && rep1 != 31)
|
||||||
{
|
{
|
||||||
if (gu == 0) sprintf (state->active_channel[rep1], "Active Group Ch: %d TG: %d-%d; ", rep1, rep2, id); //Group TG
|
if (gu == 0) sprintf (state->active_channel[rep1], "Active Ch: %d TG: %d-%d; ", rep1, rep2, id); //Group TG
|
||||||
else sprintf (state->active_channel[rep1], "Active Private Ch: %d TGT: %d-%d; ", rep1, rep2, id); //Private TGT
|
else sprintf (state->active_channel[rep1], "Active Ch: %d TGT: %d-%d; ", rep1, rep2, id); //Private TGT
|
||||||
state->last_active_time = time(NULL);
|
state->last_active_time = time(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1404,8 +1430,7 @@ void NXDN_decode_scch(dsd_opts * opts, dsd_state * state, uint8_t * Message, uin
|
|||||||
//check to see if the source/target candidate is blocked first
|
//check to see if the source/target candidate is blocked first
|
||||||
if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0)) //DE is digital encrypted, B is block
|
if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0)) //DE is digital encrypted, B is block
|
||||||
{
|
{
|
||||||
//will need to monitor, 1 second may be too long on idas, may need to try 0 or manipulate another way
|
if (state->p25_cc_freq != 0 && state->last_vc_sync_time > 1 && freq != 0) //if we aren't already on a VC and have a valid frequency already
|
||||||
if (state->p25_cc_freq != 0 && ((time(NULL) - state->last_vc_sync_time) > 1) && freq != 0)
|
|
||||||
{
|
{
|
||||||
//rigctl
|
//rigctl
|
||||||
if (opts->use_rigctl == 1)
|
if (opts->use_rigctl == 1)
|
||||||
@@ -1426,10 +1451,9 @@ void NXDN_decode_scch(dsd_opts * opts, dsd_state * state, uint8_t * Message, uin
|
|||||||
if (state->rkey_array[id] != 0) state->R = state->rkey_array[id];
|
if (state->rkey_array[id] != 0) state->R = state->rkey_array[id];
|
||||||
if (state->M == 1) state->nxdn_cipher_type = 0x1;
|
if (state->M == 1) state->nxdn_cipher_type = 0x1;
|
||||||
}
|
}
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
|
||||||
//extra safeguards due to sync issues with NXDN
|
//extra safeguards due to sync issues with NXDN
|
||||||
memset (state->nxdn_sacch_frame_segment, 1, sizeof(state->nxdn_sacch_frame_segment));
|
memset (state->nxdn_sacch_frame_segment, 1, sizeof(state->nxdn_sacch_frame_segment));
|
||||||
memset (state->nxdn_sacch_frame_segcrc, 1, sizeof(state->nxdn_sacch_frame_segcrc));
|
memset (state->nxdn_sacch_frame_segcrc, 1, sizeof(state->nxdn_sacch_frame_segcrc));
|
||||||
@@ -1437,14 +1461,13 @@ void NXDN_decode_scch(dsd_opts * opts, dsd_state * state, uint8_t * Message, uin
|
|||||||
state->last_cc_sync_time = time(NULL);
|
state->last_cc_sync_time = time(NULL);
|
||||||
state->last_vc_sync_time = time(NULL); //should we use this here, or not?
|
state->last_vc_sync_time = time(NULL); //should we use this here, or not?
|
||||||
//
|
//
|
||||||
rtl_dev_tune (opts, freq);
|
rtl_udp_tune (opts, state, freq);
|
||||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
//check the rkey array for a scrambler key value
|
//check the rkey array for a scrambler key value
|
||||||
//TGT ID and Key ID could clash though if csv or system has both with different keys
|
//TGT ID and Key ID could clash though if csv or system has both with different keys
|
||||||
if (state->rkey_array[id] != 0) state->R = state->rkey_array[id];
|
if (state->rkey_array[id] != 0) state->R = state->rkey_array[id];
|
||||||
if (state->M == 1) state->nxdn_cipher_type = 0x1;
|
if (state->M == 1) state->nxdn_cipher_type = 0x1;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ void nxdn_frame (dsd_opts * opts, dsd_state * state)
|
|||||||
uint8_t facch_bits_b[144];
|
uint8_t facch_bits_b[144];
|
||||||
uint8_t cac_bits[300];
|
uint8_t cac_bits[300];
|
||||||
uint8_t facch2_bits[348]; //facch2 or udch, same amount of bits
|
uint8_t facch2_bits[348]; //facch2 or udch, same amount of bits
|
||||||
uint8_t facch3_bits[288]; //facch3 or udch2, same amount of bits
|
uint8_t facch3_bits[288]; //facch3 or udch2, same amoount of bits
|
||||||
|
|
||||||
//nxdn bit buffer, for easy assignment handling
|
//nxdn bit buffer, for easy assignment handling
|
||||||
int nxdn_bit_buffer[364];
|
int nxdn_bit_buffer[364];
|
||||||
@@ -252,7 +252,7 @@ void nxdn_frame (dsd_opts * opts, dsd_state * state)
|
|||||||
if (opts->payload == 1)
|
if (opts->payload == 1)
|
||||||
fprintf (stderr, "L%02X - ", lich);
|
fprintf (stderr, "L%02X - ", lich);
|
||||||
}
|
}
|
||||||
else if (voice || facch || sacch || facch2 || udch || cac)
|
else if (voice || facch || sacch || facch2 || cac)
|
||||||
{
|
{
|
||||||
if (opts->frame_nxdn48 == 1)
|
if (opts->frame_nxdn48 == 1)
|
||||||
{
|
{
|
||||||
@@ -396,9 +396,6 @@ void nxdn_frame (dsd_opts * opts, dsd_state * state)
|
|||||||
|
|
||||||
#endif //end LIMAZULUTWEAKS
|
#endif //end LIMAZULUTWEAKS
|
||||||
|
|
||||||
if (opts->scanner_mode == 1)
|
|
||||||
state->last_cc_sync_time = time(NULL) + 2; //add a little extra hangtime between resuming scan
|
|
||||||
|
|
||||||
//Option/Steal Flags echoed in Voice, V+F, or Data
|
//Option/Steal Flags echoed in Voice, V+F, or Data
|
||||||
if (voice && !facch) //voice only, no facch steal
|
if (voice && !facch) //voice only, no facch steal
|
||||||
{
|
{
|
||||||
@@ -464,17 +461,8 @@ void nxdn_frame (dsd_opts * opts, dsd_state * state)
|
|||||||
if (facch2) nxdn_deperm_facch2_udch(opts, state, facch2_bits, 1);
|
if (facch2) nxdn_deperm_facch2_udch(opts, state, facch2_bits, 1);
|
||||||
|
|
||||||
//SHOULD be okay to run facch1's again on steal frames, will need testing
|
//SHOULD be okay to run facch1's again on steal frames, will need testing
|
||||||
// if (facch & 1) nxdn_deperm_facch(opts, state, facch_bits_a);
|
|
||||||
// if (facch & 2) nxdn_deperm_facch(opts, state, facch_bits_b);
|
|
||||||
|
|
||||||
//only run facch in second slot if its not equal to the first one
|
|
||||||
//ideally, this would work better AFTER decoding/FEC
|
|
||||||
if (facch & 1) nxdn_deperm_facch(opts, state, facch_bits_a);
|
if (facch & 1) nxdn_deperm_facch(opts, state, facch_bits_a);
|
||||||
if (facch & 2)
|
if (facch & 2) nxdn_deperm_facch(opts, state, facch_bits_b);
|
||||||
{
|
|
||||||
if (memcmp (facch_bits_a, facch_bits_b, 144) != 0)
|
|
||||||
nxdn_deperm_facch(opts, state, facch_bits_b);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (voice)
|
if (voice)
|
||||||
{
|
{
|
||||||
@@ -500,7 +488,6 @@ void nxdn_frame (dsd_opts * opts, dsd_state * state)
|
|||||||
closeMbeOutFile (opts, state);
|
closeMbeOutFile (opts, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//may need to reconsider this, due to double FACCH1 steals on some Type-C (ASSGN_DUP, etc) and Conventional Systems (random IDLE FACCH1 steal for no reason)
|
|
||||||
if (opts->frame_nxdn48 == 1) closeMbeOutFile (opts, state); //okay to close right away if nxdn48, no data/voice frames mixing
|
if (opts->frame_nxdn48 == 1) closeMbeOutFile (opts, state); //okay to close right away if nxdn48, no data/voice frames mixing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -295,20 +295,9 @@ void p25_lcw (dsd_opts * opts, dsd_state * state, uint8_t LCW_bits[], uint8_t ir
|
|||||||
//tune back to CC here - save about 1-2 seconds
|
//tune back to CC here - save about 1-2 seconds
|
||||||
else if (lc_format == 0x4F) //# Call Termination/Cancellation
|
else if (lc_format == 0x4F) //# Call Termination/Cancellation
|
||||||
{
|
{
|
||||||
fprintf (stderr, " Call Termination");
|
fprintf (stderr, " Call Termination/Cancellation");
|
||||||
if (opts->p25_trunk == 1 && state->p25_cc_freq != 0 && opts->p25_is_tuned == 1)
|
if (opts->p25_trunk == 1 && state->p25_cc_freq != 0 && opts->p25_is_tuned == 1)
|
||||||
{
|
{
|
||||||
|
|
||||||
//Will we need to check for a symbolrate change here, can a P25p2 TDMA-CC system
|
|
||||||
//revert back to a phase 1 traffic channel or carry a phase 1 traffic channel?
|
|
||||||
|
|
||||||
//clear heuristics from current traffic channel
|
|
||||||
if (opts->frame_p25p1 == 1 && opts->use_heuristics == 1)
|
|
||||||
{
|
|
||||||
initialize_p25_heuristics(&state->p25_heuristics);
|
|
||||||
initialize_p25_heuristics(&state->inv_p25_heuristics);
|
|
||||||
}
|
|
||||||
|
|
||||||
//rigctl
|
//rigctl
|
||||||
if (opts->use_rigctl == 1)
|
if (opts->use_rigctl == 1)
|
||||||
{
|
{
|
||||||
@@ -327,10 +316,9 @@ void p25_lcw (dsd_opts * opts, dsd_state * state, uint8_t LCW_bits[], uint8_t ir
|
|||||||
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
||||||
SetFreq(opts->rigctl_sockfd, state->p25_cc_freq);
|
SetFreq(opts->rigctl_sockfd, state->p25_cc_freq);
|
||||||
}
|
}
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
|
||||||
state->lasttg = 0;
|
state->lasttg = 0;
|
||||||
state->lastsrc = 0;
|
state->lastsrc = 0;
|
||||||
state->payload_algid = 0;
|
state->payload_algid = 0;
|
||||||
@@ -343,8 +331,7 @@ void p25_lcw (dsd_opts * opts, dsd_state * state, uint8_t LCW_bits[], uint8_t ir
|
|||||||
sprintf (state->active_channel[1], "%s", "");
|
sprintf (state->active_channel[1], "%s", "");
|
||||||
opts->p25_is_tuned = 0;
|
opts->p25_is_tuned = 0;
|
||||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = 0;
|
state->p25_vc_freq[0] = state->p25_vc_freq[1] = 0;
|
||||||
rtl_dev_tune (opts, state->p25_cc_freq);
|
rtl_udp_tune (opts, state, state->p25_cc_freq);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -459,9 +459,6 @@ processHDU(dsd_opts* opts, dsd_state* state)
|
|||||||
mihex2 = (unsigned long long int)ConvertBitIntoBytes(&mi[32], 32);
|
mihex2 = (unsigned long long int)ConvertBitIntoBytes(&mi[32], 32);
|
||||||
mihex3 = (unsigned long long int)ConvertBitIntoBytes(&mi[64], 8);
|
mihex3 = (unsigned long long int)ConvertBitIntoBytes(&mi[64], 8);
|
||||||
|
|
||||||
//reset dropbytes - skip first 11 for LCW
|
|
||||||
state->dropL = 267;
|
|
||||||
|
|
||||||
//set vc counter to 0
|
//set vc counter to 0
|
||||||
state->p25vc = 0;
|
state->p25vc = 0;
|
||||||
|
|
||||||
@@ -469,19 +466,14 @@ processHDU(dsd_opts* opts, dsd_state* state)
|
|||||||
{
|
{
|
||||||
|
|
||||||
fprintf (stderr, "%s", KYEL);
|
fprintf (stderr, "%s", KYEL);
|
||||||
fprintf (stderr, " HDU ALG ID: 0x%02X KEY ID: 0x%04X MI: 0x%08llX%08llX%02llX", algidhex, kidhex, mihex1, mihex2, mihex3);
|
fprintf (stderr, " HDU ALG ID: 0x%02X KEY ID: 0x%02X MI: 0x%08llX%08llX%02llX", algidhex, kidhex, mihex1, mihex2, mihex3);
|
||||||
|
fprintf (stderr, "%s", KNRM);
|
||||||
state->payload_algid = algidhex;
|
state->payload_algid = algidhex;
|
||||||
state->payload_keyid = kidhex;
|
state->payload_keyid = kidhex;
|
||||||
if (state->R != 0 && state->payload_algid == 0xAA)
|
|
||||||
{
|
|
||||||
fprintf (stderr, " Key: %010llX", state->R);
|
|
||||||
opts->unmute_encrypted_p25 = 1;
|
|
||||||
}
|
|
||||||
fprintf (stderr, "%s", KNRM);
|
|
||||||
//only use 64 MSB, trailing 8 bits aren't used, so no mihex3
|
//only use 64 MSB, trailing 8 bits aren't used, so no mihex3
|
||||||
state->payload_miP = (mihex1 << 32) | (mihex2);
|
state->payload_miP = (mihex1 << 32) | (mihex2);
|
||||||
|
|
||||||
if (state->payload_algid != 0x80 && state->payload_algid != 0x0)
|
if (state->payload_algid != 0x80 && state->payload_algid != 0x0) //print on payload == 1
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s", KRED);
|
fprintf (stderr, "%s", KRED);
|
||||||
fprintf (stderr, " ENC");
|
fprintf (stderr, " ENC");
|
||||||
|
|||||||
@@ -171,8 +171,6 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
|
|||||||
|
|
||||||
// TODO: error correction of the LSD bytes...
|
// TODO: error correction of the LSD bytes...
|
||||||
// TODO: do something useful with the LSD bytes...
|
// TODO: do something useful with the LSD bytes...
|
||||||
|
|
||||||
state->dropL += 2; //need to skip 2 here for the LSD bytes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IMBE 9
|
// IMBE 9
|
||||||
|
|||||||
@@ -172,8 +172,6 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
|
|||||||
|
|
||||||
// TODO: error correction of the LSD bytes...
|
// TODO: error correction of the LSD bytes...
|
||||||
// TODO: do something useful with the LSD bytes...
|
// TODO: do something useful with the LSD bytes...
|
||||||
|
|
||||||
state->dropL += 2; //need to skip 2 here for the LSD bytes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IMBE 9
|
// IMBE 9
|
||||||
@@ -185,9 +183,6 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
|
|||||||
//set vc counter to 0
|
//set vc counter to 0
|
||||||
state->p25vc = 0;
|
state->p25vc = 0;
|
||||||
|
|
||||||
//reset dropbytes -- skip first 11 for next LCW
|
|
||||||
state->dropL = 267;
|
|
||||||
|
|
||||||
if (opts->errorbars == 1)
|
if (opts->errorbars == 1)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
@@ -371,19 +366,15 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
|
|||||||
if (irrecoverable_errors == 0)
|
if (irrecoverable_errors == 0)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s", KYEL);
|
fprintf (stderr, "%s", KYEL);
|
||||||
fprintf (stderr, " LDU2 ALG ID: 0x%02X KEY ID: 0x%04X MI: 0x%08llX%08llX%02llX", algidhex, kidhex, mihex1, mihex2, mihex3);
|
fprintf (stderr, " LDU2 ALG ID: 0x%02X KEY ID: 0x%02X MI: 0x%08llX%08llX%02llX", algidhex, kidhex, mihex1, mihex2, mihex3);
|
||||||
|
fprintf (stderr, "%s", KNRM);
|
||||||
|
|
||||||
state->payload_algid = algidhex;
|
state->payload_algid = algidhex;
|
||||||
state->payload_keyid = kidhex;
|
state->payload_keyid = kidhex;
|
||||||
if (state->R != 0 && state->payload_algid == 0xAA)
|
|
||||||
{
|
|
||||||
fprintf (stderr, " Key: %010llX", state->R);
|
|
||||||
opts->unmute_encrypted_p25 = 1;
|
|
||||||
}
|
|
||||||
fprintf (stderr, "%s", KNRM);
|
|
||||||
//only use 64 MSB, trailing 8 bits aren't used, so no mihex3
|
//only use 64 MSB, trailing 8 bits aren't used, so no mihex3
|
||||||
state->payload_miP = (mihex1 << 32) | (mihex2);
|
state->payload_miP = (mihex1 << 32) | (mihex2);
|
||||||
|
|
||||||
if (state->payload_algid != 0x80 && state->payload_algid != 0x0)
|
if (state->payload_algid != 0x80 && state->payload_algid != 0x0) //print on payload == 1
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s", KRED);
|
fprintf (stderr, "%s", KRED);
|
||||||
fprintf (stderr, " ENC");
|
fprintf (stderr, " ENC");
|
||||||
@@ -399,45 +390,4 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
|
|||||||
fprintf (stderr, "%s", KNRM);
|
fprintf (stderr, "%s", KNRM);
|
||||||
}
|
}
|
||||||
|
|
||||||
//run LFSR on the MI if we have irrecoverable errors here
|
|
||||||
if (irrecoverable_errors && state->payload_algid != 0x80 && state->payload_keyid != 0 && state->payload_miP != 0)
|
|
||||||
{
|
|
||||||
LFSRP(state);
|
|
||||||
fprintf (stderr, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//LFSR code courtesy of https://github.com/mattames/LFSR/
|
|
||||||
void LFSRP(dsd_state * state)
|
|
||||||
{
|
|
||||||
//rework for P2 TDMA support
|
|
||||||
unsigned long long int lfsr = 0;
|
|
||||||
if (state->currentslot == 0)
|
|
||||||
lfsr = state->payload_miP;
|
|
||||||
|
|
||||||
if (state->currentslot == 1)
|
|
||||||
lfsr = state->payload_miN;
|
|
||||||
|
|
||||||
int cnt = 0;
|
|
||||||
for(cnt=0;cnt<64;cnt++)
|
|
||||||
{
|
|
||||||
// Polynomial is C(x) = x^64 + x^62 + x^46 + x^38 + x^27 + x^15 + 1
|
|
||||||
unsigned long long int bit = ((lfsr >> 63) ^ (lfsr >> 61) ^ (lfsr >> 45) ^ (lfsr >> 37) ^ (lfsr >> 26) ^ (lfsr >> 14)) & 0x1;
|
|
||||||
lfsr = (lfsr << 1) | (bit);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->currentslot == 0)
|
|
||||||
state->payload_miP = lfsr;
|
|
||||||
|
|
||||||
if (state->currentslot == 1)
|
|
||||||
state->payload_miN = lfsr;
|
|
||||||
|
|
||||||
//print current ENC identifiers already known and new calculated MI
|
|
||||||
fprintf (stderr, "%s", KYEL);
|
|
||||||
if (state->currentslot == 0)
|
|
||||||
fprintf (stderr, " LDU2/ESS_B FEC ERR - ALG: 0x%02X KEY ID: 0x%04X LFSR MI: 0x%016llX", state->payload_algid, state->payload_keyid, state->payload_miP);
|
|
||||||
if (state->currentslot == 1)
|
|
||||||
fprintf (stderr, " LDU2/ESS_B FEC ERR - ALG: 0x%02X KEY ID: 0x%04X LFSR MI: 0x%016llX", state->payload_algidR, state->payload_keyidR, state->payload_miN);
|
|
||||||
fprintf (stderr, "%s", KNRM);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -337,20 +337,10 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
|
|||||||
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq1 != 0) //if we aren't already on a VC and have a valid frequency
|
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq1 != 0) //if we aren't already on a VC and have a valid frequency
|
||||||
{
|
{
|
||||||
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||||
// if (opts->mod_qpsk == 1)
|
if (opts->mod_qpsk == 1)
|
||||||
// {
|
|
||||||
// int spacing = state->p25_chan_spac[channelt >> 12];
|
|
||||||
// if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
|
||||||
// {
|
|
||||||
// state->samplesPerSymbol = 8;
|
|
||||||
// state->symbolCenter = 3;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
//changed to allow symbol rate change on C4FM Phase 2 systems as well as QPSK
|
|
||||||
if (1 == 1)
|
|
||||||
{
|
{
|
||||||
if (state->p25_chan_tdma[channelt >> 12] == 1)
|
int spacing = state->p25_chan_spac[channelt >> 12];
|
||||||
|
if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||||
{
|
{
|
||||||
state->samplesPerSymbol = 8;
|
state->samplesPerSymbol = 8;
|
||||||
state->symbolCenter = 3;
|
state->symbolCenter = 3;
|
||||||
@@ -365,15 +355,13 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
|
|||||||
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
}
|
}
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune (opts, state, freq1);
|
||||||
rtl_dev_tune (opts, freq1);
|
|
||||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1;
|
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1;
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -433,22 +421,11 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
|
|||||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||||
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq1 != 0) //if we aren't already on a VC and have a valid frequency
|
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq1 != 0) //if we aren't already on a VC and have a valid frequency
|
||||||
{
|
{
|
||||||
|
|
||||||
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||||
// if (opts->mod_qpsk == 1)
|
if (opts->mod_qpsk == 1)
|
||||||
// {
|
|
||||||
// int spacing = state->p25_chan_spac[channelt >> 12];
|
|
||||||
// if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
|
||||||
// {
|
|
||||||
// state->samplesPerSymbol = 8;
|
|
||||||
// state->symbolCenter = 3;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
//changed to allow symbol rate change on C4FM Phase 2 systems as well as QPSK
|
|
||||||
if (1 == 1)
|
|
||||||
{
|
{
|
||||||
if (state->p25_chan_tdma[channelt >> 12] == 1)
|
int spacing = state->p25_chan_spac[channelt >> 12];
|
||||||
|
if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||||
{
|
{
|
||||||
state->samplesPerSymbol = 8;
|
state->samplesPerSymbol = 8;
|
||||||
state->symbolCenter = 3;
|
state->symbolCenter = 3;
|
||||||
@@ -463,15 +440,13 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
|
|||||||
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
}
|
}
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune (opts, state, freq1);
|
||||||
rtl_dev_tune (opts, freq1);
|
|
||||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1;
|
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1;
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -475,16 +475,6 @@ void process_4V (dsd_opts * opts, dsd_state * state)
|
|||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
|
|
||||||
//Cygwin OSS Slot Preference Pre-emption shim
|
|
||||||
if (opts->audio_out_type == 5)
|
|
||||||
{
|
|
||||||
//set to 21 for MBE OSS shim to preempt audio
|
|
||||||
if (state->currentslot == 0) state->dmrburstL = 21;
|
|
||||||
else state->dmrburstR = 21;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
processMbeFrame (opts, state, NULL, ambe_fr1, NULL);
|
processMbeFrame (opts, state, NULL, ambe_fr1, 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);
|
||||||
@@ -552,7 +542,6 @@ void process_ESS (dsd_opts * opts, dsd_state * state)
|
|||||||
fprintf (stderr, " ALG ID 0x%02X", state->payload_algid);
|
fprintf (stderr, " ALG ID 0x%02X", state->payload_algid);
|
||||||
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyid);
|
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyid);
|
||||||
fprintf (stderr, " MI 0x%016llX", state->payload_miP);
|
fprintf (stderr, " MI 0x%016llX", state->payload_miP);
|
||||||
if (state->R != 0 && state->payload_algid == 0xAA) fprintf (stderr, " Key 0x%010llX", state->R);
|
|
||||||
fprintf (stderr, " ESSB");
|
fprintf (stderr, " ESSB");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -568,7 +557,6 @@ void process_ESS (dsd_opts * opts, dsd_state * state)
|
|||||||
fprintf (stderr, " ALG ID 0x%02X", state->payload_algidR);
|
fprintf (stderr, " ALG ID 0x%02X", state->payload_algidR);
|
||||||
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyidR);
|
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyidR);
|
||||||
fprintf (stderr, " MI 0x%016llX", state->payload_miN);
|
fprintf (stderr, " MI 0x%016llX", state->payload_miN);
|
||||||
if (state->RR != 0 && state->payload_algidR == 0xAA) fprintf (stderr, " Key 0x%010llX", state->RR);
|
|
||||||
fprintf (stderr, " ESSB");
|
fprintf (stderr, " ESSB");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,11 +564,7 @@ void process_ESS (dsd_opts * opts, dsd_state * state)
|
|||||||
}
|
}
|
||||||
if (ec == -1 || ec >= 15)
|
if (ec == -1 || ec >= 15)
|
||||||
{
|
{
|
||||||
//ESS R-S Failure -- run LFSR on current MI if applicable
|
//ESS R-S Failure
|
||||||
if (state->currentslot == 0 && state->payload_algid != 0x80 && state->payload_keyid != 0 && state->payload_miP != 0)
|
|
||||||
LFSRP(state);
|
|
||||||
if (state->currentslot == 1 && state->payload_algidR != 0x80 && state->payload_keyidR != 0 && state->payload_miN != 0)
|
|
||||||
LFSRP(state);
|
|
||||||
}
|
}
|
||||||
fprintf (stderr, "%s", KNRM);
|
fprintf (stderr, "%s", KNRM);
|
||||||
|
|
||||||
@@ -642,28 +626,11 @@ void process_2V (dsd_opts * opts, dsd_state * state)
|
|||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
|
|
||||||
//Cygwin OSS Slot Preference Pre-emption shim
|
|
||||||
if (opts->audio_out_type == 5)
|
|
||||||
{
|
|
||||||
//set to 21 for MBE OSS shim to preempt audio
|
|
||||||
if (state->currentslot == 0) state->dmrburstL = 21;
|
|
||||||
else state->dmrburstR = 21;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
processMbeFrame (opts, state, NULL, ambe_fr1, NULL);
|
processMbeFrame (opts, state, NULL, ambe_fr1, NULL);
|
||||||
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
|
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
|
||||||
|
|
||||||
process_ESS(opts, state);
|
process_ESS(opts, state);
|
||||||
|
|
||||||
//reset drop bytes after a 2V
|
|
||||||
if (state->currentslot == 0 && state->payload_algid == 0xAA)
|
|
||||||
state->dropL = 256;
|
|
||||||
|
|
||||||
if (state->currentslot == 1 && state->payload_algidR == 0xAA)
|
|
||||||
state->dropR = 256;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//P2 Data Unit ID
|
//P2 Data Unit ID
|
||||||
@@ -884,6 +851,5 @@ void processP2 (dsd_opts * opts, dsd_state * state)
|
|||||||
process_P2_DUID (opts, state);
|
process_P2_DUID (opts, state);
|
||||||
state->dmr_stereo = 0;
|
state->dmr_stereo = 0;
|
||||||
state->p2_is_lcch = 0;
|
state->p2_is_lcch = 0;
|
||||||
|
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|||||||
190
src/p25p2_vpdu.c
190
src/p25p2_vpdu.c
@@ -118,8 +118,19 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||||
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq != 0) //if we aren't already on a VC and have a valid frequency
|
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq != 0) //if we aren't already on a VC and have a valid frequency
|
||||||
{
|
{
|
||||||
//changed to allow symbol rate change on C4FM Phase 2 systems as well as QPSK
|
// //testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||||
if (1 == 1)
|
// if (opts->mod_qpsk == 1)
|
||||||
|
// {
|
||||||
|
// int spacing = state->p25_chan_spac[channel >> 12];
|
||||||
|
// if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||||
|
// {
|
||||||
|
// state->samplesPerSymbol = 8;
|
||||||
|
// state->symbolCenter = 3;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
//may be this way independent of whether or not this is QPSK (does C4FM run at 6000 sps?)
|
||||||
|
if (opts->mod_qpsk == 1)
|
||||||
{
|
{
|
||||||
if (state->p25_chan_tdma[channel >> 12] == 1)
|
if (state->p25_chan_tdma[channel >> 12] == 1)
|
||||||
{
|
{
|
||||||
@@ -137,15 +148,13 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
}
|
}
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune (opts, state, freq);
|
||||||
rtl_dev_tune (opts, freq);
|
|
||||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,8 +203,19 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||||
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq != 0) //if we aren't already on a VC and have a valid frequency
|
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq != 0) //if we aren't already on a VC and have a valid frequency
|
||||||
{
|
{
|
||||||
//changed to allow symbol rate change on C4FM Phase 2 systems as well as QPSK
|
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||||
if (1 == 1)
|
// if (opts->mod_qpsk == 1)
|
||||||
|
// {
|
||||||
|
// int spacing = state->p25_chan_spac[channel >> 12];
|
||||||
|
// if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||||
|
// {
|
||||||
|
// state->samplesPerSymbol = 8;
|
||||||
|
// state->symbolCenter = 3;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
//may be this way independent of whether or not this is QPSK (does C4FM run at 6000 sps?)
|
||||||
|
if (opts->mod_qpsk == 1)
|
||||||
{
|
{
|
||||||
if (state->p25_chan_tdma[channel >> 12] == 1)
|
if (state->p25_chan_tdma[channel >> 12] == 1)
|
||||||
{
|
{
|
||||||
@@ -212,15 +232,13 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
}
|
}
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune (opts, state, freq);
|
||||||
rtl_dev_tune (opts, freq);
|
|
||||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -302,8 +320,19 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||||
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && tunable_freq != 0) //if we aren't already on a VC and have a valid frequency already
|
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && tunable_freq != 0) //if we aren't already on a VC and have a valid frequency already
|
||||||
{
|
{
|
||||||
//changed to allow symbol rate change on C4FM Phase 2 systems as well as QPSK
|
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||||
if (1 == 1)
|
// if (opts->mod_qpsk == 1)
|
||||||
|
// {
|
||||||
|
// int spacing = state->p25_chan_spac[tunable_chan >> 12];
|
||||||
|
// if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||||
|
// {
|
||||||
|
// state->samplesPerSymbol = 8;
|
||||||
|
// state->symbolCenter = 3;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
//may be this way independent of whether or not this is QPSK (does C4FM run at 6000 sps?)
|
||||||
|
if (opts->mod_qpsk == 1)
|
||||||
{
|
{
|
||||||
if (state->p25_chan_tdma[tunable_chan >> 12] == 1)
|
if (state->p25_chan_tdma[tunable_chan >> 12] == 1)
|
||||||
{
|
{
|
||||||
@@ -324,16 +353,14 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
j = 8; //break loop
|
j = 8; //break loop
|
||||||
|
|
||||||
}
|
}
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune (opts, state, tunable_freq);
|
||||||
rtl_dev_tune (opts, tunable_freq);
|
|
||||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
j = 8; //break loop
|
j = 8; //break loop
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -404,8 +431,19 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||||
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq != 0) //if we aren't already on a VC and have a valid frequency
|
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq != 0) //if we aren't already on a VC and have a valid frequency
|
||||||
{
|
{
|
||||||
//changed to allow symbol rate change on C4FM Phase 2 systems as well as QPSK
|
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||||
if (1 == 1)
|
// if (opts->mod_qpsk == 1)
|
||||||
|
// {
|
||||||
|
// int spacing = state->p25_chan_spac[channel >> 12];
|
||||||
|
// if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||||
|
// {
|
||||||
|
// state->samplesPerSymbol = 8;
|
||||||
|
// state->symbolCenter = 3;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
//may be this way independent of whether or not this is QPSK (does C4FM run at 6000 sps?)
|
||||||
|
if (opts->mod_qpsk == 1)
|
||||||
{
|
{
|
||||||
if (state->p25_chan_tdma[channel >> 12] == 1)
|
if (state->p25_chan_tdma[channel >> 12] == 1)
|
||||||
{
|
{
|
||||||
@@ -423,15 +461,13 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
}
|
}
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune (opts, state, freq);
|
||||||
rtl_dev_tune (opts, freq);
|
|
||||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -488,8 +524,19 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||||
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq != 0) //if we aren't already on a VC and have a valid frequency
|
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq != 0) //if we aren't already on a VC and have a valid frequency
|
||||||
{
|
{
|
||||||
//changed to allow symbol rate change on C4FM Phase 2 systems as well as QPSK
|
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||||
if (1 == 1)
|
// if (opts->mod_qpsk == 1)
|
||||||
|
// {
|
||||||
|
// int spacing = state->p25_chan_spac[channel >> 12];
|
||||||
|
// if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||||
|
// {
|
||||||
|
// state->samplesPerSymbol = 8;
|
||||||
|
// state->symbolCenter = 3;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
//may be this way independent of whether or not this is QPSK (does C4FM run at 6000 sps?)
|
||||||
|
if (opts->mod_qpsk == 1)
|
||||||
{
|
{
|
||||||
if (state->p25_chan_tdma[channel >> 12] == 1)
|
if (state->p25_chan_tdma[channel >> 12] == 1)
|
||||||
{
|
{
|
||||||
@@ -507,15 +554,13 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
}
|
}
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune (opts, state, freq);
|
||||||
rtl_dev_tune (opts, freq);
|
|
||||||
if (state->synctype == 0 || state->synctype == 1) state->p25_vc_freq[0] = freq;
|
if (state->synctype == 0 || state->synctype == 1) state->p25_vc_freq[0] = freq;
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -635,8 +680,19 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||||
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && tunable_freq != 0) //if we aren't already on a VC and have a valid frequency
|
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && tunable_freq != 0) //if we aren't already on a VC and have a valid frequency
|
||||||
{
|
{
|
||||||
//changed to allow symbol rate change on C4FM Phase 2 systems as well as QPSK
|
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||||
if (1 == 1)
|
// if (opts->mod_qpsk == 1)
|
||||||
|
// {
|
||||||
|
// int spacing = state->p25_chan_spac[tunable_chan >> 12];
|
||||||
|
// if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||||
|
// {
|
||||||
|
// state->samplesPerSymbol = 8;
|
||||||
|
// state->symbolCenter = 3;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
//may be this way independent of whether or not this is QPSK (does C4FM run at 6000 sps?)
|
||||||
|
if (opts->mod_qpsk == 1)
|
||||||
{
|
{
|
||||||
if (state->p25_chan_tdma[tunable_chan >> 12] == 1)
|
if (state->p25_chan_tdma[tunable_chan >> 12] == 1)
|
||||||
{
|
{
|
||||||
@@ -654,16 +710,14 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
j = 8; //break loop
|
j = 8; //break loop
|
||||||
}
|
}
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune (opts, state, tunable_freq);
|
||||||
rtl_dev_tune (opts, tunable_freq);
|
|
||||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
j = 8; //break loop
|
j = 8; //break loop
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -803,8 +857,19 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||||
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && tunable_freq != 0) //if we aren't already on a VC and have a valid frequency already
|
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && tunable_freq != 0) //if we aren't already on a VC and have a valid frequency already
|
||||||
{
|
{
|
||||||
//changed to allow symbol rate change on C4FM Phase 2 systems as well as QPSK
|
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||||
if (1 == 1)
|
// if (opts->mod_qpsk == 1)
|
||||||
|
// {
|
||||||
|
// int spacing = state->p25_chan_spac[tunable_chan >> 12];
|
||||||
|
// if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||||
|
// {
|
||||||
|
// state->samplesPerSymbol = 8;
|
||||||
|
// state->symbolCenter = 3;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
//may be this way independent of whether or not this is QPSK (does C4FM run at 6000 sps?)
|
||||||
|
if (opts->mod_qpsk == 1)
|
||||||
{
|
{
|
||||||
if (state->p25_chan_tdma[tunable_chan >> 12] == 1)
|
if (state->p25_chan_tdma[tunable_chan >> 12] == 1)
|
||||||
{
|
{
|
||||||
@@ -824,17 +889,15 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
j = 8; //break loop
|
j = 8; //break loop
|
||||||
}
|
}
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune (opts, state, tunable_freq);
|
||||||
rtl_dev_tune (opts, tunable_freq);
|
|
||||||
//probably best to only set these when really tuning
|
//probably best to only set these when really tuning
|
||||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
j = 8; //break loop
|
j = 8; //break loop
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -916,8 +979,19 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||||
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && tunable_freq != 0) //if we aren't already on a VC and have a valid frequency already
|
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && tunable_freq != 0) //if we aren't already on a VC and have a valid frequency already
|
||||||
{
|
{
|
||||||
//changed to allow symbol rate change on C4FM Phase 2 systems as well as QPSK
|
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||||
if (1 == 1)
|
// if (opts->mod_qpsk == 1)
|
||||||
|
// {
|
||||||
|
// int spacing = state->p25_chan_spac[tunable_chan >> 12];
|
||||||
|
// if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||||
|
// {
|
||||||
|
// state->samplesPerSymbol = 8;
|
||||||
|
// state->symbolCenter = 3;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
//may be this way independent of whether or not this is QPSK (does C4FM run at 6000 sps?)
|
||||||
|
if (opts->mod_qpsk == 1)
|
||||||
{
|
{
|
||||||
if (state->p25_chan_tdma[tunable_chan >> 12] == 1)
|
if (state->p25_chan_tdma[tunable_chan >> 12] == 1)
|
||||||
{
|
{
|
||||||
@@ -937,17 +1011,15 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
j = 8; //break loop
|
j = 8; //break loop
|
||||||
}
|
}
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune (opts, state, tunable_freq);
|
||||||
rtl_dev_tune (opts, tunable_freq);
|
|
||||||
//probably best to only set these when really tuning
|
//probably best to only set these when really tuning
|
||||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
j = 8; //break loop
|
j = 8; //break loop
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1020,9 +1092,19 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||||
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq1 != 0) //if we aren't already on a VC and have a valid frequency
|
if (state->p25_cc_freq != 0 && opts->p25_is_tuned == 0 && freq1 != 0) //if we aren't already on a VC and have a valid frequency
|
||||||
{
|
{
|
||||||
|
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||||
|
// if (opts->mod_qpsk == 1)
|
||||||
|
// {
|
||||||
|
// int spacing = state->p25_chan_spac[channelt >> 12];
|
||||||
|
// if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||||
|
// {
|
||||||
|
// state->samplesPerSymbol = 8;
|
||||||
|
// state->symbolCenter = 3;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
//changed to allow symbol rate change on C4FM Phase 2 systems as well as QPSK
|
//may be this way independent of whether or not this is QPSK (does C4FM run at 6000 sps?)
|
||||||
if (1 == 1)
|
if (opts->mod_qpsk == 1)
|
||||||
{
|
{
|
||||||
if (state->p25_chan_tdma[channelt >> 12] == 1)
|
if (state->p25_chan_tdma[channelt >> 12] == 1)
|
||||||
{
|
{
|
||||||
@@ -1040,15 +1122,13 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
}
|
}
|
||||||
//rtl
|
//rtl_udp
|
||||||
else if (opts->audio_in_type == 3)
|
else if (opts->audio_in_type == 3)
|
||||||
{
|
{
|
||||||
#ifdef USE_RTLSDR
|
rtl_udp_tune (opts, state, freq1);
|
||||||
rtl_dev_tune (opts, freq1);
|
|
||||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1;
|
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1;
|
||||||
opts->p25_is_tuned = 1;
|
opts->p25_is_tuned = 1;
|
||||||
state->last_vc_sync_time = time(NULL);
|
state->last_vc_sync_time = time(NULL);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1543,7 +1623,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||||||
int lcolorcode = ((MAC[12+len_a] & 0xF) << 8) | MAC[13+len_a];
|
int lcolorcode = ((MAC[12+len_a] & 0xF) << 8) | MAC[13+len_a];
|
||||||
fprintf (stderr, "\n Network Status Broadcast - Extended \n");
|
fprintf (stderr, "\n Network Status Broadcast - Extended \n");
|
||||||
fprintf (stderr, " LRA [%02X] WACN [%05X] SYSID [%03X] NAC [%03X] CHAN-T [%04X] CHAN-R [%04X]", lra, lwacn, lsysid, lcolorcode, channelt, channelr);
|
fprintf (stderr, " LRA [%02X] WACN [%05X] SYSID [%03X] NAC [%03X] CHAN-T [%04X] CHAN-R [%04X]", lra, lwacn, lsysid, lcolorcode, channelt, channelr);
|
||||||
state->p25_cc_freq = process_channel_to_freq (opts, state, channelt);
|
process_channel_to_freq (opts, state, channelt);
|
||||||
process_channel_to_freq (opts, state, channelr);
|
process_channel_to_freq (opts, state, channelr);
|
||||||
state->p25_cc_is_tdma = 1; //flag on for CC tuning purposes when system is qpsk
|
state->p25_cc_is_tdma = 1; //flag on for CC tuning purposes when system is qpsk
|
||||||
if (state->p2_hardset == 0 ) //state->p2_is_lcch == 1 shim until CRC is working, prevent bogus data
|
if (state->p2_hardset == 0 ) //state->p2_is_lcch == 1 shim until CRC is working, prevent bogus data
|
||||||
|
|||||||
@@ -120,7 +120,6 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
|
|||||||
{
|
{
|
||||||
//reset fourv_counter and dropbyte on PTT
|
//reset fourv_counter and dropbyte on PTT
|
||||||
state->fourv_counter[0] = 0;
|
state->fourv_counter[0] = 0;
|
||||||
state->dropL = 256;
|
|
||||||
|
|
||||||
state->dmrburstL = 20;
|
state->dmrburstL = 20;
|
||||||
fprintf (stderr, "\n VCH 0 - ");
|
fprintf (stderr, "\n VCH 0 - ");
|
||||||
@@ -143,7 +142,6 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
|
|||||||
fprintf (stderr, "\n ALG ID 0x%02X", state->payload_algid);
|
fprintf (stderr, "\n ALG ID 0x%02X", state->payload_algid);
|
||||||
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyid);
|
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyid);
|
||||||
fprintf (stderr, " MI 0x%016llX", state->payload_miP);
|
fprintf (stderr, " MI 0x%016llX", state->payload_miP);
|
||||||
if (state->R != 0 && state->payload_algid == 0xAA) fprintf (stderr, " Key 0x%010llX", state->R);
|
|
||||||
fprintf(stderr, " MPTT");
|
fprintf(stderr, " MPTT");
|
||||||
// fprintf (stderr, " %s", KRED);
|
// fprintf (stderr, " %s", KRED);
|
||||||
// fprintf (stderr, "ENC");
|
// fprintf (stderr, "ENC");
|
||||||
@@ -155,7 +153,6 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
|
|||||||
{
|
{
|
||||||
//reset fourv_counter and dropbyte on PTT
|
//reset fourv_counter and dropbyte on PTT
|
||||||
state->fourv_counter[1] = 0;
|
state->fourv_counter[1] = 0;
|
||||||
state->dropR = 256;
|
|
||||||
state->payload_algidR = 0; //zero this out as well
|
state->payload_algidR = 0; //zero this out as well
|
||||||
|
|
||||||
state->dmrburstR = 20;
|
state->dmrburstR = 20;
|
||||||
@@ -179,7 +176,6 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
|
|||||||
fprintf (stderr, "\n ALG ID 0x%02X", state->payload_algidR);
|
fprintf (stderr, "\n ALG ID 0x%02X", state->payload_algidR);
|
||||||
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyidR);
|
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyidR);
|
||||||
fprintf (stderr, " MI 0x%016llX", state->payload_miN);
|
fprintf (stderr, " MI 0x%016llX", state->payload_miN);
|
||||||
if (state->RR != 0 && state->payload_algidR == 0xAA) fprintf (stderr, " Key 0x%010llX", state->RR);
|
|
||||||
fprintf(stderr, " MPTT");
|
fprintf(stderr, " MPTT");
|
||||||
// fprintf (stderr, " %s", KRED);
|
// fprintf (stderr, " %s", KRED);
|
||||||
// fprintf (stderr, "ENC");
|
// fprintf (stderr, "ENC");
|
||||||
@@ -198,7 +194,6 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
|
|||||||
{
|
{
|
||||||
|
|
||||||
state->fourv_counter[0] = 0;
|
state->fourv_counter[0] = 0;
|
||||||
state->dropL = 256;
|
|
||||||
state->dmrburstL = 23;
|
state->dmrburstL = 23;
|
||||||
state->payload_algid = 0;
|
state->payload_algid = 0;
|
||||||
state->payload_keyid = 0;
|
state->payload_keyid = 0;
|
||||||
@@ -222,7 +217,6 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
|
|||||||
{
|
{
|
||||||
|
|
||||||
state->fourv_counter[1] = 0;
|
state->fourv_counter[1] = 0;
|
||||||
state->dropR = 256;
|
|
||||||
state->dmrburstR = 23;
|
state->dmrburstR = 23;
|
||||||
state->payload_algidR = 0;
|
state->payload_algidR = 0;
|
||||||
state->payload_keyidR = 0;
|
state->payload_keyidR = 0;
|
||||||
@@ -251,22 +245,11 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
|
|||||||
|
|
||||||
//blank the call string here -- slot variable is already flipped accordingly for sacch
|
//blank the call string here -- slot variable is already flipped accordingly for sacch
|
||||||
sprintf (state->call_string[slot], "%s", " "); //21 spaces
|
sprintf (state->call_string[slot], "%s", " "); //21 spaces
|
||||||
|
|
||||||
}
|
}
|
||||||
if (opcode == 0x4 && err == 0)
|
if (opcode == 0x4 && err == 0)
|
||||||
{
|
|
||||||
//disable to prevent blinking in ncurses terminal due to OSS preemption shim
|
|
||||||
#ifdef AERO_BUILD
|
|
||||||
if (opts->audio_out_type != 5)
|
|
||||||
{
|
{
|
||||||
if (state->currentslot == 1) state->dmrburstL = 21;
|
if (state->currentslot == 1) state->dmrburstL = 21;
|
||||||
else state->dmrburstR = 21;
|
else state->dmrburstR = 21;
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (state->currentslot == 1) state->dmrburstL = 21;
|
|
||||||
else state->dmrburstR = 21;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fprintf (stderr, " MAC_ACTIVE ");
|
fprintf (stderr, " MAC_ACTIVE ");
|
||||||
fprintf (stderr, "%s", KYEL);
|
fprintf (stderr, "%s", KYEL);
|
||||||
process_MAC_VPDU(opts, state, 1, SMAC);
|
process_MAC_VPDU(opts, state, 1, SMAC);
|
||||||
@@ -276,13 +259,13 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
|
|||||||
{
|
{
|
||||||
if (state->currentslot == 1)
|
if (state->currentslot == 1)
|
||||||
{
|
{
|
||||||
state->dmrburstL = 22;
|
state->dmrburstL = 21;
|
||||||
//close any open MBEout files
|
//close any open MBEout files
|
||||||
if (opts->mbe_out_f != NULL) closeMbeOutFile (opts, state);
|
if (opts->mbe_out_f != NULL) closeMbeOutFile (opts, state);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state->dmrburstR = 22;
|
state->dmrburstR = 21;
|
||||||
//close any open MBEout files
|
//close any open MBEout files
|
||||||
if (opts->mbe_out_fR != NULL) closeMbeOutFileR (opts, state);
|
if (opts->mbe_out_fR != NULL) closeMbeOutFileR (opts, state);
|
||||||
}
|
}
|
||||||
@@ -375,7 +358,6 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156]
|
|||||||
{
|
{
|
||||||
//reset fourv_counter and dropbyte on PTT
|
//reset fourv_counter and dropbyte on PTT
|
||||||
state->fourv_counter[0] = 0;
|
state->fourv_counter[0] = 0;
|
||||||
state->dropL = 256;
|
|
||||||
|
|
||||||
state->dmrburstL = 20;
|
state->dmrburstL = 20;
|
||||||
fprintf (stderr, "\n VCH 0 - ");
|
fprintf (stderr, "\n VCH 0 - ");
|
||||||
@@ -398,7 +380,6 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156]
|
|||||||
fprintf (stderr, "\n ALG ID 0x%02X", state->payload_algid);
|
fprintf (stderr, "\n ALG ID 0x%02X", state->payload_algid);
|
||||||
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyid);
|
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyid);
|
||||||
fprintf (stderr, " MI 0x%016llX", state->payload_miP);
|
fprintf (stderr, " MI 0x%016llX", state->payload_miP);
|
||||||
if (state->R != 0 && state->payload_algid == 0xAA) fprintf (stderr, " Key 0x%010llX", state->R);
|
|
||||||
fprintf(stderr, " MPTT");
|
fprintf(stderr, " MPTT");
|
||||||
// fprintf (stderr, " %s", KRED);
|
// fprintf (stderr, " %s", KRED);
|
||||||
// fprintf (stderr, "ENC");
|
// fprintf (stderr, "ENC");
|
||||||
@@ -410,7 +391,6 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156]
|
|||||||
{
|
{
|
||||||
//reset fourv_counter and dropbyte on PTT
|
//reset fourv_counter and dropbyte on PTT
|
||||||
state->fourv_counter[1] = 0;
|
state->fourv_counter[1] = 0;
|
||||||
state->dropR = 256;
|
|
||||||
|
|
||||||
state->dmrburstR = 20;
|
state->dmrburstR = 20;
|
||||||
fprintf (stderr, "\n VCH 1 - ");
|
fprintf (stderr, "\n VCH 1 - ");
|
||||||
@@ -433,7 +413,6 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156]
|
|||||||
fprintf (stderr, "\n ALG ID 0x%02X", state->payload_algidR);
|
fprintf (stderr, "\n ALG ID 0x%02X", state->payload_algidR);
|
||||||
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyidR);
|
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyidR);
|
||||||
fprintf (stderr, " MI 0x%016llX", state->payload_miN);
|
fprintf (stderr, " MI 0x%016llX", state->payload_miN);
|
||||||
if (state->RR != 0 && state->payload_algidR == 0xAA) fprintf (stderr, " Key 0x%010llX", state->RR);
|
|
||||||
fprintf(stderr, " MPTT");
|
fprintf(stderr, " MPTT");
|
||||||
// fprintf (stderr, " %s", KRED);
|
// fprintf (stderr, " %s", KRED);
|
||||||
// fprintf (stderr, "ENC");
|
// fprintf (stderr, "ENC");
|
||||||
@@ -451,7 +430,6 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156]
|
|||||||
{
|
{
|
||||||
|
|
||||||
state->fourv_counter[0] = 0;
|
state->fourv_counter[0] = 0;
|
||||||
state->dropL = 256;
|
|
||||||
state->dmrburstL = 23;
|
state->dmrburstL = 23;
|
||||||
state->payload_algid = 0; //zero this out as well
|
state->payload_algid = 0; //zero this out as well
|
||||||
state->payload_keyid = 0;
|
state->payload_keyid = 0;
|
||||||
@@ -475,7 +453,6 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156]
|
|||||||
{
|
{
|
||||||
|
|
||||||
state->fourv_counter[1] = 0;
|
state->fourv_counter[1] = 0;
|
||||||
state->dropR = 256;
|
|
||||||
state->dmrburstR = 23;
|
state->dmrburstR = 23;
|
||||||
state->payload_algidR = 0; //zero this out as well
|
state->payload_algidR = 0; //zero this out as well
|
||||||
state->payload_keyidR = 0;
|
state->payload_keyidR = 0;
|
||||||
@@ -524,22 +501,11 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156]
|
|||||||
|
|
||||||
//blank the call string here
|
//blank the call string here
|
||||||
sprintf (state->call_string[slot], "%s", " "); //21 spaces
|
sprintf (state->call_string[slot], "%s", " "); //21 spaces
|
||||||
|
|
||||||
}
|
}
|
||||||
if (opcode == 0x4 && err == 0)
|
if (opcode == 0x4 && err == 0)
|
||||||
{
|
|
||||||
//disable to prevent blinking in ncurses terminal due to OSS preemption shim
|
|
||||||
#ifdef AERO_BUILD
|
|
||||||
if (opts->audio_out_type != 5)
|
|
||||||
{
|
{
|
||||||
if (state->currentslot == 0) state->dmrburstL = 21;
|
if (state->currentslot == 0) state->dmrburstL = 21;
|
||||||
else state->dmrburstR = 21;
|
else state->dmrburstR = 21;
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (state->currentslot == 0) state->dmrburstL = 21;
|
|
||||||
else state->dmrburstR = 21;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fprintf (stderr, " MAC_ACTIVE ");
|
fprintf (stderr, " MAC_ACTIVE ");
|
||||||
fprintf (stderr, "%s", KYEL);
|
fprintf (stderr, "%s", KYEL);
|
||||||
process_MAC_VPDU(opts, state, 0, FMAC);
|
process_MAC_VPDU(opts, state, 0, FMAC);
|
||||||
|
|||||||
@@ -31,9 +31,9 @@
|
|||||||
#include <rtl-sdr.h>
|
#include <rtl-sdr.h>
|
||||||
#include "dsd.h"
|
#include "dsd.h"
|
||||||
|
|
||||||
#define DEFAULT_SAMPLE_RATE 48000
|
//#define DEFAULT_SAMPLE_RATE 48000 //moved to opts->rtl_bandwidth
|
||||||
#define DEFAULT_BUF_LENGTH (1 * 16384)
|
#define DEFAULT_BUF_LENGTH (1 * 16384)
|
||||||
#define MAXIMUM_OVERSAMPLE 16
|
#define MAXIMUM_OVERSAMPLE 16 //16
|
||||||
#define MAXIMUM_BUF_LENGTH (MAXIMUM_OVERSAMPLE * DEFAULT_BUF_LENGTH)
|
#define MAXIMUM_BUF_LENGTH (MAXIMUM_OVERSAMPLE * DEFAULT_BUF_LENGTH)
|
||||||
#define AUTO_GAIN -100
|
#define AUTO_GAIN -100
|
||||||
#define BUFFER_DUMP 4096
|
#define BUFFER_DUMP 4096
|
||||||
@@ -46,8 +46,7 @@ static int ACTUAL_BUF_LENGTH;
|
|||||||
static int *atan_lut = NULL;
|
static int *atan_lut = NULL;
|
||||||
static int atan_lut_size = 131072; /* 512 KB */
|
static int atan_lut_size = 131072; /* 512 KB */
|
||||||
static int atan_lut_coef = 8;
|
static int atan_lut_coef = 8;
|
||||||
|
//new for UDP
|
||||||
//UDP -- keep for compatibility reasons
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
static pthread_t socket_freq;
|
static pthread_t socket_freq;
|
||||||
@@ -58,7 +57,7 @@ int bandwidth_divisor = 48000; //divide bandwidth by this to get multiplier for
|
|||||||
|
|
||||||
short int volume_multiplier;
|
short int volume_multiplier;
|
||||||
short int port;
|
short int port;
|
||||||
|
//
|
||||||
struct dongle_state
|
struct dongle_state
|
||||||
{
|
{
|
||||||
int exit_flag;
|
int exit_flag;
|
||||||
@@ -598,6 +597,7 @@ static void *demod_thread_fn(void *arg)
|
|||||||
|
|
||||||
int nearest_gain(rtlsdr_dev_t *dev, int target_gain)
|
int nearest_gain(rtlsdr_dev_t *dev, int target_gain)
|
||||||
{
|
{
|
||||||
|
//target_gain = 36;
|
||||||
int i, r, err1, err2, count, nearest;
|
int i, r, err1, err2, count, nearest;
|
||||||
int* gains;
|
int* gains;
|
||||||
r = rtlsdr_set_tuner_gain_mode(dev, 1);
|
r = rtlsdr_set_tuner_gain_mode(dev, 1);
|
||||||
@@ -628,9 +628,10 @@ int verbose_set_frequency(rtlsdr_dev_t *dev, uint32_t frequency)
|
|||||||
int r;
|
int r;
|
||||||
r = rtlsdr_set_center_freq(dev, frequency);
|
r = rtlsdr_set_center_freq(dev, frequency);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fprintf (stderr, " (WARNING: Failed to set Center Frequency). \n");
|
fprintf (stderr, "WARNING: Failed to set center freq.\n");
|
||||||
} else {
|
} else {
|
||||||
fprintf (stderr, " (Center Frequency: %u Hz.) \n", frequency);
|
//fprintf (stderr, "Tuned to %u Hz.\n", frequency);
|
||||||
|
fprintf (stderr, "Tuned to center frequency %u Hz.\n", frequency);
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -678,6 +679,7 @@ int verbose_offset_tuning(rtlsdr_dev_t *dev)
|
|||||||
|
|
||||||
int verbose_auto_gain(rtlsdr_dev_t *dev)
|
int verbose_auto_gain(rtlsdr_dev_t *dev)
|
||||||
{
|
{
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
r = rtlsdr_set_tuner_gain_mode(dev, 0);
|
r = rtlsdr_set_tuner_gain_mode(dev, 0);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
@@ -690,6 +692,7 @@ int verbose_auto_gain(rtlsdr_dev_t *dev)
|
|||||||
|
|
||||||
int verbose_gain_set(rtlsdr_dev_t *dev, int gain)
|
int verbose_gain_set(rtlsdr_dev_t *dev, int gain)
|
||||||
{
|
{
|
||||||
|
//gain = 36;
|
||||||
int r;
|
int r;
|
||||||
r = rtlsdr_set_tuner_gain_mode(dev, 1);
|
r = rtlsdr_set_tuner_gain_mode(dev, 1);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@@ -707,6 +710,7 @@ int verbose_gain_set(rtlsdr_dev_t *dev, int gain)
|
|||||||
|
|
||||||
int verbose_ppm_set(rtlsdr_dev_t *dev, int ppm_error)
|
int verbose_ppm_set(rtlsdr_dev_t *dev, int ppm_error)
|
||||||
{
|
{
|
||||||
|
//ppm_error = -2; //fix this opt arg to accept negative float values, i.e. float or double??
|
||||||
int r;
|
int r;
|
||||||
if (ppm_error == 0) {
|
if (ppm_error == 0) {
|
||||||
return 0;}
|
return 0;}
|
||||||
@@ -728,23 +732,25 @@ int verbose_reset_buffer(rtlsdr_dev_t *dev)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void optimal_settings(int freq, int rate)
|
//static void optimal_settings(struct fm_state *fm, int freq, int hopping)
|
||||||
|
static void optimal_settings(int freq, int rate) //
|
||||||
{
|
{
|
||||||
// giant ball of hacks
|
// giant ball of hacks
|
||||||
// seems unable to do a single pass, 2:1
|
// seems unable to do a single pass, 2:1
|
||||||
|
//int r, capture_freq, capture_rate;
|
||||||
int capture_freq, capture_rate;
|
int capture_freq, capture_rate;
|
||||||
struct dongle_state *d = &dongle;
|
struct dongle_state *d = &dongle;
|
||||||
struct demod_state *dm = &demod;
|
struct demod_state *dm = &demod;
|
||||||
struct controller_state *cs = &controller;
|
struct controller_state *cs = &controller;
|
||||||
dm->downsample = (1000000 / dm->rate_in) + 1; //dm->rate_in is the rtl_bandwidth value
|
dm->downsample = (1000000 / dm->rate_in) + 1;
|
||||||
if (dm->downsample_passes) {
|
if (dm->downsample_passes) {
|
||||||
dm->downsample_passes = (int)log2(dm->downsample) + 1;
|
dm->downsample_passes = (int)log2(dm->downsample) + 1;
|
||||||
dm->downsample = 1 << dm->downsample_passes;
|
dm->downsample = 1 << dm->downsample_passes;
|
||||||
}
|
}
|
||||||
capture_freq = freq;
|
capture_freq = freq;
|
||||||
capture_rate = dm->downsample * dm->rate_in; //
|
capture_rate = dm->downsample * dm->rate_in;
|
||||||
if (!d->offset_tuning) {
|
if (!d->offset_tuning) {
|
||||||
capture_freq = freq + capture_rate/4;} //
|
capture_freq = freq + capture_rate/4;}
|
||||||
capture_freq += cs->edge * dm->rate_in / 2;
|
capture_freq += cs->edge * dm->rate_in / 2;
|
||||||
dm->output_scale = (1<<15) / (128 * dm->downsample);
|
dm->output_scale = (1<<15) / (128 * dm->downsample);
|
||||||
if (dm->output_scale < 1) {
|
if (dm->output_scale < 1) {
|
||||||
@@ -753,7 +759,6 @@ static void optimal_settings(int freq, int rate)
|
|||||||
dm->output_scale = 1;}
|
dm->output_scale = 1;}
|
||||||
d->freq = (uint32_t)capture_freq;
|
d->freq = (uint32_t)capture_freq;
|
||||||
d->rate = (uint32_t)capture_rate;
|
d->rate = (uint32_t)capture_rate;
|
||||||
// fprintf (stderr, "Capture Frequency: %i Rate: %i \n", capture_freq, capture_rate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *controller_thread_fn(void *arg)
|
static void *controller_thread_fn(void *arg)
|
||||||
@@ -785,6 +790,7 @@ static void *controller_thread_fn(void *arg)
|
|||||||
/* Set the sample rate */
|
/* Set the sample rate */
|
||||||
verbose_set_sample_rate(dongle.dev, dongle.rate);
|
verbose_set_sample_rate(dongle.dev, dongle.rate);
|
||||||
fprintf (stderr, "Output at %u Hz.\n", demod.rate_in/demod.post_downsample);
|
fprintf (stderr, "Output at %u Hz.\n", demod.rate_in/demod.post_downsample);
|
||||||
|
fprintf (stderr, "Press CTRL + C to close.\n");
|
||||||
|
|
||||||
while (!exitflag) {
|
while (!exitflag) {
|
||||||
safe_cond_wait(&s->hop, &s->hop_m);
|
safe_cond_wait(&s->hop, &s->hop_m);
|
||||||
@@ -801,16 +807,20 @@ static void *controller_thread_fn(void *arg)
|
|||||||
|
|
||||||
void dongle_init(struct dongle_state *s)
|
void dongle_init(struct dongle_state *s)
|
||||||
{
|
{
|
||||||
|
//s->rate = DEFAULT_SAMPLE_RATE;
|
||||||
s->rate = rtl_bandwidth;
|
s->rate = rtl_bandwidth;
|
||||||
s->gain = AUTO_GAIN; // tenths of a dB
|
s->gain = AUTO_GAIN; // tenths of a dB
|
||||||
s->mute = 0;
|
s->mute = 0;
|
||||||
s->direct_sampling = 0;
|
s->direct_sampling = 0;
|
||||||
s->offset_tuning = 0; //E4000 tuners only
|
s->offset_tuning = 0; //
|
||||||
s->demod_target = &demod;
|
s->demod_target = &demod;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void demod_init(struct demod_state *s)
|
void demod_init(struct demod_state *s)
|
||||||
{
|
{
|
||||||
|
//s->rate_in = DEFAULT_SAMPLE_RATE;
|
||||||
|
//s->rate_out = DEFAULT_SAMPLE_RATE;
|
||||||
s->rate_in = rtl_bandwidth;
|
s->rate_in = rtl_bandwidth;
|
||||||
s->rate_out = rtl_bandwidth;
|
s->rate_out = rtl_bandwidth;
|
||||||
s->squelch_level = 0;
|
s->squelch_level = 0;
|
||||||
@@ -820,16 +830,16 @@ void demod_init(struct demod_state *s)
|
|||||||
s->downsample_passes = 0;
|
s->downsample_passes = 0;
|
||||||
s->comp_fir_size = 0;
|
s->comp_fir_size = 0;
|
||||||
s->prev_index = 0;
|
s->prev_index = 0;
|
||||||
s->post_downsample = 1; //1 -- once this works, default = 4 -- doesn't work on the official rtl-sdr source code either
|
s->post_downsample = 1; // once this works, default = 4
|
||||||
s->custom_atan = 0;
|
s->custom_atan = 0;
|
||||||
s->deemph = 0;
|
s->deemph = 0;
|
||||||
s->rate_out2 = rtl_bandwidth; // -1 flag for disabled -- this enables low_pass_real, seems to work okay
|
s->rate_out2 = -1; // flag for disabled
|
||||||
s->mode_demod = &fm_demod;
|
s->mode_demod = &fm_demod;
|
||||||
s->pre_j = s->pre_r = s->now_r = s->now_j = 0;
|
s->pre_j = s->pre_r = s->now_r = s->now_j = 0;
|
||||||
s->prev_lpr_index = 0;
|
s->prev_lpr_index = 0;
|
||||||
s->deemph_a = 0;
|
s->deemph_a = 0;
|
||||||
s->now_lpr = 0;
|
s->now_lpr = 0;
|
||||||
s->dc_block = 1; //enabling by default, but offset tuning is also enabled, so center spike shouldn't be an issue
|
s->dc_block = 0;
|
||||||
s->dc_avg = 0;
|
s->dc_avg = 0;
|
||||||
pthread_rwlock_init(&s->rw, NULL);
|
pthread_rwlock_init(&s->rw, NULL);
|
||||||
pthread_cond_init(&s->ready, NULL);
|
pthread_cond_init(&s->ready, NULL);
|
||||||
@@ -846,6 +856,7 @@ void demod_cleanup(struct demod_state *s)
|
|||||||
|
|
||||||
void output_init(struct output_state *s)
|
void output_init(struct output_state *s)
|
||||||
{
|
{
|
||||||
|
//s->rate = DEFAULT_SAMPLE_RATE;
|
||||||
s->rate = rtl_bandwidth;
|
s->rate = rtl_bandwidth;
|
||||||
pthread_rwlock_init(&s->rw, NULL);
|
pthread_rwlock_init(&s->rw, NULL);
|
||||||
pthread_cond_init(&s->ready, NULL);
|
pthread_cond_init(&s->ready, NULL);
|
||||||
@@ -893,8 +904,7 @@ void sanity_checks(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
//UDP remote all below HERE
|
||||||
//UDP remote stuff
|
|
||||||
static unsigned int chars_to_int(unsigned char* buf) {
|
static unsigned int chars_to_int(unsigned char* buf) {
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
@@ -908,7 +918,9 @@ static unsigned int chars_to_int(unsigned char* buf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void *socket_thread_fn(void *arg) {
|
static void *socket_thread_fn(void *arg) {
|
||||||
|
//struct fm_state *fm = arg;
|
||||||
struct demod_state *d = static_cast<demod_state*>(arg);
|
struct demod_state *d = static_cast<demod_state*>(arg);
|
||||||
|
//int port = 6020;
|
||||||
int r, n;
|
int r, n;
|
||||||
int sockfd, newsockfd, portno;
|
int sockfd, newsockfd, portno;
|
||||||
socklen_t clilen;
|
socklen_t clilen;
|
||||||
@@ -940,34 +952,114 @@ static void *socket_thread_fn(void *arg) {
|
|||||||
while((n = read(sockfd,buffer,5)) != 0) {
|
while((n = read(sockfd,buffer,5)) != 0) {
|
||||||
if(buffer[0] == 0) {
|
if(buffer[0] == 0) {
|
||||||
new_freq = chars_to_int(buffer);
|
new_freq = chars_to_int(buffer);
|
||||||
dongle.freq = new_freq;
|
dongle.freq = new_freq; //
|
||||||
|
//opts->rtlsdr_center_freq = new_freq; //or dongle.freq, this should update the freq displayed in ncurses terminal hopefully and not do anything naughty
|
||||||
|
|
||||||
optimal_settings(new_freq, demod.rate_in);
|
optimal_settings(new_freq, demod.rate_in);
|
||||||
rtlsdr_set_center_freq(dongle.dev, dongle.freq);
|
rtlsdr_set_center_freq(dongle.dev, dongle.freq);
|
||||||
|
//verbose_set_frequency (dongle.dev, new_freq);
|
||||||
|
//fprintf (stderr, "Tuning to: %d [Hz] (central freq: %d [Hz])\n", new_freq, new_freq + freq_offset);
|
||||||
fprintf (stderr, "\nTuning to: %d [Hz] \n", new_freq);
|
fprintf (stderr, "\nTuning to: %d [Hz] \n", new_freq);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
if(buffer[0] == 1) {
|
||||||
|
// change demod type
|
||||||
|
int type = chars_to_int(buffer);
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case 0:
|
||||||
|
fprintf (stderr, "Changing demod type to FM\n");
|
||||||
|
fm->mode_demod = &fm_demod;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
fprintf (stderr, "Changing demod type to AM\n");
|
||||||
|
fm->mode_demod = &am_demod;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
fprintf (stderr, "Changing demod type to USB\n");
|
||||||
|
fm->mode_demod = &usb_demod;
|
||||||
|
fm->custom_atan = 1;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
fprintf (stderr, "Changing demod type to LSB\n");
|
||||||
|
fm->mode_demod = &lsb_demod;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf (stderr, "Unknown demod type %d\n", type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//SQUELCH HERE
|
||||||
|
|
||||||
|
if (buffer[0] == 2) {
|
||||||
|
new_squelch = chars_to_int(buffer);
|
||||||
|
demod.squelch_level = new_squelch; //demod, or d*? or d->
|
||||||
|
//full_demod(d);
|
||||||
|
//new_freq = 850000000;
|
||||||
|
//dongle.freq = new_freq;
|
||||||
|
//optimal_settings(new_freq, demod.rate_in); //hacky way to 'squelch', just setting it to a dead freq instead
|
||||||
|
//rtlsdr_set_center_freq(dongle.dev, dongle.freq);
|
||||||
|
fprintf (stderr, "Changing squelch to %d \n", new_squelch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (buffer[0] == 3) {
|
||||||
|
new_gain = chars_to_int(buffer);
|
||||||
|
if (new_gain == AUTO_GAIN) {
|
||||||
|
r = rtlsdr_set_tuner_gain_mode(dev, 0);
|
||||||
|
} else {
|
||||||
|
r = rtlsdr_set_tuner_gain_mode(dev, 1);
|
||||||
|
new_gain = nearest_gain(new_gain);
|
||||||
|
r = rtlsdr_set_tuner_gain(dev, new_gain);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r != 0) {
|
||||||
|
fprintf (stderr, "WARNING: Failed to set tuner gain.\n");
|
||||||
|
} else if (new_gain == AUTO_GAIN) {
|
||||||
|
fprintf (stderr, "Tuner gain set to automatic.\n");
|
||||||
|
} else {
|
||||||
|
fprintf (stderr, "Tuner gain set to %0.2f dB.\n", new_gain/10.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
if (buffer[0] == 8) {
|
||||||
|
agc_mode = chars_to_int(buffer);
|
||||||
|
if (agc_mode == 0 || agc_mode == 1) {
|
||||||
|
fprintf (stderr, "Setting AGC to %d\n", agc_mode);
|
||||||
|
rtlsdr_set_agc_mode(dev, agc_mode);
|
||||||
|
} else {
|
||||||
|
fprintf (stderr, "Failed to set AGC to %d\n", agc_mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//UDP stuff end
|
//UDP Control all above HERE
|
||||||
|
|
||||||
void rtlsdr_sighandler()
|
void rtlsdr_sighandler()
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Signal caught, exiting!\n");
|
//fprintf (stderr, "Signal caught, exiting!\n");
|
||||||
|
//fprintf (stderr, "Press CTRL + C again to close. Thanks. \n"); //Kindly remind user to double tap CTRL + C
|
||||||
|
|
||||||
rtlsdr_cancel_async(dongle.dev);
|
rtlsdr_cancel_async(dongle.dev);
|
||||||
|
//cleanup_rtlsdr_stream(); //thank the wraith for this one...if it works...didn't work
|
||||||
|
//_Exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void open_rtlsdr_stream(dsd_opts *opts)
|
void open_rtlsdr_stream(dsd_opts *opts)
|
||||||
{
|
{
|
||||||
struct sigaction sigact;
|
struct sigaction sigact;
|
||||||
int r;
|
int r;
|
||||||
rtl_bandwidth = opts->rtl_bandwidth * 1000; //reverted back to straight value
|
rtl_bandwidth = opts->rtl_bandwidth * 1000; //multiple by 1000 to get rate
|
||||||
|
//rtl_bandwidth = 48000;
|
||||||
bandwidth_multiplier = (bandwidth_divisor / rtl_bandwidth);
|
bandwidth_multiplier = (bandwidth_divisor / rtl_bandwidth);
|
||||||
|
//bandwidth_multiplier = 1;
|
||||||
//this needs to be initted first, then we set the parameters
|
|
||||||
dongle_init(&dongle);
|
dongle_init(&dongle);
|
||||||
demod_init(&demod);
|
demod_init(&demod);
|
||||||
output_init(&output);
|
output_init(&output);
|
||||||
@@ -978,23 +1070,29 @@ void open_rtlsdr_stream(dsd_opts *opts)
|
|||||||
controller.freq_len++;
|
controller.freq_len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts->rtlsdr_ppm_error != 0) {
|
if (opts->rtlsdr_ppm_error > 0 || opts->rtlsdr_ppm_error < 0) { //this way will adjust PPM based on negative values as well
|
||||||
dongle.ppm_error = opts->rtlsdr_ppm_error;
|
dongle.ppm_error = opts->rtlsdr_ppm_error;
|
||||||
fprintf (stderr, "Setting RTL PPM Error Set to %d\n", opts->rtlsdr_ppm_error);
|
fprintf (stderr, "Setting RTL PPM Error Set to %d\n", opts->rtlsdr_ppm_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opts->audio_in_type == 3) {
|
||||||
dongle.dev_index = opts->rtl_dev_index;
|
dongle.dev_index = opts->rtl_dev_index;
|
||||||
// demod.squelch_level = opts->rtl_squelch_level; //no longer used here, used in framesync vc rms value under select conditions
|
//rtl_bandwidth = opts->rtl_bandwidth * 1000; //multiple by 1000 to get rate
|
||||||
fprintf (stderr, "Setting RTL Bandwidth to %d Hz\n", rtl_bandwidth);
|
//rtl_bandwidth = 48000;
|
||||||
// fprintf (stderr, "Setting RTL Sample Multiplier to %d\n", bandwidth_multiplier);
|
//bandwidth_multiplier = rtl_bandwidth / bandwidth_divisor; //find multiple with no remainder if oddball number entered
|
||||||
fprintf (stderr, "Setting RTL RMS Squelch Level to %d\n", opts->rtl_squelch_level);
|
//bandwidth_multiplier = 1;
|
||||||
if (opts->rtl_udp_port != 0) port = opts->rtl_udp_port; //set this here, only open socket thread if set
|
demod.squelch_level = opts->rtl_squelch_level; //adding user definable squelch level to prevent false positives on account of noise in NXDN etc
|
||||||
|
fprintf (stderr, "Setting RTL VFO Bandwidth to %d Hz\n", rtl_bandwidth);
|
||||||
|
fprintf (stderr, "Setting RTL Sample Multiplier to %d\n", bandwidth_multiplier);
|
||||||
|
fprintf (stderr, "Setting RTL Squelch Level to %d\n", demod.squelch_level);
|
||||||
|
port = opts->rtl_udp_port;
|
||||||
|
}
|
||||||
|
|
||||||
if (opts->rtl_gain_value > 0) {
|
if (opts->rtl_gain_value > 0) {
|
||||||
dongle.gain = opts->rtl_gain_value * 10; //multiple by ten to make it consitent with the way rtl_fm works
|
dongle.gain = opts->rtl_gain_value * 10; //multiple by ten to make it consitent with the way rtl_fm really works
|
||||||
}
|
}
|
||||||
volume_multiplier = opts->rtl_volume_multiplier;
|
volume_multiplier = opts->rtl_volume_multiplier;
|
||||||
// fprintf (stderr, "Setting RTL Volume Multiplier to %d\n", volume_multiplier);
|
fprintf (stderr, "Setting RTL Volume Multiplier to %d\n", volume_multiplier);
|
||||||
|
|
||||||
/* quadruple sample_rate to limit to Δθ to ±π/2 */
|
/* quadruple sample_rate to limit to Δθ to ±π/2 */
|
||||||
demod.rate_in *= demod.post_downsample;
|
demod.rate_in *= demod.post_downsample;
|
||||||
|
|
||||||
@@ -1005,16 +1103,24 @@ void open_rtlsdr_stream(dsd_opts *opts)
|
|||||||
if (controller.freq_len > 1) demod.terminate_on_squelch = 0;
|
if (controller.freq_len > 1) demod.terminate_on_squelch = 0;
|
||||||
|
|
||||||
ACTUAL_BUF_LENGTH = lcm_post[demod.post_downsample] * DEFAULT_BUF_LENGTH;
|
ACTUAL_BUF_LENGTH = lcm_post[demod.post_downsample] * DEFAULT_BUF_LENGTH;
|
||||||
|
|
||||||
r = rtlsdr_open(&dongle.dev, (uint32_t)dongle.dev_index);
|
r = rtlsdr_open(&dongle.dev, (uint32_t)dongle.dev_index);
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Failed to open rtlsdr device %d.\n", dongle.dev_index);
|
fprintf (stderr, "Failed to open rtlsdr device %d.\n", dongle.dev_index);
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
fprintf (stderr, "Using RTLSDR Device Index: %d. \n", dongle.dev_index);
|
fprintf (stderr, "Using RTLSDR Device Index: %d. \n", dongle.dev_index); //Kindly tell us which device we are using
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sigact.sa_handler = sighandler;
|
||||||
|
// sigemptyset(&sigact.sa_mask);
|
||||||
|
// sigact.sa_flags = 0;
|
||||||
|
// sigaction(SIGINT, &sigact, NULL);
|
||||||
|
// sigaction(SIGTERM, &sigact, NULL);
|
||||||
|
// sigaction(SIGQUIT, &sigact, NULL);
|
||||||
|
// sigaction(SIGPIPE, &sigact, NULL);
|
||||||
|
|
||||||
if (demod.deemph) {
|
if (demod.deemph) {
|
||||||
demod.deemph_a = (int)round(1.0/((1.0-exp(-1.0/(demod.rate_out * 75e-6)))));
|
demod.deemph_a = (int)round(1.0/((1.0-exp(-1.0/(demod.rate_out * 75e-6)))));
|
||||||
}
|
}
|
||||||
@@ -1022,11 +1128,9 @@ void open_rtlsdr_stream(dsd_opts *opts)
|
|||||||
/* Set the tuner gain */
|
/* Set the tuner gain */
|
||||||
if (dongle.gain == AUTO_GAIN) {
|
if (dongle.gain == AUTO_GAIN) {
|
||||||
verbose_auto_gain(dongle.dev);
|
verbose_auto_gain(dongle.dev);
|
||||||
fprintf (stderr, "Setting RTL Autogain. \n");
|
|
||||||
} else {
|
} else {
|
||||||
dongle.gain = nearest_gain(dongle.dev, dongle.gain);
|
dongle.gain = nearest_gain(dongle.dev, dongle.gain);
|
||||||
verbose_gain_set(dongle.dev, dongle.gain);
|
verbose_gain_set(dongle.dev, dongle.gain);
|
||||||
// fprintf (stderr, "Setting RTL Nearest Gain to %d. \n", dongle.gain); //seems to be working now
|
|
||||||
}
|
}
|
||||||
|
|
||||||
verbose_ppm_set(dongle.dev, dongle.ppm_error);
|
verbose_ppm_set(dongle.dev, dongle.ppm_error);
|
||||||
@@ -1038,8 +1142,7 @@ void open_rtlsdr_stream(dsd_opts *opts)
|
|||||||
usleep(100000);
|
usleep(100000);
|
||||||
pthread_create(&demod.thread, NULL, demod_thread_fn, (void*)(&demod));
|
pthread_create(&demod.thread, NULL, demod_thread_fn, (void*)(&demod));
|
||||||
pthread_create(&dongle.thread, NULL, dongle_thread_fn, (void*)(&dongle));
|
pthread_create(&dongle.thread, NULL, dongle_thread_fn, (void*)(&dongle));
|
||||||
//only create socket thread IF user specified (for legacy uses), else don't use it
|
pthread_create(&socket_freq, NULL, socket_thread_fn, (void *)(&controller));
|
||||||
if (port != 0) pthread_create(&socket_freq, NULL, socket_thread_fn, (void *)(&controller));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup_rtlsdr_stream()
|
void cleanup_rtlsdr_stream()
|
||||||
@@ -1052,6 +1155,8 @@ void cleanup_rtlsdr_stream()
|
|||||||
safe_cond_signal(&output.ready, &output.ready_m);
|
safe_cond_signal(&output.ready, &output.ready_m);
|
||||||
safe_cond_signal(&controller.hop, &controller.hop_m);
|
safe_cond_signal(&controller.hop, &controller.hop_m);
|
||||||
pthread_join(controller.thread, NULL);
|
pthread_join(controller.thread, NULL);
|
||||||
|
//add socket thread
|
||||||
|
//pthread_join(socket_freq, NULL);
|
||||||
|
|
||||||
//dongle_cleanup(&dongle);
|
//dongle_cleanup(&dongle);
|
||||||
demod_cleanup(&demod);
|
demod_cleanup(&demod);
|
||||||
@@ -1059,69 +1164,32 @@ void cleanup_rtlsdr_stream()
|
|||||||
controller_cleanup(&controller);
|
controller_cleanup(&controller);
|
||||||
|
|
||||||
rtlsdr_close(dongle.dev);
|
rtlsdr_close(dongle.dev);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//original for safe keeping
|
//void get_rtlsdr_sample(int16_t *sample)
|
||||||
// void get_rtlsdr_sample(int16_t *sample, dsd_opts * opts, dsd_state * state)
|
|
||||||
// {
|
|
||||||
// if (output.queue.empty())
|
|
||||||
// {
|
|
||||||
// safe_cond_wait(&output.ready, &output.ready_m);
|
|
||||||
// }
|
|
||||||
// pthread_rwlock_wrlock(&output.rw);
|
|
||||||
// *sample = output.queue.front() * volume_multiplier;
|
|
||||||
// output.queue.pop();
|
|
||||||
// pthread_rwlock_unlock(&output.rw);
|
|
||||||
// }
|
|
||||||
|
|
||||||
//find way to modify this function to allow hopping (tuning) while squelched and send 0 sample?
|
|
||||||
void get_rtlsdr_sample(int16_t *sample, dsd_opts * opts, dsd_state * state)
|
void get_rtlsdr_sample(int16_t *sample, dsd_opts * opts, dsd_state * state)
|
||||||
{
|
{
|
||||||
if (output.queue.empty())
|
if (output.queue.empty())
|
||||||
{
|
{
|
||||||
safe_cond_wait(&output.ready, &output.ready_m);
|
if (opts->use_ncurses_terminal == 1)
|
||||||
|
{
|
||||||
|
//ncursesPrinter(opts, state);
|
||||||
|
//printw ("\n\n\n HELP I'M LOCKED!\n");
|
||||||
}
|
}
|
||||||
|
safe_cond_wait(&output.ready, &output.ready_m);
|
||||||
|
//goto END;
|
||||||
|
}
|
||||||
|
|
||||||
pthread_rwlock_wrlock(&output.rw);
|
pthread_rwlock_wrlock(&output.rw);
|
||||||
*sample = output.queue.front() * volume_multiplier;
|
//*sample = output.queue.front();
|
||||||
|
|
||||||
|
*sample = output.queue.front() * volume_multiplier; //try multiplying by numbers here for 'gain'
|
||||||
output.queue.pop();
|
output.queue.pop();
|
||||||
pthread_rwlock_unlock(&output.rw);
|
pthread_rwlock_unlock(&output.rw);
|
||||||
}
|
// END:
|
||||||
|
// if (1 == 2)
|
||||||
//function may lag since it isn't running as its own thread
|
// {
|
||||||
void rtl_dev_tune(dsd_opts * opts, long int frequency)
|
// fprintf (stderr, "This is a dumb thing to fix");
|
||||||
{
|
// }
|
||||||
int r;
|
|
||||||
if (opts->payload == 1)
|
|
||||||
fprintf (stderr, "\nTuning to %lu Hz.", frequency);
|
|
||||||
dongle.freq = opts->rtlsdr_center_freq = frequency;
|
|
||||||
optimal_settings(dongle.freq, demod.rate_in);
|
|
||||||
if (opts->payload == 1)
|
|
||||||
fprintf (stderr, " (Center Frequency: %u Hz.) \n", dongle.freq);
|
|
||||||
r = rtlsdr_set_center_freq(dongle.dev, dongle.freq);
|
|
||||||
if (r < 0)
|
|
||||||
fprintf (stderr, " (WARNING: Failed to set Center Frequency %u). \n", dongle.freq);
|
|
||||||
|
|
||||||
pthread_rwlock_wrlock(&output.rw); //prevent possible segfault when cleaning the queue
|
|
||||||
rtl_clean_queue();
|
|
||||||
pthread_rwlock_unlock(&output.rw); //resume
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//return RMS value (root means square) power level -- used as soft squelch inside of framesync
|
|
||||||
int rtl_return_rms()
|
|
||||||
{
|
|
||||||
int sr = 0;
|
|
||||||
sr = rms(demod.lowpassed, demod.lp_len, 1);
|
|
||||||
// 'Fix' potential negative value overflow from the rms function -- Observed in Windows builds
|
|
||||||
sr = abs(sr);
|
|
||||||
if (sr > 9999) sr = 9999;
|
|
||||||
return (sr);
|
|
||||||
}
|
|
||||||
|
|
||||||
//simple function to clear the rtl sample queue when tuning and during other events (ncurses menu open/close)
|
|
||||||
void rtl_clean_queue()
|
|
||||||
{
|
|
||||||
//insert method to clear the entire queue to prevent sample 'lag'
|
|
||||||
std::queue<int16_t> empty; //create an empty queue
|
|
||||||
std::swap( output.queue, empty ); //swap in empty queue to effectively zero out current queue
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user