Compare commits
351 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7f51f794fd | ||
|
f76bfcb8f4 | ||
|
88e52f362a | ||
|
8a4b8e3731 | ||
|
3966480fea | ||
|
115922c385 | ||
|
32dbf0f325 | ||
|
03bc7e3d08 | ||
|
49f2527fcd | ||
|
2dbc61a92e | ||
|
4dade2a709 | ||
|
7c738b161c | ||
|
4afde2a399 | ||
|
7f5f59e510 | ||
|
61608067f4 | ||
|
deac6017e3 | ||
|
d67798da56 | ||
|
ca5898bc57 | ||
|
694c3a334d | ||
|
99fca7c09e | ||
|
d2470a5379 | ||
|
638898d3a4 | ||
|
e16772c154 | ||
|
914a3af96f | ||
|
e5fc6fbd81 | ||
|
83bff3e847 | ||
|
b340b92a04 | ||
|
89a25c8a7f | ||
|
0e93251349 | ||
|
65e6f89214 | ||
|
e287ac60d5 | ||
|
5985a0d2e0 | ||
|
9864650d9a | ||
|
0a3a455937 | ||
|
e564ac2f39 | ||
|
7948561cdc | ||
|
43e1e9c095 | ||
|
811f320536 | ||
|
290ba12c93 | ||
|
6dba1f6813 | ||
|
05f88acf02 | ||
|
3e0375f6d5 | ||
|
d441dad344 | ||
|
55de2c724f | ||
|
cca47bbb50 | ||
|
8a3a246888 | ||
|
b7619e1c57 | ||
|
9b714aed45 | ||
|
c791067ea8 | ||
|
bc235856a8 | ||
|
ff3b3f4ef5 | ||
|
29f7d534e5 | ||
|
395e9e0821 | ||
|
1e5257b851 | ||
|
d26aa35969 | ||
|
24b1807a07 | ||
|
6c9dd36f8b | ||
|
1aeac6e268 | ||
|
d834c363b3 | ||
|
d988aab950 | ||
|
c50097e420 | ||
|
1baca797f6 | ||
|
6a9bba0656 | ||
|
aa28bc700d | ||
|
96cc7a550f | ||
|
4678abf091 | ||
|
276083d3e8 | ||
|
13ecf0124e | ||
|
db9ccd9ca8 | ||
|
1304926162 | ||
|
2aa2ad27da | ||
|
1975c1748c | ||
|
f882747e97 | ||
|
f1aab5c97e | ||
|
d453e164fa | ||
|
3b22d436ee | ||
|
4c1f99a7d2 | ||
|
cd38c0d6a3 | ||
|
91b83cff3b | ||
|
c333fb505c | ||
|
b897b2176d | ||
|
f7b9727ef9 | ||
|
76b4623375 | ||
|
28077752a9 | ||
|
3d3195489a | ||
|
89d7fe736f | ||
|
2f47258605 | ||
|
de4147b853 | ||
|
002f5e8af3 | ||
|
ce007419e8 | ||
|
fc82606e6e | ||
|
ab54ac7a63 | ||
|
379c802d39 | ||
|
e6eb23d8a0 | ||
|
0111ce247b | ||
|
c108f5be40 | ||
|
1074bd0105 | ||
|
a5d1f48580 | ||
|
1c8d7bdaf1 | ||
|
77b2b815b8 | ||
|
2e1411311b | ||
|
c8fed979d4 | ||
|
60869b74f9 | ||
|
88b2f29894 | ||
|
fa6a801411 | ||
|
1c6b167527 | ||
|
bafcb75313 | ||
|
e33d6e9b64 | ||
|
7e6342624c | ||
|
90ddb54371 | ||
|
356e5e42be | ||
|
c7e2a78903 | ||
|
8ff41d60fd | ||
|
5f74620406 | ||
|
7a97bbfea0 | ||
|
81bae39a22 | ||
|
596544ade7 | ||
|
fed8856e1e | ||
|
825c1d0759 | ||
|
190b8c6aeb | ||
|
0c502c59f8 | ||
|
ad46defda9 | ||
|
42a674037f | ||
|
3c9931bc59 | ||
|
cb5d921e68 | ||
|
5ae5641f99 | ||
|
b3f83c33fa | ||
|
c40da37faf | ||
|
ba673bf3a2 | ||
|
082a07d39b | ||
|
d24c552d24 | ||
|
31ab1480d0 | ||
|
08537b5a5a | ||
|
4627be2e50 | ||
|
7f20ca0a6d | ||
|
310df0046c | ||
|
3c5ce69846 | ||
|
b653117360 | ||
|
a2f8428352 | ||
|
e6b3e50fd2 | ||
|
504684c609 | ||
|
fc64424377 | ||
|
89e392e91f | ||
|
23279d2f46 | ||
|
d7863b25c6 | ||
|
6ded8f079b | ||
|
d524bf2057 | ||
|
6df8b94637 | ||
|
19d8a1da0f | ||
|
2ea5ef220b | ||
|
9ea7ade57f | ||
|
c9c9febe41 | ||
|
4519e512c6 | ||
|
2248b42a06 | ||
|
7af58538b6 | ||
|
9f61152d37 | ||
|
52d59b8609 | ||
|
6b30f17361 | ||
|
2f280ec06a | ||
|
3c7fd19f59 | ||
|
e38e2e773f | ||
|
f841eecab9 | ||
|
b2a1dc3569 | ||
|
9c64424cec | ||
|
a3692309c0 | ||
|
83b36c6aab | ||
|
c62a25f40a | ||
|
86ac92e63e | ||
|
aa65bd5b39 | ||
|
4203e72e12 | ||
|
73f345792d | ||
|
5eeae7c231 | ||
|
67dec1dd83 | ||
|
4e3545cf0e | ||
|
3f7e1193fa | ||
|
c2652d3ee5 | ||
|
51b540cf72 | ||
|
70d090101a | ||
|
d3584f6af2 | ||
|
c5efd73f6b | ||
|
4510f40729 | ||
|
56bd20d59b | ||
|
a4269dcd78 | ||
|
9f661aee30 | ||
|
35088962fe | ||
|
930e4d7e50 | ||
|
f4e2d10055 | ||
|
68126592ad | ||
|
5ea872fe30 | ||
|
7dec953ade | ||
|
1462890a77 | ||
|
d696dd66a0 | ||
|
107d1ee6c8 | ||
|
4a8adc4a42 | ||
|
a9385cb91c | ||
|
ec0ffa005a | ||
|
405073d198 | ||
|
88c5554970 | ||
|
c4e57a1696 | ||
|
99011d8bbc | ||
|
d86dbbade9 | ||
|
87a3d9dea7 | ||
|
c0b8620baa | ||
|
4b714dfaa5 | ||
|
ec4d14be3f | ||
|
1f0a8e3690 | ||
|
5ba42f1866 | ||
|
3c3e5cf3df | ||
|
943a1fb56c | ||
|
460ebfbeb2 | ||
|
a91fa3b760 | ||
|
d0cae88ba8 | ||
|
30a0198862 | ||
|
7b7f9e2c06 | ||
|
a12d664055 | ||
|
5cc7b3ac33 | ||
|
4465e1e8b8 | ||
|
4da9a34c87 | ||
|
7bc6210b64 | ||
|
f8a991e4a3 | ||
|
6dcc342c10 | ||
|
7c7a7d7c1e | ||
|
0a94970a70 | ||
|
875f16f12a | ||
|
c4733a3645 | ||
|
585841e787 | ||
|
bba9d0b421 | ||
|
600e338bab | ||
|
f03499a9a3 | ||
|
73533231a5 | ||
|
d52179dbe2 | ||
|
a7c67a8540 | ||
|
cb4651af0b | ||
|
ba6a3cc665 | ||
|
9f95769608 | ||
|
ca76d5fbae | ||
|
d7547e2d25 | ||
|
d53aa60112 | ||
|
8284388862 | ||
|
d69ca4d1f6 | ||
|
43077fc549 | ||
|
1ca63912b6 | ||
|
86f4a5bc69 | ||
|
b96b4b60b4 | ||
|
3da2074d9d | ||
|
ae5dc866c7 | ||
|
bf837e0e02 | ||
|
b6816fe886 | ||
|
f09a1259e4 | ||
|
5bffac3eaa | ||
|
197ac366e2 | ||
|
14063a80e9 | ||
|
8ed7972dce | ||
|
2abe88368b | ||
|
06678a5978 | ||
|
29bac274d6 | ||
|
eceedd5db8 | ||
|
98481a96e9 | ||
|
28faddea1d | ||
|
a9f25b3642 | ||
|
1235f71388 | ||
|
e277e4fc1f | ||
|
fcc1bca5a0 | ||
|
b8fc311997 | ||
|
9161fc1c05 | ||
|
fd168e881a | ||
|
df6cefbd69 | ||
|
23a8fdeb86 | ||
|
feabcef336 | ||
|
b122d40bce | ||
|
8346cc4988 | ||
|
067324edd9 | ||
|
c72a72b3f8 | ||
|
763438c7e5 | ||
|
00df25ff63 | ||
|
8f030d9ea5 | ||
|
bd8853f2e9 | ||
|
8c7e650f8f | ||
|
e6e6084e1c | ||
|
dc330b7d5b | ||
|
1ecaa22721 | ||
|
d516e9529d | ||
|
9afab2af89 | ||
|
4f36b21d2e | ||
|
e8041308b1 | ||
|
b04d7eb10a | ||
|
441c47c35f | ||
|
9bd001c9ed | ||
|
4ba1340e8e | ||
|
1094874321 | ||
|
84251abda7 | ||
|
fa4f9c2d82 | ||
|
7f275f2a3e | ||
|
ff56523865 | ||
|
1653698f99 | ||
|
a9dbfea8d1 | ||
|
7a9b5ee068 | ||
|
8e81d3825a | ||
|
bd67d553ea | ||
|
03f4dfe2e1 | ||
|
28d0b73bc5 | ||
|
0bfef9de14 | ||
|
622958bdb5 | ||
|
5c41fe8342 | ||
|
32a9144f55 | ||
|
e707d75624 | ||
|
868bfea65e | ||
|
9d3fe6e86e | ||
|
d9f36dc508 | ||
|
e35133b741 | ||
|
3df03768d2 | ||
|
4d6d97538c | ||
|
ede06e2ca8 | ||
|
f124186366 | ||
|
618e234d6c | ||
|
7bab142af1 | ||
|
11614b417b | ||
|
729d663832 | ||
|
e5fa27ba96 | ||
|
4b37779e9e | ||
|
46e8688de2 | ||
|
fceee07486 | ||
|
a108d0b986 | ||
|
362e23bea0 | ||
|
5ac77fca98 | ||
|
ab13f94cf0 | ||
|
764bce52fe | ||
|
b37c7f6cb9 | ||
|
35aa393f11 | ||
|
ed89eea72c | ||
|
f6f2d9bee7 | ||
|
66247ec6fd | ||
|
dbbf1918ab | ||
|
77895090dc | ||
|
2538662c9b | ||
|
89134729cc | ||
|
2132ac8ed2 | ||
|
7ed543ec35 | ||
|
907fe25d3c | ||
|
427d17351d | ||
|
b6146caf36 | ||
|
de37c031b5 | ||
|
ac49a480f4 | ||
|
31cbe96b4c | ||
|
5b9e61d839 | ||
|
e3af72febb | ||
|
aaf9f53571 | ||
|
9171ae9cd7 | ||
|
0b84a572d6 | ||
|
ec2f62fa5c | ||
|
a47c0913b5 |
212
.appveyor.yml
@ -20,118 +20,118 @@ environment:
|
||||
# -DBUILD_SERVER=OFF \
|
||||
# -DCMAKE_PREFIX_PATH=C:\\Qt\\5.15.2\\msvc2019_64;C:\\Libraries\\boost_1_73_0"
|
||||
# CMAKE_GENERATOR: Ninja
|
||||
- TARGET: ubuntu2204prod
|
||||
APPVEYOR_BUILD_WORKER_CLOUD: nasrock Docker
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Linux
|
||||
CC: "gcc-11"
|
||||
CXX: "g++-11"
|
||||
CMAKE_CUSTOM_OPTIONS: "-DCMAKE_BUILD_TYPE=Release \
|
||||
-DARCH_OPT=nehalem \
|
||||
-DDEBUG_OUTPUT=ON \
|
||||
-DENABLE_EXTERNAL_LIBRARIES=AUTO \
|
||||
-DBUILD_SERVER=OFF"
|
||||
# - TARGET: ubuntu2204prod
|
||||
# APPVEYOR_BUILD_WORKER_CLOUD: nasrock Docker
|
||||
# APPVEYOR_BUILD_WORKER_IMAGE: Linux
|
||||
# CC: "gcc-11"
|
||||
# CXX: "g++-11"
|
||||
# CMAKE_CUSTOM_OPTIONS: "-DCMAKE_BUILD_TYPE=Release \
|
||||
# -DARCH_OPT=nehalem \
|
||||
# -DDEBUG_OUTPUT=ON \
|
||||
# -DENABLE_EXTERNAL_LIBRARIES=AUTO \
|
||||
# -DBUILD_SERVER=OFF"
|
||||
- TARGET: ubuntu2204docker
|
||||
APPVEYOR_BUILD_WORKER_CLOUD: nasrock
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Linux
|
||||
APPVEYOR_CONSOLE_DISABLE_PTY: true
|
||||
|
||||
for:
|
||||
# - matrix:
|
||||
# only:
|
||||
# - TARGET: 'vs2019gui'
|
||||
# cache:
|
||||
# - C:\ProgramData\chocolatey\bin
|
||||
# - C:\ProgramData\chocolatey\lib
|
||||
# build_script:
|
||||
# - call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
|
||||
# # Install GNU patch as applying patches with git fails in BladeRF tree
|
||||
# - choco install patch
|
||||
# - git submodule update --init --recursive
|
||||
# - mkdir build && cd build
|
||||
# - cmake .. -G "%CMAKE_GENERATOR%" %CMAKE_CUSTOM_OPTIONS%
|
||||
# - cmake --build . --config Release --target package
|
||||
# artifacts: # push installer executable
|
||||
# path: build\*.exe
|
||||
# name: installer
|
||||
# deploy:
|
||||
# release: sdrangel-v$(appveyor_build_version)
|
||||
# description: 'SDRangel Windows'
|
||||
# provider: GitHub
|
||||
# auth_token:
|
||||
# secure: kyU5TaXRoily6q/QLRLqal2xCFGWEdnb8AJIu7FknsUQyj1wjRGmqC2My+Wfszod
|
||||
# artifact: installer, portable
|
||||
# draft: false
|
||||
# prerelease: false
|
||||
# tag: $(APPVEYOR_REPO_TAG_NAME) # will not work until tag is pushed
|
||||
# on:
|
||||
# APPVEYOR_REPO_TAG: true # deploy on tag push only
|
||||
# branch: master # release from master branch only
|
||||
- matrix:
|
||||
only:
|
||||
- TARGET: ubuntu2204prod
|
||||
clone_folder: /home/appveyor/projects
|
||||
cache:
|
||||
- $HOME/external/
|
||||
install:
|
||||
- sh: sudo apt-get update
|
||||
- sh: echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections
|
||||
# not sdrplay with soapysdr; libairspyhf-dev is too old (no lna)
|
||||
- sh: |
|
||||
sudo apt-get -y install build-essential cmake git xxd \
|
||||
devscripts fakeroot debhelper libfftw3-dev qtbase5-dev libopengl-dev libqt5opengl5-dev \
|
||||
qttools5-dev qttools5-dev-tools qtmultimedia5-dev libqt5multimedia5-plugins libqt5websockets5-dev \
|
||||
libqt5quick5 qtwebengine5-dev qtbase5-private-dev \
|
||||
qml-module-qtlocation qml-module-qtpositioning qml-module-qtquick-window2 qml-module-qtquick-dialogs \
|
||||
qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-layouts qml-module-qtgraphicaleffects \
|
||||
libqt5serialport5-dev qtdeclarative5-dev qtpositioning5-dev qtlocation5-dev \
|
||||
libqt5charts5-dev libqt5texttospeech5-dev libqt5gamepad5-dev libqt5svg5-dev libfaad-dev libflac-dev zlib1g-dev \
|
||||
libusb-1.0-0-dev libhidapi-dev libboost-all-dev libasound2-dev libopencv-dev libopencv-imgcodecs-dev \
|
||||
libxml2-dev bison flex ffmpeg libpostproc-dev libavcodec-dev libavformat-dev \
|
||||
libopus-dev libcodec2-dev libairspy-dev libhackrf-dev \
|
||||
libbladerf-dev libsoapysdr-dev libiio-dev libuhd-dev libhamlib-dev \
|
||||
python3-mako python3-cheetah python3-numpy \
|
||||
autoconf automake libtool ninja-build libclang1-11
|
||||
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_cm256cc.sh; fi
|
||||
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_mbelib.sh; fi
|
||||
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_serialdv.sh; fi
|
||||
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_dsdcc.sh; fi
|
||||
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_perseus-sdr.sh; fi
|
||||
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_xtrx-sdr.sh; fi
|
||||
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_airspyhf.sh; fi
|
||||
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_rtlsdr.sh; fi
|
||||
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_limesuite.sh; fi
|
||||
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_ggmorse.sh; fi
|
||||
- sh: bash cmake/ci/build_sdrplay.sh
|
||||
before_build:
|
||||
- sh: bash -c export
|
||||
- sh: bash -c pwd
|
||||
build_script:
|
||||
- sh: ./cmake/ci/build_sdrangel.sh
|
||||
test_script:
|
||||
# debian build path
|
||||
- sh: ./obj-x86_64-linux-gnu/sdrangelbench
|
||||
after_build:
|
||||
- sh: mkdir sdrangel-${APPVEYOR_BUILD_VERSION}
|
||||
- sh: cp ../*.deb ../*.build ../*.buildinfo ../*.changes sdrangel-${APPVEYOR_BUILD_VERSION}
|
||||
- sh: tar -czf sdrangel-${APPVEYOR_BUILD_VERSION}.tar.gz sdrangel-${APPVEYOR_BUILD_VERSION}
|
||||
artifacts:
|
||||
- path: sdrangel-${APPVEYOR_BUILD_VERSION}.tar.gz
|
||||
name: package2204
|
||||
# deploy:
|
||||
# release: sdrangel-v$(appveyor_build_version)
|
||||
# description: 'SDRangel Ubuntu 22.04'
|
||||
# provider: GitHub
|
||||
# auth_token:
|
||||
# secure: kyU5TaXRoily6q/QLRLqal2xCFGWEdnb8AJIu7FknsUQyj1wjRGmqC2My+Wfszod
|
||||
# artifact: archive
|
||||
# draft: false
|
||||
# prerelease: false
|
||||
# on:
|
||||
# APPVEYOR_REPO_TAG: true # deploy on tag push only
|
||||
# branch: master # release from master branch only
|
||||
deploy:
|
||||
provider: Environment
|
||||
name: f4exb
|
||||
# # - matrix:
|
||||
# # only:
|
||||
# # - TARGET: 'vs2019gui'
|
||||
# # cache:
|
||||
# # - C:\ProgramData\chocolatey\bin
|
||||
# # - C:\ProgramData\chocolatey\lib
|
||||
# # build_script:
|
||||
# # - call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
|
||||
# # # Install GNU patch as applying patches with git fails in BladeRF tree
|
||||
# # - choco install patch
|
||||
# # - git submodule update --init --recursive
|
||||
# # - mkdir build && cd build
|
||||
# # - cmake .. -G "%CMAKE_GENERATOR%" %CMAKE_CUSTOM_OPTIONS%
|
||||
# # - cmake --build . --config Release --target package
|
||||
# # artifacts: # push installer executable
|
||||
# # path: build\*.exe
|
||||
# # name: installer
|
||||
# # deploy:
|
||||
# # release: sdrangel-v$(appveyor_build_version)
|
||||
# # description: 'SDRangel Windows'
|
||||
# # provider: GitHub
|
||||
# # auth_token:
|
||||
# # secure: kyU5TaXRoily6q/QLRLqal2xCFGWEdnb8AJIu7FknsUQyj1wjRGmqC2My+Wfszod
|
||||
# # artifact: installer, portable
|
||||
# # draft: false
|
||||
# # prerelease: false
|
||||
# # tag: $(APPVEYOR_REPO_TAG_NAME) # will not work until tag is pushed
|
||||
# # on:
|
||||
# # APPVEYOR_REPO_TAG: true # deploy on tag push only
|
||||
# # branch: master # release from master branch only
|
||||
# - matrix:
|
||||
# only:
|
||||
# - TARGET: ubuntu2204prod
|
||||
# clone_folder: /home/appveyor/projects
|
||||
# cache:
|
||||
# - $HOME/external/
|
||||
# install:
|
||||
# - sh: sudo apt-get update
|
||||
# - sh: echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections
|
||||
# # not sdrplay with soapysdr; libairspyhf-dev is too old (no lna)
|
||||
# - sh: |
|
||||
# sudo apt-get -y install build-essential cmake git xxd \
|
||||
# devscripts fakeroot debhelper libfftw3-dev qtbase5-dev libopengl-dev libqt5opengl5-dev \
|
||||
# qttools5-dev qttools5-dev-tools qtmultimedia5-dev libqt5multimedia5-plugins libqt5websockets5-dev \
|
||||
# libqt5quick5 qtwebengine5-dev qtbase5-private-dev \
|
||||
# qml-module-qtlocation qml-module-qtpositioning qml-module-qtquick-window2 qml-module-qtquick-dialogs \
|
||||
# qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-layouts qml-module-qtgraphicaleffects \
|
||||
# libqt5serialport5-dev qtdeclarative5-dev qtpositioning5-dev qtlocation5-dev \
|
||||
# libqt5charts5-dev libqt5texttospeech5-dev libqt5gamepad5-dev libqt5svg5-dev libfaad-dev libflac-dev zlib1g-dev \
|
||||
# libusb-1.0-0-dev libhidapi-dev libboost-all-dev libasound2-dev libopencv-dev libopencv-imgcodecs-dev \
|
||||
# libxml2-dev bison flex ffmpeg libpostproc-dev libavcodec-dev libavformat-dev \
|
||||
# libopus-dev libcodec2-dev libairspy-dev libhackrf-dev \
|
||||
# libbladerf-dev libsoapysdr-dev libiio-dev libuhd-dev libhamlib-dev \
|
||||
# python3-mako python3-cheetah python3-numpy \
|
||||
# autoconf automake libtool ninja-build libclang1-11
|
||||
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_cm256cc.sh; fi
|
||||
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_mbelib.sh; fi
|
||||
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_serialdv.sh; fi
|
||||
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_dsdcc.sh; fi
|
||||
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_perseus-sdr.sh; fi
|
||||
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_xtrx-sdr.sh; fi
|
||||
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_airspyhf.sh; fi
|
||||
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_rtlsdr.sh; fi
|
||||
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_limesuite.sh; fi
|
||||
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_ggmorse.sh; fi
|
||||
# - sh: bash cmake/ci/build_sdrplay.sh
|
||||
# before_build:
|
||||
# - sh: bash -c export
|
||||
# - sh: bash -c pwd
|
||||
# build_script:
|
||||
# - sh: ./cmake/ci/build_sdrangel.sh
|
||||
# test_script:
|
||||
# # debian build path
|
||||
# - sh: ./obj-x86_64-linux-gnu/sdrangelbench
|
||||
# after_build:
|
||||
# - sh: mkdir sdrangel-${APPVEYOR_BUILD_VERSION}
|
||||
# - sh: cp ../*.deb ../*.build ../*.buildinfo ../*.changes sdrangel-${APPVEYOR_BUILD_VERSION}
|
||||
# - sh: tar -czf sdrangel-${APPVEYOR_BUILD_VERSION}.tar.gz sdrangel-${APPVEYOR_BUILD_VERSION}
|
||||
# artifacts:
|
||||
# - path: sdrangel-${APPVEYOR_BUILD_VERSION}.tar.gz
|
||||
# name: package2204
|
||||
# # deploy:
|
||||
# # release: sdrangel-v$(appveyor_build_version)
|
||||
# # description: 'SDRangel Ubuntu 22.04'
|
||||
# # provider: GitHub
|
||||
# # auth_token:
|
||||
# # secure: kyU5TaXRoily6q/QLRLqal2xCFGWEdnb8AJIu7FknsUQyj1wjRGmqC2My+Wfszod
|
||||
# # artifact: archive
|
||||
# # draft: false
|
||||
# # prerelease: false
|
||||
# # on:
|
||||
# # APPVEYOR_REPO_TAG: true # deploy on tag push only
|
||||
# # branch: master # release from master branch only
|
||||
# deploy:
|
||||
# provider: Environment
|
||||
# name: f4exb
|
||||
- matrix:
|
||||
only:
|
||||
- TARGET: ubuntu2204docker
|
||||
|
62
.github/workflows/linux.yml
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
name: SDRangel Linux release build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- linux_github_release
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
build_deb:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-22.04, ubuntu-24.04]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install build-essential cmake git xxd \
|
||||
devscripts fakeroot debhelper libfftw3-dev qtbase5-dev libopengl-dev libqt5opengl5-dev \
|
||||
qttools5-dev qttools5-dev-tools qtmultimedia5-dev libqt5multimedia5-plugins libqt5websockets5-dev \
|
||||
libqt5quick5 qtwebengine5-dev qtbase5-private-dev \
|
||||
qml-module-qtlocation qml-module-qtpositioning qml-module-qtquick-window2 qml-module-qtquick-dialogs \
|
||||
qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-layouts qml-module-qtgraphicaleffects \
|
||||
libqt5serialport5-dev qtdeclarative5-dev qtpositioning5-dev qtlocation5-dev \
|
||||
libqt5charts5-dev libqt5texttospeech5-dev libqt5gamepad5-dev libqt5svg5-dev libfaad-dev libflac-dev zlib1g-dev \
|
||||
libusb-1.0-0-dev libhidapi-dev libboost-all-dev libasound2-dev libopencv-dev libopencv-imgcodecs-dev \
|
||||
libxml2-dev bison flex ffmpeg libpostproc-dev libavcodec-dev libavformat-dev \
|
||||
libopus-dev libcodec2-dev libairspy-dev libhackrf-dev \
|
||||
libbladerf-dev libsoapysdr-dev libiio-dev libuhd-dev libhamlib-dev \
|
||||
python3-mako python3-cheetah python3-numpy \
|
||||
autoconf automake libtool ninja-build
|
||||
bash cmake/ci/build_sdrplay.sh
|
||||
- name: Build SDRangel
|
||||
run: |
|
||||
debuild -i -us -uc -b
|
||||
- name: Get version
|
||||
id: get_version
|
||||
run: |
|
||||
if [[ "${{github.ref_name}}" == "linux_github_release" ]]; then
|
||||
echo "version=$(echo ${{github.sha}} | cut -c1-7)" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "version=$(echo ${{github.ref_name}} | cut -c2-)" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
- name: Rename
|
||||
run: mv ../sdrangel_*_amd64.deb sdrangel_${{ steps.get_version.outputs.version }}_${{ matrix.os }}_amd64.deb
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sdrangel_${{ steps.get_version.outputs.version }}_${{ matrix.os }}_amd64.deb
|
||||
path: sdrangel_${{ steps.get_version.outputs.version }}_${{ matrix.os }}_amd64.deb
|
||||
- name: Upload release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: sdrangel_${{ steps.get_version.outputs.version }}_${{ matrix.os }}_amd64.deb
|
161
.github/workflows/mac.yml
vendored
Normal file
@ -0,0 +1,161 @@
|
||||
name: SDRangel Mac release build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- mac_ci
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
build_mac_x64:
|
||||
runs-on: macos-13
|
||||
env:
|
||||
MACOSX_DEPLOYMENT_TARGET: 12.0
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
- name: Update brew
|
||||
run: brew update
|
||||
- name: Install brew packages
|
||||
run: brew install nasm subversion
|
||||
- name: Install SDRplay API
|
||||
run: |
|
||||
wget https://www.sdrplay.com/software/SDRplayAPI-macos-installer-universal-3.15.0.pkg
|
||||
sudo installer -pkg SDRplayAPI-macos-installer-universal-3.15.0.pkg -target /
|
||||
- name: Install python
|
||||
run: |
|
||||
wget https://www.python.org/ftp/python/3.12.7/python-3.12.7-macos11.pkg
|
||||
sudo installer -pkg python-3.12.7-macos11.pkg -target /
|
||||
- name: Install python packages for UHD
|
||||
run: |
|
||||
/usr/local/bin/python3.12 -m pip install numpy mako requests Cheetah3 setuptools
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
version: '6.9.1'
|
||||
host: 'mac'
|
||||
arch: 'clang_64'
|
||||
modules: 'qtcharts qtscxml qt5compat qtlocation qtmultimedia qtpositioning qtserialport qtspeech qtwebsockets qtwebengine qtshadertools qtwebchannel'
|
||||
- name: Configure SDRangel
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake .. -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_QT6=ON -DCMAKE_BUILD_TYPE=Release -DARCH_OPT=nehalem -DDEBUG_OUTPUT=ON -DENABLE_USRP=ON -DENABLE_MIRISDR=OFF -DBUILD_SERVER=OFF -DENABLE_EXTERNAL_LIBRARIES=ON -DBUNDLE=ON -DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=TRUE -DPYTHON_EXECUTABLE=/usr/local/bin/python3.12
|
||||
- name: Build SDRangel on Mac
|
||||
run: |
|
||||
cd build
|
||||
make -j4
|
||||
- name: Create dmg
|
||||
run: |
|
||||
cd build
|
||||
RETRIES=5
|
||||
COUNT=1
|
||||
set +e
|
||||
while [ $COUNT -lt $RETRIES ]; do
|
||||
make package
|
||||
if [ $? -eq 0 ]; then
|
||||
RETRIES=0
|
||||
break
|
||||
fi
|
||||
let COUNT=$COUNT+1
|
||||
done
|
||||
shell: bash
|
||||
continue-on-error: true
|
||||
- name: Get version
|
||||
id: get_version
|
||||
run: |
|
||||
if [[ "${{github.ref_name}}" == "mac_ci" ]]; then
|
||||
echo "version=$(echo ${{github.sha}} | cut -c1-7)" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "version=$(echo ${{github.ref_name}} | cut -c2-)" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
- name: Get filename
|
||||
id: get_filename
|
||||
run: echo "filename=$(grep CPACK_PACKAGE_FILE_NAME build/CMakeCache.txt | cut -d "=" -f2)" >> $GITHUB_OUTPUT
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sdrangel-${{ steps.get_version.outputs.version }}-macx64.dmg
|
||||
path: ${{ github.workspace }}/build/${{ steps.get_filename.outputs.filename }}.dmg
|
||||
- name: Upload release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: ${{ github.workspace }}/build/${{ steps.get_filename.outputs.filename }}.dmg
|
||||
|
||||
build_mac_arm64:
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
- name: Update brew
|
||||
run: brew update
|
||||
- name: Install brew packages
|
||||
run: brew install nasm subversion
|
||||
- name: Install SDRplay API
|
||||
run: |
|
||||
wget https://www.sdrplay.com/software/SDRplayAPI-macos-installer-universal-3.15.0.pkg
|
||||
sudo installer -pkg SDRplayAPI-macos-installer-universal-3.15.0.pkg -target /
|
||||
- name: Install python
|
||||
run: |
|
||||
wget https://www.python.org/ftp/python/3.12.7/python-3.12.7-macos11.pkg
|
||||
sudo installer -pkg python-3.12.7-macos11.pkg -target /
|
||||
- name: Install python packages for UHD
|
||||
run: |
|
||||
/usr/local/bin/python3.12 -m pip install numpy mako requests Cheetah3 setuptools
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
version: '6.9.1'
|
||||
host: 'mac'
|
||||
arch: 'clang_64'
|
||||
modules: 'qtcharts qtscxml qt5compat qtlocation qtmultimedia qtpositioning qtserialport qtspeech qtwebsockets qtwebengine qtshadertools qtwebchannel'
|
||||
- name: Configure SDRangel
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake .. -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_QT6=ON -DCMAKE_BUILD_TYPE=Release -DDEBUG_OUTPUT=ON -DENABLE_USRP=ON -DENABLE_MIRISDR=OFF -DBUILD_SERVER=OFF -DENABLE_EXTERNAL_LIBRARIES=ON -DBUNDLE=ON -DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=TRUE -DPYTHON_EXECUTABLE=/usr/local/bin/python3.12
|
||||
- name: Build SDRangel on Mac
|
||||
run: |
|
||||
cd build
|
||||
make -j3
|
||||
- name: Create dmg
|
||||
run: |
|
||||
cd build
|
||||
RETRIES=5
|
||||
COUNT=1
|
||||
set +e
|
||||
while [ $COUNT -lt $RETRIES ]; do
|
||||
make package
|
||||
if [ $? -eq 0 ]; then
|
||||
RETRIES=0
|
||||
break
|
||||
fi
|
||||
let COUNT=$COUNT+1
|
||||
done
|
||||
shell: bash
|
||||
continue-on-error: true
|
||||
- name: Get version
|
||||
id: get_version
|
||||
run: |
|
||||
if [[ "${{github.ref_name}}" == "mac_ci" ]]; then
|
||||
echo "version=$(echo ${{github.sha}} | cut -c1-7)" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "version=$(echo ${{github.ref_name}} | cut -c2-)" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
- name: Get filename
|
||||
id: get_filename
|
||||
run: echo "filename=$(grep CPACK_PACKAGE_FILE_NAME build/CMakeCache.txt | cut -d "=" -f2)" >> $GITHUB_OUTPUT
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sdrangel-${{ steps.get_version.outputs.version }}-macarm64.dmg
|
||||
path: ${{ github.workspace }}/build/${{ steps.get_filename.outputs.filename }}.dmg
|
||||
- name: Upload release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: ${{ github.workspace }}/build/${{ steps.get_filename.outputs.filename }}.dmg
|
28
.github/workflows/sdrangel.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
||||
WIN_ARCH: "x64",
|
||||
os: windows-latest,
|
||||
QT_INST_DIR: "C:/",
|
||||
QTDIR: "C:/Qt/5.15.2/msvc2019_64",
|
||||
QTDIR: "C:/Qt/6.7.3/msvc2019_64",
|
||||
QT_ARCH: win64_msvc2019_64,
|
||||
boost_dl: "${{ github.workspace }}\\downloads\\boost",
|
||||
lib_dir: "C:\\Libraries",
|
||||
@ -41,6 +41,9 @@ jobs:
|
||||
echo github.event_name: ${{ github.event_name }}
|
||||
echo github.ref: ${{ github.ref }}
|
||||
echo github.workspace: ${{ github.workspace }}
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
- name: Install basic dependencies on Windows
|
||||
if: startsWith(matrix.config.os, 'windows')
|
||||
run: |
|
||||
@ -69,19 +72,20 @@ jobs:
|
||||
rm -rf boost_*/* download.tar.bz2 download.tar
|
||||
shell: bash
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
version: '6.7.3'
|
||||
dir: ${{matrix.config.QT_INST_DIR}}
|
||||
arch: ${{matrix.config.QT_ARCH}}
|
||||
setup-python: false
|
||||
modules: 'qtcharts qtwebengine'
|
||||
modules: 'qtcharts qtscxml qt5compat qtlocation qtmultimedia qtpositioning qtserialport qtspeech qtwebsockets qtwebengine qtshadertools qtwebchannel'
|
||||
- name: build sdrangel on Windows
|
||||
if: startsWith(matrix.config.os, 'windows')
|
||||
run: |
|
||||
cmd "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||
cmd "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||
choco install patch
|
||||
mkdir build && cd build
|
||||
cmake .. -G "${{ matrix.config.generators }}" -DCMAKE_BUILD_TYPE=Release -DARCH_OPT=SSE4_2 -DDEBUG_OUTPUT=ON -DENABLE_MIRISDR=OFF -DBUILD_SERVER=OFF -DCMAKE_PREFIX_PATH="C:\Qt\5.15.2\msvc2019_64;C:\Libraries\boost_1_73_0"
|
||||
cmake .. -G "${{ matrix.config.generators }}" -DCMAKE_BUILD_TYPE=Release -DENABLE_QT6=ON -DARCH_OPT=SSE4_2 -DDEBUG_OUTPUT=ON -DENABLE_MIRISDR=OFF -DBUILD_SERVER=OFF -DCMAKE_PREFIX_PATH="C:\Qt\6.7.3\msvc2019_64;C:\Libraries\boost_1_73_0"
|
||||
cmake --build . --config Release --target package
|
||||
- name: Check disk space
|
||||
run: Get-PSDrive
|
||||
@ -89,18 +93,13 @@ jobs:
|
||||
id: get_version
|
||||
run: echo "version=$(grep sdrangel_VERSION build/CMakeCache.txt | cut -d "=" -f2)" >> $env:GITHUB_OUTPUT
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
|
||||
path: ${{ github.workspace }}/build/sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
|
||||
- name: Upload release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: softprops/action-gh-release@v0.1.13
|
||||
with:
|
||||
files: ${{ github.workspace }}/build/sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
|
||||
|
||||
build_mac:
|
||||
runs-on: macos-13
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@ -125,10 +124,7 @@ jobs:
|
||||
- name: Configure SDRangel
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake .. -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_QT6=ON -DCMAKE_BUILD_TYPE=Release -DARCH_OPT=nehalem -DDEBUG_OUTPUT=ON -DENABLE_CHANNELRX_DEMODDATV=OFF -DENABLE_CHANNELTX_MODDATV=OFF -DENABLE_MIRISDR=OFF -DBUILD_SERVER=OFF -DENABLE_EXTERNAL_LIBRARIES=AUTO -DBUNDLE=ON -DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=TRUE -DCMAKE_PREFIX_PATH="/usr/local/opt/ffmpeg@5/"
|
||||
- name: Get filename
|
||||
id: get_filename
|
||||
run: echo "filename=$(grep CPACK_PACKAGE_FILE_NAME build/CMakeCache.txt | cut -d "=" -f2)" >> $GITHUB_OUTPUT
|
||||
cmake .. -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_QT6=ON -DCMAKE_BUILD_TYPE=Release -DDEBUG_OUTPUT=ON -DENABLE_CHANNELRX_DEMODDATV=OFF -DENABLE_CHANNELTX_MODDATV=OFF -DENABLE_MIRISDR=OFF -DBUILD_SERVER=OFF -DENABLE_EXTERNAL_LIBRARIES=AUTO -DBUNDLE=ON -DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=TRUE -DCMAKE_PREFIX_PATH="/usr/local/opt/ffmpeg@5/"
|
||||
- name: Build SDRangel on Mac
|
||||
run: |
|
||||
cd build
|
||||
|
44
.github/workflows/snap.yml
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
# See: https://github.com/snapcore/action-build
|
||||
name: SDRangel snap release build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- snap
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
build_snap:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
- name: Get version
|
||||
id: get_version
|
||||
run: |
|
||||
if [[ "${{github.ref_name}}" == "snap" ]]; then
|
||||
echo "version=${{github.sha}}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "version=$(echo ${{github.ref_name}} | cut -c2-)" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
- uses: snapcore/action-build@v1
|
||||
id: build
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sdrangel-${{ steps.get_version.outputs.version }}-amd64.snap
|
||||
path: ${{ steps.build.outputs.snap }}
|
||||
- name: Upload release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: ${{ steps.build.outputs.snap }}
|
||||
- uses: snapcore/action-publish@v1
|
||||
env:
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_STORE_LOGIN }}
|
||||
with:
|
||||
snap: ${{ steps.build.outputs.snap }}
|
||||
release: stable
|
119
.github/workflows/windows.yml
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
name: SDRangel Windows release build and signing
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.config.name }}
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- {
|
||||
name: "Windows-x64",
|
||||
WIN_ARCH: "x64",
|
||||
os: windows-latest,
|
||||
QT_INST_DIR: "C:/",
|
||||
QTDIR: "C:/Qt/6.7.3/msvc2019_64",
|
||||
QT_ARCH: win64_msvc2019_64,
|
||||
boost_dl: "${{ github.workspace }}\\downloads\\boost",
|
||||
lib_dir: "C:\\Libraries",
|
||||
generators: Ninja
|
||||
}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
- name: Print env
|
||||
run: |
|
||||
echo github.event.action: ${{ github.event.action }}
|
||||
echo github.event_name: ${{ github.event_name }}
|
||||
echo github.ref: ${{ github.ref }}
|
||||
echo github.workspace: ${{ github.workspace }}
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
- name: Install basic dependencies on Windows
|
||||
if: startsWith(matrix.config.os, 'windows')
|
||||
run: |
|
||||
choco install ninja cmake
|
||||
ninja --version
|
||||
cmake --version
|
||||
- name: Install MSVC on Windows
|
||||
if: startsWith(matrix.config.os, 'windows')
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: x64
|
||||
- name: Install Boost
|
||||
env:
|
||||
BOOST_ROOT: ${{ matrix.config.boost_dl }}
|
||||
BOOST_DEST: ${{ matrix.config.lib_dir }}
|
||||
BOOST_URL: https://archives.boost.io/release/1.73.0/source/boost_1_73_0.tar.bz2
|
||||
run: |
|
||||
mkdir -p $BOOST_ROOT
|
||||
mkdir -p $BOOST_DEST
|
||||
curl --progress-bar --location --output $BOOST_ROOT/download.tar.bz2 $BOOST_URL
|
||||
7z -o$BOOST_ROOT x $BOOST_ROOT/download.tar.bz2 -y -bd
|
||||
7z -o$BOOST_ROOT x $BOOST_ROOT/download.tar -y -bd
|
||||
cd $BOOST_ROOT && cp -r boost_* $BOOST_DEST
|
||||
ls -l $BOOST_DEST
|
||||
ls -l "C:\\"
|
||||
rm -rf boost_*/* download.tar.bz2 download.tar
|
||||
shell: bash
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
version: '6.7.3'
|
||||
dir: ${{matrix.config.QT_INST_DIR}}
|
||||
arch: ${{matrix.config.QT_ARCH}}
|
||||
setup-python: 'false'
|
||||
modules: 'qtcharts qtscxml qt5compat qtlocation qtmultimedia qtpositioning qtserialport qtspeech qtwebsockets qtwebengine qtshadertools qtwebchannel'
|
||||
- name: build sdrangel on Windows
|
||||
if: startsWith(matrix.config.os, 'windows')
|
||||
run: |
|
||||
cmd "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||
choco install patch
|
||||
mkdir build && cd build
|
||||
cmake .. -G "${{ matrix.config.generators }}" -DCMAKE_BUILD_TYPE=Release -DENABLE_QT6=ON -DARCH_OPT=SSE4_2 -DDEBUG_OUTPUT=ON -DENABLE_MIRISDR=OFF -DBUILD_SERVER=OFF -DCMAKE_PREFIX_PATH="C:\Qt\6.7.3\msvc2019_64;C:\Libraries\boost_1_73_0"
|
||||
cmake --build . --config Release --target package
|
||||
- name: Check disk space
|
||||
run: Get-PSDrive
|
||||
- name: Get version
|
||||
id: get_version
|
||||
run: echo "version=$(grep sdrangel_VERSION build/CMakeCache.txt | cut -d "=" -f2)" >> $env:GITHUB_OUTPUT
|
||||
- name: Upload unsigned artifact
|
||||
id: upload-unsigned-artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
|
||||
path: ${{ github.workspace }}/build/sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
|
||||
- name: Sign Code
|
||||
id: sign_code
|
||||
uses: signpath/github-action-submit-signing-request@v1
|
||||
with:
|
||||
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
|
||||
organization-id: '553b8f53-adf0-4fe5-be3d-283504a21a51'
|
||||
project-slug: 'sdrangel'
|
||||
signing-policy-slug: 'release-signing'
|
||||
github-artifact-id: '${{ steps.upload-unsigned-artifact.outputs.artifact-id }}'
|
||||
wait-for-completion: true
|
||||
output-artifact-directory: 'build\signed'
|
||||
wait-for-completion-timeout-in-seconds: 3600
|
||||
- name: Upload signed artifact
|
||||
id: upload-signed-artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sdrangel-${{ steps.get_version.outputs.version }}-win64-signed.exe
|
||||
path: ${{ github.workspace }}/build/signed/sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
|
||||
- name: Upload release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: ${{ github.workspace }}/build/signed/sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
|
76
CHANGELOG
@ -1,3 +1,77 @@
|
||||
sdrangel (7.22.8-1) unstable; urgency=medium
|
||||
|
||||
* See Github release
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Wed, 02 Jul 2025 17:00:39 +0200
|
||||
|
||||
sdrangel (7.22.7-1) unstable; urgency=medium
|
||||
|
||||
* See Github release
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 04 May 2025 17:58:14 +0200
|
||||
|
||||
sdrangel (7.22.6-1) unstable; urgency=medium
|
||||
|
||||
* See Github release
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 02 Feb 2025 18:08:11 +0100
|
||||
|
||||
sdrangel (7.22.5-1) unstable; urgency=medium
|
||||
|
||||
* Windows: upload signed releases rather than unsigned releases to Github releases page. PR #2347
|
||||
* Windows: fixed signed releases. PR #2344
|
||||
* FT8 Demod: limit upper bandwidth to 5.8 kHz. Fixes #2339
|
||||
* Stop device while changing channel set. Fixes #2332. PR #2342
|
||||
* ADSB: Update URL of OpenSkyNetwork Aircraft database. PR #2341
|
||||
* Don't stop source if being deleted. For #2315. PR #2340
|
||||
* Send DSPSignalNotification in audio mods for #2336. PR #2340
|
||||
* Radiosonde: limit precision of floating point numbers sent to SondeHub. PR #2338
|
||||
* Windows signed releases: use relative path. Increase timeout to 30 minutes. PR #2335
|
||||
* ADSB: Include adsbdemodsettings.h PR #2334
|
||||
* Use release signing certificate for Windows installer. PR #2331
|
||||
* Fix memory leak and race condition relating to DSP*Engines. Part of #2159 PR #2330
|
||||
* FreeDV: Fix memory allocation/free issues. Part of #2315. PR #2330
|
||||
* Wav Files: Add support for meta-data. PR #2328
|
||||
* DemodAnalyzer: Ensure sample rate is set in worker. Fixes #2309. PR #2328
|
||||
^ SDRplayv3: Mac: link with libsdrplay_api.so.3 rather than libsdrplay_api.so.3.15. PR #2327
|
||||
* ADS-B: Fix memory use after delete. For #1734 and part of #2315 PR #2326
|
||||
* Fixed Appveyor Docker image build
|
||||
* Fix output-artifact-directory and unzip file. PR #2323
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Thu, 05 Dec 2024 01:07:27 +0100
|
||||
|
||||
sdrangel (7.22.4-1) unstable; urgency=medium
|
||||
|
||||
* Use macos-12 for Mac x86 build. PR #2321
|
||||
* Workaround for "hdiutil: create failed - Resource busy"
|
||||
* Pager: Add alpha and numeric columns. Implements #2319. PR #2320
|
||||
* Added qtwebchannel dependecy to fix missing 3d Map and Sky Map from Windows release. PR #2316
|
||||
* Removed .deb package build from Appveyor
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Mom, 11 Nov 2024 08:42:03 +0100
|
||||
|
||||
sdrangel (7.22.3-1) unstable; urgency=medium
|
||||
|
||||
* Add deb dependencies for pipewire. PR #2314
|
||||
* Added compilation options for WebAssembly. PR #2313
|
||||
* ADS-B: Use settings keys. PR #2310
|
||||
* AIS Demod: Remove spacing around messages. PR #2310
|
||||
* Freuqency Scanner: Add multiplex mode. PR #2310
|
||||
* Build snap, MAC, Windows and Ubuntu .deb with Github actions. Various PRs
|
||||
* Server: Use Sink/MIMO signals rather than Source. Part of #2294. PR #2304
|
||||
* Updated some Python scripts to Python3. PR #2298
|
||||
* RemoteTCPSink: Does use IQ only setting for RTL0. PR #2301
|
||||
* Server: wait for set sample source/sink/MIMO to complete before loading the device settings. Fixes #2294
|
||||
* Fix spectrum peak measurement for SSB spectra. Fixes #2282. PR #2299
|
||||
* Upgrade C++ standard to c++17
|
||||
* Fixes for Android . PR #2288
|
||||
* Add qtshadertools. PR #2287
|
||||
* Add more Qt modules and set ENABLE_QT6=ON. PR #2287
|
||||
* Update Qt optional packages for 6.8 , PR #2287
|
||||
* Use Qt 6.8 for Windows build. PR #2287
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sat, 09 Nov 2024 17:30:44 +0100
|
||||
|
||||
sdrangel (7.22.2-1) unstable; urgency=medium
|
||||
|
||||
* ChirpChat: increased preamble symbols limit from 20 to 32. Fixes #2284
|
||||
@ -19,7 +93,7 @@ sdrangel (7.22.2-1) unstable; urgency=medium
|
||||
* RemoteTCPInput: Add wss protocol support. PR #2270
|
||||
* Fix DeviceAPI::deserialize. Fixes #2266. PR #2267
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 20 Oct 2024 08:26:38 +0200
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 20 Oct 2024 08:26:38 +0200
|
||||
|
||||
sdrangel (7.22.1-1) unstable; urgency=medium
|
||||
|
||||
|
@ -11,7 +11,7 @@ endif()
|
||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
|
||||
|
||||
# disable only when needed
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
@ -20,7 +20,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
# configure version
|
||||
set(sdrangel_VERSION_MAJOR "7")
|
||||
set(sdrangel_VERSION_MINOR "22")
|
||||
set(sdrangel_VERSION_PATCH "2")
|
||||
set(sdrangel_VERSION_PATCH "8")
|
||||
set(sdrangel_VERSION_SUFFIX "")
|
||||
|
||||
# SDRAngel cmake options
|
||||
@ -277,6 +277,7 @@ set(INSTALL_PLUGINSSRV_DIR "${INSTALL_LIB_DIR}/pluginssrv")
|
||||
if(ANDROID)
|
||||
set(PLUGINS_PREFIX "sdrangel_plugins_")
|
||||
set(PLUGINSSRV_PREFIX "sdrangel_pluginssrv_")
|
||||
set(ANDROID_PACKAGE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/android/qt6 CACHE INTERNAL "")
|
||||
else()
|
||||
set(PLUGINS_PREFIX "")
|
||||
set(PLUGINSSRV_PREFIX "")
|
||||
@ -428,7 +429,7 @@ elseif (WIN32)
|
||||
elseif(ANDROID)
|
||||
set(EXTERNAL_LIBRARY_FOLDER "${CMAKE_SOURCE_DIR}/external/android")
|
||||
|
||||
set(Boost_INCLUDE_DIR "${EXTERNAL_LIBRARY_FOLDER}/ndk_21_boost_1.72.0/include" CACHE INTERNAL "")
|
||||
set(Boost_INCLUDE_DIR "${EXTERNAL_LIBRARY_FOLDER}/ndk_26b_boost_1.83.0/include" CACHE INTERNAL "")
|
||||
|
||||
set(FFTW3F_FOUND ON CACHE INTERNAL "")
|
||||
set(FFTW3F_INCLUDE_DIRS "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/fftw-3/include" CACHE INTERNAL "")
|
||||
@ -485,6 +486,14 @@ elseif(ANDROID)
|
||||
set(SWSCALE_INCLUDE_DIRS "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/ffmpeg/include" CACHE INTERNAL "")
|
||||
set(SWSCALE_LIBRARIES "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/ffmpeg/lib/libswscale.so" CACHE INTERNAL "")
|
||||
|
||||
set(GGMORSE_FOUND ON CACHE INTERNAL "")
|
||||
set(GGMORSE_INCLUDE_DIR "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/ggmorse/include/" CACHE INTERNAL "")
|
||||
set(GGMORSE_LIBRARIES "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/ggmorse/lib/static/libggmorse.a" CACHE INTERNAL "")
|
||||
|
||||
set(FLAC_FOUND ON CACHE INTERNAL "")
|
||||
set(FLAC_INCLUDE_DIR "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/flac/include/" CACHE INTERNAL "")
|
||||
set(FLAC_LIBRARIES "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/flac/lib/libFLAC.so" CACHE INTERNAL "")
|
||||
|
||||
set(LIBUSB_FOUND ON CACHE INTERNAL "")
|
||||
set(LIBUSB_INCLUDE_DIR "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/libusb/include/" CACHE INTERNAL "")
|
||||
set(LIBUSB_LIBRARIES "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/libusb/lib/libusb1.0.so" CACHE INTERNAL "")
|
||||
@ -507,11 +516,6 @@ elseif(ANDROID)
|
||||
|
||||
if (ENABLE_QT6)
|
||||
set(ANDROID_EXTRA_LIBS
|
||||
${Qt6_DIR}/../../../android_arm64_v8a/lib/libQt6Charts_arm64-v8a.so
|
||||
${Qt6_DIR}/../../../android_arm64_v8a/lib/libQt6Concurrent_arm64-v8a.so
|
||||
${Qt6_DIR}/../../../android_arm64_v8a/lib/libQt6MultimediaWidgets_arm64-v8a.so
|
||||
${Qt6_DIR}/../../../android_arm64_v8a/lib/libQt6SerialPort_arm64-v8a.so
|
||||
${Qt6_DIR}/../../../android_arm64_v8a/lib/libQt6TextToSpeech_arm64-v8a.so
|
||||
${EXTERNAL_LIBRARY_FOLDER}/android_openssl/latest/arm64/libssl_1_1.so
|
||||
${EXTERNAL_LIBRARY_FOLDER}/android_openssl/latest/arm64/libcrypto_1_1.so
|
||||
${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/ffmpeg/lib/libavcodec.so
|
||||
@ -526,6 +530,7 @@ elseif(ANDROID)
|
||||
${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/dsdcc/lib/libdsdcc.so
|
||||
${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/libusb/lib/libunrooted_android.so
|
||||
${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/libusb/lib/libusb1.0.so
|
||||
${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/flac/lib/libFLAC.so
|
||||
CACHE INTERNAL ""
|
||||
)
|
||||
else()
|
||||
@ -576,6 +581,7 @@ elseif(ANDROID)
|
||||
${EXTERNAL_LIBRARY_FOLDER}/arm64-v8a/dsdcc/lib/libdsdcc.so
|
||||
${EXTERNAL_LIBRARY_FOLDER}/arm64-v8a/libusb/lib/libunrooted_android.so
|
||||
${EXTERNAL_LIBRARY_FOLDER}/arm64-v8a/libusb/lib/libusb1.0.so
|
||||
${EXTERNAL_LIBRARY_FOLDER}/arm64-v8a/flac/lib/libFLAC.so
|
||||
${EXTERNAL_LIBRARY_FOLDER}/armeabi-v7a/ffmpeg/lib/libavcodec.so
|
||||
${EXTERNAL_LIBRARY_FOLDER}/armeabi-v7a/ffmpeg/lib/libavdevice.so
|
||||
${EXTERNAL_LIBRARY_FOLDER}/armeabi-v7a/ffmpeg/lib/libavfilter.so
|
||||
@ -588,6 +594,7 @@ elseif(ANDROID)
|
||||
${EXTERNAL_LIBRARY_FOLDER}/armeabi-v7a/dsdcc/lib/libdsdcc.so
|
||||
${EXTERNAL_LIBRARY_FOLDER}/armeabi-v7a/libusb/lib/libunrooted_android.so
|
||||
${EXTERNAL_LIBRARY_FOLDER}/armeabi-v7a/libusb/lib/libusb1.0.so
|
||||
${EXTERNAL_LIBRARY_FOLDER}/armeabi-v7a/flac/lib/libFLAC.so
|
||||
CACHE INTERNAL ""
|
||||
)
|
||||
endif()
|
||||
@ -650,8 +657,7 @@ if(ENABLE_QT6)
|
||||
MultimediaWidgets
|
||||
Positioning
|
||||
Charts
|
||||
SerialPort
|
||||
Core5Compat)
|
||||
SerialPort)
|
||||
else()
|
||||
find_package(Qt5 5.15
|
||||
REQUIRED COMPONENTS
|
||||
@ -679,7 +685,8 @@ if (BUILD_GUI)
|
||||
QuickWidgets
|
||||
TextToSpeech
|
||||
Svg
|
||||
SvgWidgets)
|
||||
SvgWidgets
|
||||
StateMachine)
|
||||
else()
|
||||
find_package(Qt5
|
||||
REQUIRED COMPONENTS
|
||||
|
15
app/main.cpp
@ -22,7 +22,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
#include <QProxyStyle>
|
||||
#include <QStyleFactory>
|
||||
#include <QFontDatabase>
|
||||
@ -48,10 +47,6 @@
|
||||
|
||||
static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *logger)
|
||||
{
|
||||
/*
|
||||
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
|
||||
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
|
||||
*/
|
||||
QCoreApplication::setOrganizationName(COMPANY);
|
||||
QCoreApplication::setApplicationName(APPLICATION_NAME);
|
||||
QCoreApplication::setApplicationVersion(SDRANGEL_VERSION);
|
||||
@ -193,7 +188,9 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo
|
||||
logger = nullptr;
|
||||
}
|
||||
|
||||
MainWindow w(logger, parser);
|
||||
MainWindow w(logger, parser);
|
||||
|
||||
w.show();
|
||||
|
||||
if (parser.getListDevices())
|
||||
{
|
||||
@ -202,12 +199,6 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (parser.getRemoteTCPSink()) {
|
||||
RemoteTCPSinkStarter::start(parser);
|
||||
}
|
||||
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,11 @@ if(WIN32)
|
||||
endif()
|
||||
|
||||
if(NOT MSVC)
|
||||
add_compile_options(-Wall -Wextra -Wvla -Woverloaded-virtual -Wno-inconsistent-missing-override -ffast-math -fno-finite-math-only -ftree-vectorize)
|
||||
add_compile_options(-Wall -Wextra -Wvla -ffast-math -fno-finite-math-only -ftree-vectorize)
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Woverloaded-virtual>)
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
add_compile_options(-Wno-inconsistent-missing-override)
|
||||
endif()
|
||||
else()
|
||||
# Disable some warnings, so more useful warnings aren't hidden in the noise
|
||||
# 4996 'fopen': This function or variable may be unsafe. Consider using fopen_s instead.
|
||||
|
@ -36,7 +36,7 @@ if(APPLE AND BUNDLE AND BUILD_GUI)
|
||||
set(CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/cmake/cpack/sdrangel_icon.icns")
|
||||
set(CPACK_BUNDLE_PLIST "${CMAKE_BINARY_DIR}/Info.plist")
|
||||
set(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/cmake/cpack/sdrangel_icon.icns")
|
||||
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION}_${CPACK_MACOS_PACKAGE_ARCHITECTURE}_${CMAKE_SYSTEM_PROCESSOR}" CACHE INTERNAL "")
|
||||
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION}_mac-${CPACK_MACOS_PACKAGE_ARCHITECTURE}_${CMAKE_SYSTEM_PROCESSOR}" CACHE INTERNAL "")
|
||||
set(CPACK_PRE_BUILD_SCRIPTS "${PROJECT_BINARY_DIR}/deploy_mac.cmake")
|
||||
|
||||
# copy SoapySDR Modules
|
||||
@ -175,7 +175,7 @@ elseif(WIN32 OR MINGW)
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${fftw3f_dll}" "${SDRANGEL_BINARY_BIN_DIR}/"
|
||||
)
|
||||
endforeach(fftw3f_dll)
|
||||
|
||||
|
||||
file(GLOB LIBUSB_DLLS "${LIBUSB_DLL_DIR}/*${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
foreach(libusb_dll ${LIBUSB_DLLS})
|
||||
get_filename_component(libusb_dll_name "${libusb_dll}" NAME)
|
||||
|
@ -1,14 +1,15 @@
|
||||
# This CPACK_PRE_BUILD_SCRIPTS script is used to copy all required Qt and other 3rd party libraries (SDR drivers and codecs) in to the .app bundle
|
||||
# It is run in a staging area (${CPACK_TEMPORARY_INSTALL_DIRECTORY}/SDRangel.app) after all targets have been installed (E.g. sdrangel exe and plugins)
|
||||
# The copying of frameworks and libraries is mostly done by 'macdeployqt', however, in order for 'macdeployqt' to copy libraries built by external/CMakeLists.txt,
|
||||
# we first need to add RPATHs into the libraries giving the locations of any libraries they might depend on.
|
||||
# we first need to add RPATHs into the libraries giving the locations of any libraries they might depend on.
|
||||
# These paths are in the variable MACOS_EXTERNAL_LIBS_FIXUP set in externals/CMakeLists.txt
|
||||
# Is there an easier way to this?
|
||||
|
||||
# Copy executable that will be run when icon in /Applications is clicked
|
||||
message ("Copying default executable to SDRangel.app/Contents/MacOS/SDRangel")
|
||||
execute_process (COMMAND mkdir ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/SDRangel.app/Contents/MacOS/)
|
||||
execute_process (COMMAND cp /opt/build/sdrangel/build/sdrangel ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/SDRangel.app/Contents/MacOS/SDRangel)
|
||||
execute_process (COMMAND pwd)
|
||||
execute_process (COMMAND cp sdrangel ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/SDRangel.app/Contents/MacOS/SDRangel)
|
||||
|
||||
|
||||
# Add RPATHS to libraries so macdeployqt can find out and copy all dependencies
|
||||
|
76
debian/changelog
vendored
@ -1,3 +1,77 @@
|
||||
sdrangel (7.22.8-1) unstable; urgency=medium
|
||||
|
||||
* See Github release
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Wed, 02 Jul 2025 17:00:39 +0200
|
||||
|
||||
sdrangel (7.22.7-1) unstable; urgency=medium
|
||||
|
||||
* See Github release
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 04 May 2025 17:58:14 +0200
|
||||
|
||||
sdrangel (7.22.6-1) unstable; urgency=medium
|
||||
|
||||
* See Github release
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 02 Feb 2025 18:08:11 +0100
|
||||
|
||||
sdrangel (7.22.5-1) unstable; urgency=medium
|
||||
|
||||
* Windows: upload signed releases rather than unsigned releases to Github releases page. PR #2347
|
||||
* Windows: fixed signed releases. PR #2344
|
||||
* FT8 Demod: limit upper bandwidth to 5.8 kHz. Fixes #2339
|
||||
* Stop device while changing channel set. Fixes #2332. PR #2342
|
||||
* ADSB: Update URL of OpenSkyNetwork Aircraft database. PR #2341
|
||||
* Don't stop source if being deleted. For #2315. PR #2340
|
||||
* Send DSPSignalNotification in audio mods for #2336. PR #2340
|
||||
* Radiosonde: limit precision of floating point numbers sent to SondeHub. PR #2338
|
||||
* Windows signed releases: use relative path. Increase timeout to 30 minutes. PR #2335
|
||||
* ADSB: Include adsbdemodsettings.h PR #2334
|
||||
* Use release signing certificate for Windows installer. PR #2331
|
||||
* Fix memory leak and race condition relating to DSP*Engines. Part of #2159 PR #2330
|
||||
* FreeDV: Fix memory allocation/free issues. Part of #2315. PR #2330
|
||||
* Wav Files: Add support for meta-data. PR #2328
|
||||
* DemodAnalyzer: Ensure sample rate is set in worker. Fixes #2309. PR #2328
|
||||
^ SDRplayv3: Mac: link with libsdrplay_api.so.3 rather than libsdrplay_api.so.3.15. PR #2327
|
||||
* ADS-B: Fix memory use after delete. For #1734 and part of #2315 PR #2326
|
||||
* Fixed Appveyor Docker image build
|
||||
* Fix output-artifact-directory and unzip file. PR #2323
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Thu, 05 Dec 2024 01:07:27 +0100
|
||||
|
||||
sdrangel (7.22.4-1) unstable; urgency=medium
|
||||
|
||||
* Use macos-12 for Mac x86 build. PR #2321
|
||||
* Workaround for "hdiutil: create failed - Resource busy"
|
||||
* Pager: Add alpha and numeric columns. Implements #2319. PR #2320
|
||||
* Added qtwebchannel dependecy to fix missing 3d Map and Sky Map from Windows release. PR #2316
|
||||
* Removed .deb package build from Appveyor
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Mom, 11 Nov 2024 08:42:03 +0100
|
||||
|
||||
sdrangel (7.22.3-1) unstable; urgency=medium
|
||||
|
||||
* Add deb dependencies for pipewire. PR #2314
|
||||
* Added compilation options for WebAssembly. PR #2313
|
||||
* ADS-B: Use settings keys. PR #2310
|
||||
* AIS Demod: Remove spacing around messages. PR #2310
|
||||
* Freuqency Scanner: Add multiplex mode. PR #2310
|
||||
* Build snap, MAC, Windows and Ubuntu .deb with Github actions. Various PRs
|
||||
* Server: Use Sink/MIMO signals rather than Source. Part of #2294. PR #2304
|
||||
* Updated some Python scripts to Python3. PR #2298
|
||||
* RemoteTCPSink: Does use IQ only setting for RTL0. PR #2301
|
||||
* Server: wait for set sample source/sink/MIMO to complete before loading the device settings. Fixes #2294
|
||||
* Fix spectrum peak measurement for SSB spectra. Fixes #2282. PR #2299
|
||||
* Upgrade C++ standard to c++17
|
||||
* Fixes for Android . PR #2288
|
||||
* Add qtshadertools. PR #2287
|
||||
* Add more Qt modules and set ENABLE_QT6=ON. PR #2287
|
||||
* Update Qt optional packages for 6.8 , PR #2287
|
||||
* Use Qt 6.8 for Windows build. PR #2287
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sat, 09 Nov 2024 17:30:44 +0100
|
||||
|
||||
sdrangel (7.22.2-1) unstable; urgency=medium
|
||||
|
||||
* ChirpChat: increased preamble symbols limit from 20 to 32. Fixes #2284
|
||||
@ -19,7 +93,7 @@ sdrangel (7.22.2-1) unstable; urgency=medium
|
||||
* RemoteTCPInput: Add wss protocol support. PR #2270
|
||||
* Fix DeviceAPI::deserialize. Fixes #2266. PR #2267
|
||||
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 20 Oct 2024 08:26:38 +0200
|
||||
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 20 Oct 2024 08:26:38 +0200
|
||||
|
||||
sdrangel (7.22.1-1) unstable; urgency=medium
|
||||
|
||||
|
7
debian/control
vendored
@ -42,8 +42,10 @@ Build-Depends: debhelper (>= 9),
|
||||
libopencv-imgcodecs-dev,
|
||||
libxml2-dev,
|
||||
bison,
|
||||
cmake,
|
||||
flex,
|
||||
ffmpeg,
|
||||
ninja-build,
|
||||
libfaad-dev,
|
||||
libflac-dev,
|
||||
libavcodec-dev,
|
||||
@ -63,12 +65,13 @@ Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends},
|
||||
libasound2,
|
||||
libgl1-mesa-glx,
|
||||
libgl1,
|
||||
libglx-mesa0,
|
||||
libqt5multimedia5-plugins,
|
||||
libqt5gamepad5,
|
||||
libqt5svg5,
|
||||
qtspeech5-speechd-plugin,
|
||||
pulseaudio,
|
||||
pulseaudio | pipewire-pulse,
|
||||
ffmpeg,
|
||||
gstreamer1.0-libav,
|
||||
qml-module-qtlocation,
|
||||
|
@ -40,4 +40,6 @@ if(ENABLE_USRP AND UHD_FOUND)
|
||||
add_subdirectory(usrp)
|
||||
endif()
|
||||
|
||||
add_subdirectory(metis)
|
||||
if(ENABLE_METIS)
|
||||
add_subdirectory(metis)
|
||||
endif()
|
||||
|
Before Width: | Height: | Size: 640 KiB After Width: | Height: | Size: 1.4 MiB |
BIN
doc/img/ADSBDemod_plugin_chart.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
doc/img/ADSBDemod_plugin_coverage.png
Normal file
After Width: | Height: | Size: 217 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 37 KiB |
BIN
doc/img/ADSBDemod_plugin_displaysettings_map.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
doc/img/ADSBDemod_plugin_ic.png
Normal file
After Width: | Height: | Size: 181 KiB |
Before Width: | Height: | Size: 490 KiB After Width: | Height: | Size: 844 KiB |
Before Width: | Height: | Size: 570 KiB After Width: | Height: | Size: 819 KiB |
Before Width: | Height: | Size: 372 KiB After Width: | Height: | Size: 2.3 MiB |
BIN
doc/img/ADSBDemod_plugin_radius.png
Normal file
After Width: | Height: | Size: 259 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 42 KiB |
BIN
doc/img/ADSBDemod_plugin_stats.png
Normal file
After Width: | Height: | Size: 93 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 351 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 1.6 MiB |
Before Width: | Height: | Size: 603 KiB After Width: | Height: | Size: 1.4 MiB |
BIN
doc/img/Map_plugin_aurora.png
Normal file
After Width: | Height: | Size: 859 KiB |
Before Width: | Height: | Size: 547 KiB After Width: | Height: | Size: 1.2 MiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 53 KiB |
BIN
doc/img/Map_plugin_magdec.png
Normal file
After Width: | Height: | Size: 1.6 MiB |
BIN
doc/img/Map_plugin_maidenhead_converter.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
doc/img/Map_plugin_maidenhead_grid1.png
Normal file
After Width: | Height: | Size: 426 KiB |
BIN
doc/img/Map_plugin_maidenhead_grid2.png
Normal file
After Width: | Height: | Size: 473 KiB |
BIN
doc/img/Map_plugin_pfd.png
Normal file
After Width: | Height: | Size: 745 KiB |
26
external/CMakeLists.txt
vendored
@ -11,9 +11,9 @@
|
||||
set(CODEC2_TAG "v1.0.3")
|
||||
set(CM256CC_TAG c0e92b92aca3d1d36c990b642b937c64d363c559)
|
||||
set(MBELIB_TAG fe83b32c6a60cdd7bce8cecf3c7a0b9ec87a7667)
|
||||
set(SERIALDV_TAG "v1.1.4")
|
||||
set(SERIALDV_TAG "v1.1.5")
|
||||
set(DSDCC_TAG "v1.9.5")
|
||||
set(LIMESUITE_TAG 70e3859a55d8d5353963a5318013c8454594769f)
|
||||
set(LIMESUITE_TAG b39cb61ed03d74c35a2de757d495e901acbb6404)
|
||||
set(BLADERF_TAG "2021.02")
|
||||
set(LIBIIO_TAG 826563e41b5ce9890b75506f672017de8d76d52d)
|
||||
set(AIRSPYHF_TAG "1af81c0ca18944b8c9897c3c98dc0a991815b686")
|
||||
@ -29,17 +29,11 @@ set(SOAPYSDR_SDRPLAY_TAG "soapy-sdrplay-0.2.0")
|
||||
set(SOAPYSDR_AUDIO_TAG "soapy-audio-0.1.1")
|
||||
set(SOAPYSDR_REMOTE_TAG "soapy-remote-0.5.1")
|
||||
set(AIRSPY_TAG "37c768ce9997b32e7328eb48972a7fda0a1f8554")
|
||||
set(HACKRF_TAG "v2022.09.1")
|
||||
set(HACKRF_TAG "v2024.02.1")
|
||||
set(LIBXML2_TAG "v2.10.4")
|
||||
set(UHD_TAG "v4.6.0.0")
|
||||
if (APPLE AND (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL x86_64))
|
||||
# UHD fails to load with 1.80+
|
||||
set(BOOST_TAG "1.78.0")
|
||||
set(BOOST_TAG2 "1_78_0")
|
||||
else()
|
||||
set(BOOST_TAG "1.83.0")
|
||||
set(BOOST_TAG2 "1_83_0")
|
||||
endif()
|
||||
set(UHD_TAG "v4.7.0.0")
|
||||
set(BOOST_TAG "1.86.0")
|
||||
set(BOOST_TAG2 "1_86_0")
|
||||
|
||||
# For some external project macros
|
||||
include(ExternalProject)
|
||||
@ -60,6 +54,7 @@ if (WIN32)
|
||||
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG=${SDRANGEL_BINARY_LIB_DIR}
|
||||
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE=${SDRANGEL_BINARY_LIB_DIR}
|
||||
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO=${SDRANGEL_BINARY_LIB_DIR}
|
||||
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
|
||||
)
|
||||
elseif (LINUX)
|
||||
set(COMMON_CMAKE_ARGS
|
||||
@ -426,6 +421,7 @@ if (NOT FFMPEG_FOUND AND NOT USE_PRECOMPILED_LIBS)
|
||||
if (NOT X265_FOUND OR X265_EXTERNAL)
|
||||
ExternalProject_Add(x265
|
||||
GIT_REPOSITORY https://bitbucket.org/multicoreware/x265_git.git
|
||||
GIT_TAG 4.1
|
||||
PREFIX "${EXTERNAL_BUILD_LIBRARIES}/x265"
|
||||
SOURCE_SUBDIR "source"
|
||||
CMAKE_ARGS ${COMMON_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
|
||||
@ -546,7 +542,7 @@ endif (NOT FFMPEG_FOUND AND NOT USE_PRECOMPILED_LIBS)
|
||||
if (NOT OpenCV_FOUND AND NOT USE_PRECOMPILED_LIBS AND ENABLE_CHANNELTX_MODATV)
|
||||
ExternalProject_Add(opencv
|
||||
GIT_REPOSITORY https://github.com/opencv/opencv.git
|
||||
GIT_TAG 4.5.5
|
||||
GIT_TAG 4.10.0
|
||||
DEPENDS "${FFMPEG_DEPENDS}"
|
||||
PREFIX "${EXTERNAL_BUILD_LIBRARIES}/opencv"
|
||||
CMAKE_ARGS ${COMMON_CMAKE_ARGS} -DWITH_FFMPEG=ON -DCMAKE_PREFIX_PATH=${FFMPEG_INSTALL_DIR}
|
||||
@ -864,7 +860,7 @@ if(ENABLE_CHANNELRX_REMOTETCPSINK)
|
||||
ExternalProject_Add(flac
|
||||
GIT_REPOSITORY https://github.com/xiph/flac.git
|
||||
PREFIX "${EXTERNAL_BUILD_LIBRARIES}/flac"
|
||||
CMAKE_ARGS ${COMMON_CMAKE_ARGS} -DINSTALL_MANPAGES=OFF -D=BUILD_SHARED_LIBS=ON -DWITH_FORTIFY_SOURCE=OFF -DWITH_STACK_PROTECTOR=PFF -DBUILD_PROGRAMS=OFF -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF -DWITH_OGG=OFF -DBUILD_DOCS=OFF
|
||||
CMAKE_ARGS ${COMMON_CMAKE_ARGS} -DINSTALL_MANPAGES=OFF -DBUILD_SHARED_LIBS=ON -DWITH_FORTIFY_SOURCE=OFF -DWITH_STACK_PROTECTOR=PFF -DBUILD_PROGRAMS=OFF -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF -DWITH_OGG=OFF -DBUILD_DOCS=OFF
|
||||
BUILD_BYPRODUCTS "${FLAC_LIBRARIES}"
|
||||
INSTALL_COMMAND ""
|
||||
TEST_COMMAND ""
|
||||
@ -1578,6 +1574,8 @@ if (WIN32 OR APPLE)
|
||||
-DLIBUSB_LIBRARIES=${LIBUSB_LIBRARIES}
|
||||
-DLIBUSB_INCLUDE_DIR=${LIBUSB_INCLUDE_DIR}
|
||||
${UHD_PYTHON_ARGS}
|
||||
-DPython3_FIND_FRAMEWORK=NEVER
|
||||
-DENABLE_PYTHON_API=OFF
|
||||
-DCMAKE_INSTALL_NAME_DIR=<INSTALL_DIR>/lib
|
||||
TEST_COMMAND ""
|
||||
)
|
||||
|
@ -82,7 +82,7 @@ std::string Packing::unpackcall(int x)
|
||||
|
||||
if (x <= 1002)
|
||||
{
|
||||
sprintf(tmp, "CQ %d", x - 3);
|
||||
snprintf(tmp, sizeof(tmp), "CQ %d", x - 3);
|
||||
return std::string(tmp);
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ std::string Packing::unpackcall(int x)
|
||||
int ci3 = x / 27;
|
||||
x %= 27;
|
||||
int ci4 = x;
|
||||
sprintf(tmp, "CQ %c%c%c%c", c4[ci1], c4[ci2], c4[ci3], c4[ci4]);
|
||||
snprintf(tmp, sizeof(tmp), "CQ %c%c%c%c", c4[ci1], c4[ci2], c4[ci3], c4[ci4]);
|
||||
return std::string(tmp);
|
||||
}
|
||||
|
||||
@ -193,9 +193,9 @@ std::string Packing::unpackgrid15(int ng, int ir)
|
||||
char tmp[16];
|
||||
|
||||
if (db >= 0) {
|
||||
sprintf(tmp, "%s+%02d", ir ? "R" : "", db);
|
||||
snprintf(tmp, sizeof(tmp), "%s+%02d", ir ? "R" : "", db);
|
||||
} else {
|
||||
sprintf(tmp, "%s-%02d", ir ? "R" : "", 0 - db);
|
||||
snprintf(tmp, sizeof(tmp), "%s-%02d", ir ? "R" : "", 0 - db);
|
||||
}
|
||||
|
||||
return std::string(tmp);
|
||||
@ -396,7 +396,7 @@ std::string Packing::unpack_5(int a77[], std::string& call1str, std::string& cal
|
||||
i += 3;
|
||||
int qsonb = un64(a77, i, 11);
|
||||
char report[16];
|
||||
sprintf(report, "%d%04d", rst, qsonb);
|
||||
snprintf(report, sizeof(report), "%d%04d", rst, qsonb);
|
||||
i += 11;
|
||||
// g25
|
||||
int ng = un64(a77, i, 25);
|
||||
@ -467,9 +467,9 @@ std::string Packing::unpack_0_1(int a77[], std::string& call1str, std::string& c
|
||||
char tmp[32];
|
||||
|
||||
if (r >= 0) {
|
||||
sprintf(tmp, "+%02d", r);
|
||||
snprintf(tmp, sizeof(tmp), "+%02d", r);
|
||||
} else {
|
||||
sprintf(tmp, "-%02d", -r);
|
||||
snprintf(tmp, sizeof(tmp), "-%02d", -r);
|
||||
}
|
||||
|
||||
locstr = std::string(tmp);
|
||||
@ -553,7 +553,7 @@ std::string Packing::unpack_3(int a77[], std::string& call1str, std::string& cal
|
||||
else
|
||||
{
|
||||
char tmp[32];
|
||||
sprintf(tmp, "%04d", serial);
|
||||
snprintf(tmp, sizeof(tmp), "%04d", serial);
|
||||
serialstr = std::string(tmp);
|
||||
}
|
||||
|
||||
@ -571,7 +571,7 @@ std::string Packing::unpack_3(int a77[], std::string& call1str, std::string& cal
|
||||
}
|
||||
{
|
||||
char tmp[16];
|
||||
sprintf(tmp, "%d ", rst);
|
||||
snprintf(tmp, sizeof(tmp), "%d ", rst);
|
||||
msg += std::string(tmp);
|
||||
}
|
||||
|
||||
@ -634,7 +634,7 @@ std::string Packing::unpack_0_3(int a77[], int n3, std::string& call1str, std::s
|
||||
|
||||
{
|
||||
char tmp[16];
|
||||
sprintf(tmp, "%d%c ", n_transmitters + 1, clss + 'A');
|
||||
snprintf(tmp, sizeof(tmp), "%d%c ", n_transmitters + 1, clss + 'A');
|
||||
msg += std::string(tmp);
|
||||
}
|
||||
|
||||
@ -658,9 +658,9 @@ std::string Packing::unpack(int a77[], std::string& call1, std::string& call2, s
|
||||
char tmp[64];
|
||||
|
||||
if (i3 == 0) {
|
||||
sprintf(tmp, "%d.%d", i3, n3);
|
||||
snprintf(tmp, sizeof(tmp), "%d.%d", i3, n3);
|
||||
} else {
|
||||
sprintf(tmp, "%d", i3);
|
||||
snprintf(tmp, sizeof(tmp), "%d", i3);
|
||||
}
|
||||
|
||||
type = std::string(tmp);
|
||||
@ -714,7 +714,7 @@ std::string Packing::unpack(int a77[], std::string& call1, std::string& call2, s
|
||||
}
|
||||
|
||||
call1 = "UNK";
|
||||
sprintf(tmp, "UNK i3=%d n3=%d", i3, n3);
|
||||
snprintf(tmp, sizeof(tmp), "UNK i3=%d n3=%d", i3, n3);
|
||||
return std::string(tmp);
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,6 @@ PLUGINS=$(git diff --name-only ${1}..${2} | grep plugins/ | cut -d'/' -f2,3 | so
|
||||
for plugin in $PLUGINS
|
||||
do
|
||||
FILE=$(find $BASEDIR/plugins/$plugin -name "*plugin.cpp")
|
||||
sed -i -E "s/QStringLiteral\(\"7\.(.*)\"\)/QStringLiteral\(\"7\.22\.2\"\)/" $FILE
|
||||
echo $FILE
|
||||
sed -i -E "s/QStringLiteral\(\"7\.(.*)\"\)/QStringLiteral\(\"7\.22\.7\"\)/" $FILE
|
||||
done
|
||||
|
||||
|
@ -17,10 +17,18 @@ if (NOT SERVER_MODE)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINS_DIR}")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINS_DIR}")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINS_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINS_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINS_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINS_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINS_DIR}")
|
||||
if(WIN32 AND Qt6_FOUND)
|
||||
# https://bugreports.qt.io/browse/QTBUG-124589
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINS_RUNTIME_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINS_RUNTIME_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINS_RUNTIME_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINS_RUNTIME_DIR}")
|
||||
else()
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINS_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINS_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINS_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINS_DIR}")
|
||||
endif()
|
||||
else()
|
||||
if(WIN32)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
|
||||
@ -32,10 +40,17 @@ else()
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINSSRV_DIR}")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINSSRV_DIR}")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINSSRV_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINSSRV_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINSSRV_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINSSRV_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINSSRV_DIR}")
|
||||
if(WIN32 AND Qt6_FOUND)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
|
||||
else()
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINSSRV_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINSSRV_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINSSRV_DIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINSSRV_DIR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (ENABLE_CHANNELMIMO)
|
||||
|
@ -211,6 +211,26 @@ else()
|
||||
message(STATUS "Not building wdsprx (ENABLE_CHANNELRX_WDSPRX=${ENABLE_CHANNELRX_WDSPRX} WDSP_SUPPORT=${WDSP_SUPPORT})")
|
||||
endif()
|
||||
|
||||
# need ffmpeg 3.1 that correstonds to
|
||||
# libavutil 55.27.100
|
||||
# libavcodec 57.48.101
|
||||
# libavformat 57.40.101
|
||||
find_package(FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE)
|
||||
|
||||
if (ENABLE_CHANNELRX_DEMODDATV AND FFMPEG_FOUND)
|
||||
if(WIN32)
|
||||
add_subdirectory(demoddatv)
|
||||
else()
|
||||
if(((AVUTIL_VERSION VERSION_GREATER "55.27.99") AND (AVCODEC_VERSION VERSION_GREATER "57.48.101")) OR FFMPEG_EXTERNAL OR FFMPEG_SKIP_CHECK)
|
||||
message(STATUS "Include demoddatv")
|
||||
add_subdirectory(demoddatv)
|
||||
else()
|
||||
message(STATUS "FFmpeg too old to compile demoddatv; needs at least avutil: 55.27.100, avcodec/avformat: 57.48.101")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Not building demoddatv (ENABLE_CHANNELRX_DEMODDATV=${ENABLE_CHANNELRX_DEMODDATV} FFMPEG_FOUND=${FFMPEG_FOUND})")
|
||||
endif()
|
||||
|
||||
if(NOT SERVER_MODE)
|
||||
if (ENABLE_CHANNELRX_HEATMAP)
|
||||
@ -230,25 +250,4 @@ if(NOT SERVER_MODE)
|
||||
else()
|
||||
message(STATUS "Not building demodatv (ENABLE_CHANNELRX_DEMODATV=${ENABLE_CHANNELRX_DEMODATV})")
|
||||
endif()
|
||||
|
||||
# need ffmpeg 3.1 that correstonds to
|
||||
# libavutil 55.27.100
|
||||
# libavcodec 57.48.101
|
||||
# libavformat 57.40.101
|
||||
find_package(FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE)
|
||||
|
||||
if (ENABLE_CHANNELRX_DEMODDATV AND FFMPEG_FOUND)
|
||||
if(WIN32)
|
||||
add_subdirectory(demoddatv)
|
||||
else()
|
||||
if(((AVUTIL_VERSION VERSION_GREATER "55.27.99") AND (AVCODEC_VERSION VERSION_GREATER "57.48.101")) OR FFMPEG_EXTERNAL OR FFMPEG_SKIP_CHECK)
|
||||
message(STATUS "Include demoddatv")
|
||||
add_subdirectory(demoddatv)
|
||||
else()
|
||||
message(STATUS "FFmpeg too old to compile demoddatv; needs at least avutil: 55.27.100, avcodec/avformat: 57.48.101")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Not building demoddatv (ENABLE_CHANNELRX_DEMODDATV=${ENABLE_CHANNELRX_DEMODDATV} FFMPEG_FOUND=${FFMPEG_FOUND})")
|
||||
endif()
|
||||
endif()
|
||||
|
@ -88,7 +88,7 @@ ChannelAnalyzer::~ChannelAnalyzer()
|
||||
delete m_networkManager;
|
||||
|
||||
m_deviceAPI->removeChannelSinkAPI(this);
|
||||
m_deviceAPI->removeChannelSink(this);
|
||||
m_deviceAPI->removeChannelSink(this, true);
|
||||
|
||||
if (m_basebandSink->isRunning()) {
|
||||
stop();
|
||||
@ -103,7 +103,7 @@ void ChannelAnalyzer::setDeviceAPI(DeviceAPI *deviceAPI)
|
||||
if (deviceAPI != m_deviceAPI)
|
||||
{
|
||||
m_deviceAPI->removeChannelSinkAPI(this);
|
||||
m_deviceAPI->removeChannelSink(this);
|
||||
m_deviceAPI->removeChannelSink(this, false);
|
||||
m_deviceAPI = deviceAPI;
|
||||
m_deviceAPI->addChannelSink(this);
|
||||
m_deviceAPI->addChannelSinkAPI(this);
|
||||
|
@ -27,7 +27,7 @@
|
||||
const PluginDescriptor ChannelAnalyzerPlugin::m_pluginDescriptor = {
|
||||
ChannelAnalyzer::m_channelId,
|
||||
QStringLiteral("Channel Analyzer"),
|
||||
QStringLiteral("7.22.1"),
|
||||
QStringLiteral("7.22.5"),
|
||||
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -84,7 +84,7 @@ ChannelPower::~ChannelPower()
|
||||
);
|
||||
delete m_networkManager;
|
||||
m_deviceAPI->removeChannelSinkAPI(this);
|
||||
m_deviceAPI->removeChannelSink(this);
|
||||
m_deviceAPI->removeChannelSink(this, true);
|
||||
|
||||
if (m_basebandSink->isRunning()) {
|
||||
stop();
|
||||
@ -98,7 +98,7 @@ void ChannelPower::setDeviceAPI(DeviceAPI *deviceAPI)
|
||||
if (deviceAPI != m_deviceAPI)
|
||||
{
|
||||
m_deviceAPI->removeChannelSinkAPI(this);
|
||||
m_deviceAPI->removeChannelSink(this);
|
||||
m_deviceAPI->removeChannelSink(this, false);
|
||||
m_deviceAPI = deviceAPI;
|
||||
m_deviceAPI->addChannelSink(this);
|
||||
m_deviceAPI->addChannelSinkAPI(this);
|
||||
|
@ -29,7 +29,7 @@
|
||||
const PluginDescriptor ChannelPowerPlugin::m_pluginDescriptor = {
|
||||
ChannelPower::m_channelId,
|
||||
QStringLiteral("Channel Power"),
|
||||
QStringLiteral("7.22.1"),
|
||||
QStringLiteral("7.22.5"),
|
||||
QStringLiteral("(c) Jon Beniston, M7RCE"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
@ -28,7 +28,6 @@ set(adsb_HEADERS
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
|
||||
${Boost_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
if(NOT SERVER_MODE)
|
||||
@ -47,6 +46,7 @@ if(NOT SERVER_MODE)
|
||||
adsbdemodicons.qrc
|
||||
airlinelogos.qrc
|
||||
flags.qrc
|
||||
sideviews.qrc
|
||||
)
|
||||
set(adsb_HEADERS
|
||||
${adsb_HEADERS}
|
||||
@ -60,7 +60,7 @@ if(NOT SERVER_MODE)
|
||||
)
|
||||
|
||||
set(TARGET_NAME ${PLUGINS_PREFIX}demodadsb)
|
||||
set(TARGET_LIB Qt::Widgets Qt::Quick Qt::QuickWidgets Qt::Positioning)
|
||||
set(TARGET_LIB Qt::Widgets Qt::Quick Qt::QuickWidgets Qt::Positioning Qt::Charts)
|
||||
if(Qt${QT_DEFAULT_MAJOR_VERSION}Location_FOUND)
|
||||
list(APPEND TARGET_LIB Qt::Location)
|
||||
endif()
|
||||
@ -86,12 +86,7 @@ if(NOT BUILD_SHARED_LIBS)
|
||||
set_property(GLOBAL APPEND PROPERTY STATIC_PLUGINS_PROPERTY ${TARGET_NAME})
|
||||
endif()
|
||||
|
||||
if (NOT WIN32)
|
||||
link_directories(${Boost_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE
|
||||
Boost::disable_autolinking
|
||||
Qt::Core
|
||||
${TARGET_LIB}
|
||||
sdrbase
|
||||
|
@ -17,10 +17,6 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define BOOST_CHRONO_HEADER_ONLY
|
||||
#include <boost/chrono/chrono.hpp>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <complex.h>
|
||||
|
||||
#include <QTime>
|
||||
@ -49,6 +45,7 @@
|
||||
|
||||
MESSAGE_CLASS_DEFINITION(ADSBDemod::MsgConfigureADSBDemod, Message)
|
||||
MESSAGE_CLASS_DEFINITION(ADSBDemod::MsgAircraftReport, Message)
|
||||
MESSAGE_CLASS_DEFINITION(ADSBDemod::MsgResetStats, Message)
|
||||
|
||||
const char* const ADSBDemod::m_channelIdURI = "sdrangel.channel.adsbdemod";
|
||||
const char* const ADSBDemod::m_channelId = "ADSBDemod";
|
||||
@ -71,7 +68,7 @@ ADSBDemod::ADSBDemod(DeviceAPI *devieAPI) :
|
||||
m_worker = new ADSBDemodWorker();
|
||||
m_basebandSink->setMessageQueueToWorker(m_worker->getInputMessageQueue());
|
||||
|
||||
applySettings(m_settings, true);
|
||||
applySettings(m_settings, QStringList(), true);
|
||||
|
||||
m_deviceAPI->addChannelSink(this);
|
||||
m_deviceAPI->addChannelSinkAPI(this);
|
||||
@ -104,9 +101,9 @@ ADSBDemod::~ADSBDemod()
|
||||
);
|
||||
delete m_networkManager;
|
||||
m_deviceAPI->removeChannelSinkAPI(this);
|
||||
m_deviceAPI->removeChannelSink(this);
|
||||
m_deviceAPI->removeChannelSink(this, true);
|
||||
delete m_basebandSink; // This results in a call to ADSBDemod::stop(), so need to delete before worker and thread
|
||||
delete m_worker;
|
||||
delete m_basebandSink;
|
||||
delete m_thread;
|
||||
}
|
||||
|
||||
@ -115,7 +112,7 @@ void ADSBDemod::setDeviceAPI(DeviceAPI *deviceAPI)
|
||||
if (deviceAPI != m_deviceAPI)
|
||||
{
|
||||
m_deviceAPI->removeChannelSinkAPI(this);
|
||||
m_deviceAPI->removeChannelSink(this);
|
||||
m_deviceAPI->removeChannelSink(this, false);
|
||||
m_deviceAPI = deviceAPI;
|
||||
m_deviceAPI->addChannelSink(this);
|
||||
m_deviceAPI->addChannelSinkAPI(this);
|
||||
@ -147,7 +144,7 @@ void ADSBDemod::start()
|
||||
m_basebandSink->startWork();
|
||||
m_thread->start();
|
||||
|
||||
ADSBDemodWorker::MsgConfigureADSBDemodWorker *msg = ADSBDemodWorker::MsgConfigureADSBDemodWorker::create(m_settings, true);
|
||||
ADSBDemodWorker::MsgConfigureADSBDemodWorker *msg = ADSBDemodWorker::MsgConfigureADSBDemodWorker::create(m_settings, QStringList(), true);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
|
||||
@ -169,7 +166,7 @@ bool ADSBDemod::handleMessage(const Message& cmd)
|
||||
MsgConfigureADSBDemod& cfg = (MsgConfigureADSBDemod&) cmd;
|
||||
qDebug() << "ADSBDemod::handleMessage: MsgConfigureADSBDemod";
|
||||
|
||||
applySettings(cfg.getSettings(), cfg.getForce());
|
||||
applySettings(cfg.getSettings(), cfg.getSettingsKeys(), cfg.getForce());
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -194,118 +191,25 @@ bool ADSBDemod::handleMessage(const Message& cmd)
|
||||
m_aircraftReport = msg.getReport();
|
||||
return true;
|
||||
}
|
||||
else if (MsgResetStats::match(cmd))
|
||||
{
|
||||
MsgResetStats& msg = (MsgResetStats&) cmd;
|
||||
MsgResetStats* rep = new MsgResetStats(msg);
|
||||
m_basebandSink->getInputMessageQueue()->push(rep);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ADSBDemod::applySettings(const ADSBDemodSettings& settings, bool force)
|
||||
void ADSBDemod::applySettings(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force)
|
||||
{
|
||||
qDebug() << "ADSBDemod::applySettings:"
|
||||
<< " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset
|
||||
<< " m_rfBandwidth: " << settings.m_rfBandwidth
|
||||
<< " m_streamIndex: " << settings.m_streamIndex
|
||||
<< " m_useReverseAPI: " << settings.m_useReverseAPI
|
||||
<< " m_reverseAPIAddress: " << settings.m_reverseAPIAddress
|
||||
<< " m_reverseAPIPort: " << settings.m_reverseAPIPort
|
||||
<< " m_reverseAPIDeviceIndex: " << settings.m_reverseAPIDeviceIndex
|
||||
<< " m_reverseAPIChannelIndex: " << settings.m_reverseAPIChannelIndex
|
||||
<< settings.getDebugString(settingsKeys, force)
|
||||
<< " force: " << force;
|
||||
|
||||
QList<QString> reverseAPIKeys;
|
||||
|
||||
if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force) {
|
||||
reverseAPIKeys.append("inputFrequencyOffset");
|
||||
}
|
||||
if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force) {
|
||||
reverseAPIKeys.append("rfBandwidth");
|
||||
}
|
||||
if ((settings.m_correlationThreshold != m_settings.m_correlationThreshold) || force) {
|
||||
reverseAPIKeys.append("correlationThreshold");
|
||||
}
|
||||
if ((settings.m_samplesPerBit != m_settings.m_samplesPerBit) || force) {
|
||||
reverseAPIKeys.append("samplesPerBit");
|
||||
}
|
||||
if ((settings.m_correlateFullPreamble != m_settings.m_correlateFullPreamble) || force) {
|
||||
reverseAPIKeys.append("correlateFullPreamble");
|
||||
}
|
||||
if ((settings.m_demodModeS != m_settings.m_demodModeS) || force) {
|
||||
reverseAPIKeys.append("demodModeS");
|
||||
}
|
||||
if ((settings.m_interpolatorPhaseSteps != m_settings.m_interpolatorPhaseSteps) || force) {
|
||||
reverseAPIKeys.append("interpolatorPhaseSteps");
|
||||
}
|
||||
if ((settings.m_interpolatorTapsPerPhase != m_settings.m_interpolatorTapsPerPhase) || force) {
|
||||
reverseAPIKeys.append("interpolatorTapsPerPhase");
|
||||
}
|
||||
if ((settings.m_removeTimeout != m_settings.m_removeTimeout) || force) {
|
||||
reverseAPIKeys.append("removeTimeout");
|
||||
}
|
||||
if ((settings.m_feedEnabled != m_settings.m_feedEnabled) || force) {
|
||||
reverseAPIKeys.append("feedEnabled");
|
||||
}
|
||||
if ((settings.m_exportClientEnabled != m_settings.m_exportClientEnabled) || force) {
|
||||
reverseAPIKeys.append("exportClientEnabled");
|
||||
}
|
||||
if ((settings.m_exportClientHost != m_settings.m_exportClientHost) || force) {
|
||||
reverseAPIKeys.append("exportClientHost");
|
||||
}
|
||||
if ((settings.m_exportClientPort != m_settings.m_exportClientPort) || force) {
|
||||
reverseAPIKeys.append("exportClientPort");
|
||||
}
|
||||
if ((settings.m_exportClientFormat != m_settings.m_exportClientFormat) || force) {
|
||||
reverseAPIKeys.append("exportClientFormat");
|
||||
}
|
||||
if ((settings.m_exportServerEnabled != m_settings.m_exportServerEnabled) || force) {
|
||||
reverseAPIKeys.append("exportServerEnabled");
|
||||
}
|
||||
if ((settings.m_exportServerPort != m_settings.m_exportServerPort) || force) {
|
||||
reverseAPIKeys.append("exportServerPort");
|
||||
}
|
||||
if ((settings.m_importEnabled != m_settings.m_importEnabled) || force) {
|
||||
reverseAPIKeys.append("importEnabled");
|
||||
}
|
||||
if ((settings.m_importHost != m_settings.m_importHost) || force) {
|
||||
reverseAPIKeys.append("importHost");
|
||||
}
|
||||
if ((settings.m_importUsername != m_settings.m_importUsername) || force) {
|
||||
reverseAPIKeys.append("importUsername");
|
||||
}
|
||||
if ((settings.m_importPassword != m_settings.m_importPassword) || force) {
|
||||
reverseAPIKeys.append("importPassword");
|
||||
}
|
||||
if ((settings.m_importParameters != m_settings.m_importParameters) || force) {
|
||||
reverseAPIKeys.append("importParameters");
|
||||
}
|
||||
if ((settings.m_importPeriod != m_settings.m_importPeriod) || force) {
|
||||
reverseAPIKeys.append("importPeriod");
|
||||
}
|
||||
if ((settings.m_importMinLatitude != m_settings.m_importMinLatitude) || force) {
|
||||
reverseAPIKeys.append("importMinLatitude");
|
||||
}
|
||||
if ((settings.m_importMaxLatitude != m_settings.m_importMaxLatitude) || force) {
|
||||
reverseAPIKeys.append("importMaxLatitude");
|
||||
}
|
||||
if ((settings.m_importMinLongitude != m_settings.m_importMinLongitude) || force) {
|
||||
reverseAPIKeys.append("importMinLongitude");
|
||||
}
|
||||
if ((settings.m_importMaxLongitude != m_settings.m_importMaxLongitude) || force) {
|
||||
reverseAPIKeys.append("importMaxLongitude");
|
||||
}
|
||||
if ((settings.m_logFilename != m_settings.m_logFilename) || force) {
|
||||
reverseAPIKeys.append("logFilename");
|
||||
}
|
||||
if ((settings.m_logEnabled != m_settings.m_logEnabled) || force) {
|
||||
reverseAPIKeys.append("logEnabled");
|
||||
}
|
||||
if ((settings.m_title != m_settings.m_title) || force) {
|
||||
reverseAPIKeys.append("title");
|
||||
}
|
||||
if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force) {
|
||||
reverseAPIKeys.append("rfBandwidth");
|
||||
}
|
||||
|
||||
if (m_settings.m_streamIndex != settings.m_streamIndex)
|
||||
{
|
||||
if (m_deviceAPI->getSampleMIMO()) // change of stream is possible for MIMO devices only
|
||||
@ -317,38 +221,40 @@ void ADSBDemod::applySettings(const ADSBDemodSettings& settings, bool force)
|
||||
m_settings.m_streamIndex = settings.m_streamIndex; // make sure ChannelAPI::getStreamIndex() is consistent
|
||||
emit streamIndexChanged(settings.m_streamIndex);
|
||||
}
|
||||
|
||||
reverseAPIKeys.append("streamIndex");
|
||||
}
|
||||
|
||||
ADSBDemodBaseband::MsgConfigureADSBDemodBaseband *msg = ADSBDemodBaseband::MsgConfigureADSBDemodBaseband::create(settings, force);
|
||||
ADSBDemodBaseband::MsgConfigureADSBDemodBaseband *msg = ADSBDemodBaseband::MsgConfigureADSBDemodBaseband::create(settings, settingsKeys, force);
|
||||
m_basebandSink->getInputMessageQueue()->push(msg);
|
||||
|
||||
ADSBDemodWorker::MsgConfigureADSBDemodWorker *workerMsg = ADSBDemodWorker::MsgConfigureADSBDemodWorker::create(settings, force);
|
||||
ADSBDemodWorker::MsgConfigureADSBDemodWorker *workerMsg = ADSBDemodWorker::MsgConfigureADSBDemodWorker::create(settings, settingsKeys, force);
|
||||
m_worker->getInputMessageQueue()->push(workerMsg);
|
||||
|
||||
if (settings.m_useReverseAPI)
|
||||
{
|
||||
bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) ||
|
||||
(m_settings.m_reverseAPIAddress != settings.m_reverseAPIAddress) ||
|
||||
(m_settings.m_reverseAPIPort != settings.m_reverseAPIPort) ||
|
||||
(m_settings.m_reverseAPIDeviceIndex != settings.m_reverseAPIDeviceIndex) ||
|
||||
(m_settings.m_reverseAPIChannelIndex != settings.m_reverseAPIChannelIndex);
|
||||
webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force);
|
||||
bool fullUpdate = (settingsKeys.contains("useReverseAPI") && settings.m_useReverseAPI) ||
|
||||
settingsKeys.contains("reverseAPIAddress") ||
|
||||
settingsKeys.contains("reverseAPIPort") ||
|
||||
settingsKeys.contains("reverseAPIDeviceIndex") ||
|
||||
settingsKeys.contains("reverseAPIChannelIndex");
|
||||
webapiReverseSendSettings(settingsKeys, settings, fullUpdate || force);
|
||||
}
|
||||
|
||||
m_settings = settings;
|
||||
if (force) {
|
||||
m_settings = settings;
|
||||
} else {
|
||||
m_settings.applySettings(settingsKeys, settings);
|
||||
}
|
||||
}
|
||||
|
||||
void ADSBDemod::setCenterFrequency(qint64 frequency)
|
||||
{
|
||||
ADSBDemodSettings settings = m_settings;
|
||||
settings.m_inputFrequencyOffset = frequency;
|
||||
applySettings(settings);
|
||||
applySettings(settings, {"inputFrequencyOffset"}, false);
|
||||
|
||||
if (m_guiMessageQueue) // forward to GUI if any
|
||||
{
|
||||
MsgConfigureADSBDemod *msgToGUI = MsgConfigureADSBDemod::create(settings, false);
|
||||
MsgConfigureADSBDemod *msgToGUI = MsgConfigureADSBDemod::create(settings, {"inputFrequencyOffset"}, false);
|
||||
m_guiMessageQueue->push(msgToGUI);
|
||||
}
|
||||
}
|
||||
@ -368,7 +274,7 @@ bool ADSBDemod::deserialize(const QByteArray& data)
|
||||
success = false;
|
||||
}
|
||||
|
||||
MsgConfigureADSBDemod *msg = MsgConfigureADSBDemod::create(m_settings, true);
|
||||
MsgConfigureADSBDemod *msg = MsgConfigureADSBDemod::create(m_settings, QStringList(), true);
|
||||
m_inputMessageQueue.push(msg);
|
||||
|
||||
return success;
|
||||
@ -404,12 +310,12 @@ int ADSBDemod::webapiSettingsPutPatch(
|
||||
ADSBDemodSettings settings = m_settings;
|
||||
webapiUpdateChannelSettings(settings, channelSettingsKeys, response);
|
||||
|
||||
MsgConfigureADSBDemod *msg = MsgConfigureADSBDemod::create(settings, force);
|
||||
MsgConfigureADSBDemod *msg = MsgConfigureADSBDemod::create(settings, channelSettingsKeys, force);
|
||||
m_inputMessageQueue.push(msg);
|
||||
|
||||
if (m_guiMessageQueue) // forward to GUI if any
|
||||
{
|
||||
MsgConfigureADSBDemod *msgToGUI = MsgConfigureADSBDemod::create(settings, force);
|
||||
MsgConfigureADSBDemod *msgToGUI = MsgConfigureADSBDemod::create(settings, channelSettingsKeys, force);
|
||||
m_guiMessageQueue->push(msgToGUI);
|
||||
}
|
||||
|
||||
@ -435,9 +341,6 @@ void ADSBDemod::webapiUpdateChannelSettings(
|
||||
if (channelSettingsKeys.contains("samplesPerBit")) {
|
||||
settings.m_samplesPerBit = response.getAdsbDemodSettings()->getSamplesPerBit();
|
||||
}
|
||||
if (channelSettingsKeys.contains("correlateFullPreamble")) {
|
||||
settings.m_correlateFullPreamble = response.getAdsbDemodSettings()->getCorrelateFullPreamble() != 0;
|
||||
}
|
||||
if (channelSettingsKeys.contains("demodModeS")) {
|
||||
settings.m_demodModeS = response.getAdsbDemodSettings()->getDemodModeS() != 0;
|
||||
}
|
||||
@ -556,7 +459,6 @@ void ADSBDemod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& res
|
||||
response.getAdsbDemodSettings()->setRfBandwidth(settings.m_rfBandwidth);
|
||||
response.getAdsbDemodSettings()->setCorrelationThreshold(settings.m_correlationThreshold);
|
||||
response.getAdsbDemodSettings()->setSamplesPerBit(settings.m_samplesPerBit);
|
||||
response.getAdsbDemodSettings()->setCorrelateFullPreamble(settings.m_correlateFullPreamble ? 1 : 0);
|
||||
response.getAdsbDemodSettings()->setDemodModeS(settings.m_demodModeS ? 1 : 0);
|
||||
response.getAdsbDemodSettings()->setInterpolatorPhaseSteps(settings.m_interpolatorPhaseSteps);
|
||||
response.getAdsbDemodSettings()->setInterpolatorTapsPerPhase(settings.m_interpolatorTapsPerPhase);
|
||||
@ -661,7 +563,7 @@ void ADSBDemod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& respons
|
||||
}
|
||||
}
|
||||
|
||||
void ADSBDemod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const ADSBDemodSettings& settings, bool force)
|
||||
void ADSBDemod::webapiReverseSendSettings(const QList<QString>& channelSettingsKeys, const ADSBDemodSettings& settings, bool force)
|
||||
{
|
||||
SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
|
||||
swgChannelSettings->setDirection(0); // single sink (Rx)
|
||||
@ -685,9 +587,6 @@ void ADSBDemod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, c
|
||||
if (channelSettingsKeys.contains("samplesPerBit") || force) {
|
||||
swgADSBDemodSettings->setSamplesPerBit(settings.m_samplesPerBit);
|
||||
}
|
||||
if (channelSettingsKeys.contains("correlateFullPreamble") || force) {
|
||||
swgADSBDemodSettings->setCorrelateFullPreamble(settings.m_correlateFullPreamble ? 1 : 0);
|
||||
}
|
||||
if (channelSettingsKeys.contains("demodModeS") || force) {
|
||||
swgADSBDemodSettings->setDemodModeS(settings.m_demodModeS ? 1 : 0);
|
||||
}
|
||||
|
@ -20,8 +20,6 @@
|
||||
#ifndef INCLUDE_ADSBDEMOD_H
|
||||
#define INCLUDE_ADSBDEMOD_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QNetworkRequest>
|
||||
|
||||
#include "dsp/basebandsamplesink.h"
|
||||
@ -44,20 +42,23 @@ public:
|
||||
|
||||
public:
|
||||
const ADSBDemodSettings& getSettings() const { return m_settings; }
|
||||
const QStringList& getSettingsKeys() const { return m_settingsKeys; }
|
||||
bool getForce() const { return m_force; }
|
||||
|
||||
static MsgConfigureADSBDemod* create(const ADSBDemodSettings& settings, bool force)
|
||||
static MsgConfigureADSBDemod* create(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force)
|
||||
{
|
||||
return new MsgConfigureADSBDemod(settings, force);
|
||||
return new MsgConfigureADSBDemod(settings, settingsKeys, force);
|
||||
}
|
||||
|
||||
private:
|
||||
ADSBDemodSettings m_settings;
|
||||
QStringList m_settingsKeys;
|
||||
bool m_force;
|
||||
|
||||
MsgConfigureADSBDemod(const ADSBDemodSettings& settings, bool force) :
|
||||
MsgConfigureADSBDemod(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force) :
|
||||
Message(),
|
||||
m_settings(settings),
|
||||
m_settingsKeys(settingsKeys),
|
||||
m_force(force)
|
||||
{ }
|
||||
};
|
||||
@ -91,6 +92,21 @@ public:
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgResetStats : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
static MsgResetStats* create()
|
||||
{
|
||||
return new MsgResetStats();
|
||||
}
|
||||
|
||||
private:
|
||||
MsgResetStats() :
|
||||
Message()
|
||||
{ }
|
||||
};
|
||||
|
||||
ADSBDemod(DeviceAPI *deviceAPI);
|
||||
virtual ~ADSBDemod();
|
||||
virtual void destroy() { delete this; }
|
||||
@ -184,9 +200,9 @@ private:
|
||||
QNetworkRequest m_networkRequest;
|
||||
|
||||
virtual bool handleMessage(const Message& cmd); //!< Processing of a message. Returns true if message has actually been processed
|
||||
void applySettings(const ADSBDemodSettings& settings, bool force = false);
|
||||
void applySettings(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force = false);
|
||||
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response);
|
||||
void webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const ADSBDemodSettings& settings, bool force);
|
||||
void webapiReverseSendSettings(const QList<QString>& channelSettingsKeys, const ADSBDemodSettings& settings, bool force);
|
||||
|
||||
private slots:
|
||||
void networkManagerFinished(QNetworkReply *reply);
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "dsp/downchannelizer.h"
|
||||
|
||||
#include "adsbdemodbaseband.h"
|
||||
#include "adsbdemod.h"
|
||||
#include "adsb.h"
|
||||
|
||||
MESSAGE_CLASS_DEFINITION(ADSBDemodBaseband::MsgConfigureADSBDemodBaseband, Message)
|
||||
@ -117,7 +118,7 @@ bool ADSBDemodBaseband::handleMessage(const Message& cmd)
|
||||
MsgConfigureADSBDemodBaseband& cfg = (MsgConfigureADSBDemodBaseband&) cmd;
|
||||
qDebug() << "ADSBDemodBaseband::handleMessage: MsgConfigureADSBDemodBaseband";
|
||||
|
||||
applySettings(cfg.getSettings(), cfg.getForce());
|
||||
applySettings(cfg.getSettings(), cfg.getSettingsKeys(), cfg.getForce());
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -132,25 +133,35 @@ bool ADSBDemodBaseband::handleMessage(const Message& cmd)
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (ADSBDemod::MsgResetStats::match(cmd))
|
||||
{
|
||||
m_sink.resetStats();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ADSBDemodBaseband::applySettings(const ADSBDemodSettings& settings, bool force)
|
||||
void ADSBDemodBaseband::applySettings(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force)
|
||||
{
|
||||
if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset)
|
||||
|| (settings.m_samplesPerBit != m_settings.m_samplesPerBit) || force)
|
||||
if ( (settingsKeys.contains("inputFrequencyOffset") && (settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset))
|
||||
|| (settingsKeys.contains("samplesPerBit") && (settings.m_samplesPerBit != m_settings.m_samplesPerBit))
|
||||
|| force)
|
||||
{
|
||||
int requestedRate = ADS_B_BITS_PER_SECOND * settings.m_samplesPerBit;
|
||||
m_channelizer->setChannelization(requestedRate, settings.m_inputFrequencyOffset);
|
||||
m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
|
||||
}
|
||||
|
||||
m_sink.applySettings(settings, force);
|
||||
m_sink.applySettings(settings, settingsKeys, force);
|
||||
|
||||
m_settings = settings;
|
||||
if (force) {
|
||||
m_settings = settings;
|
||||
} else {
|
||||
m_settings.applySettings(settingsKeys, settings);
|
||||
}
|
||||
}
|
||||
|
||||
int ADSBDemodBaseband::getChannelSampleRate() const
|
||||
|
@ -39,20 +39,23 @@ public:
|
||||
|
||||
public:
|
||||
const ADSBDemodSettings& getSettings() const { return m_settings; }
|
||||
const QStringList& getSettingsKeys() const { return m_settingsKeys; }
|
||||
bool getForce() const { return m_force; }
|
||||
|
||||
static MsgConfigureADSBDemodBaseband* create(const ADSBDemodSettings& settings, bool force)
|
||||
static MsgConfigureADSBDemodBaseband* create(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force)
|
||||
{
|
||||
return new MsgConfigureADSBDemodBaseband(settings, force);
|
||||
return new MsgConfigureADSBDemodBaseband(settings, settingsKeys, force);
|
||||
}
|
||||
|
||||
private:
|
||||
ADSBDemodSettings m_settings;
|
||||
QStringList m_settingsKeys;
|
||||
bool m_force;
|
||||
|
||||
MsgConfigureADSBDemodBaseband(const ADSBDemodSettings& settings, bool force) :
|
||||
MsgConfigureADSBDemodBaseband(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force) :
|
||||
Message(),
|
||||
m_settings(settings),
|
||||
m_settingsKeys(settingsKeys),
|
||||
m_force(force)
|
||||
{ }
|
||||
};
|
||||
@ -80,7 +83,7 @@ private:
|
||||
QRecursiveMutex m_mutex;
|
||||
|
||||
bool handleMessage(const Message& cmd);
|
||||
void applySettings(const ADSBDemodSettings& settings, bool force = false);
|
||||
void applySettings(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force = false);
|
||||
|
||||
private slots:
|
||||
void handleInputMessages();
|
||||
|
@ -50,7 +50,6 @@ ADSBDemodDisplayDialog::ADSBDemodDisplayDialog(ADSBDemodSettings *settings, QWid
|
||||
ui->airportSize->setCurrentIndex((int)settings->m_airportMinimumSize);
|
||||
ui->heliports->setChecked(settings->m_displayHeliports);
|
||||
ui->units->setCurrentIndex((int)settings->m_siUnits);
|
||||
ui->displayStats->setChecked(settings->m_displayDemodStats);
|
||||
ui->autoResizeTableColumns->setChecked(settings->m_autoResizeTableColumns);
|
||||
ui->aviationstackAPIKey->setText(settings->m_aviationstackAPIKey);
|
||||
ui->checkWXAPIKey->setText(settings->m_checkWXAPIKey);
|
||||
@ -67,12 +66,17 @@ ADSBDemodDisplayDialog::ADSBDemodDisplayDialog(ADSBDemodSettings *settings, QWid
|
||||
ui->mapProvider->setCurrentText(settings->m_mapProvider);
|
||||
}
|
||||
ui->mapType->setCurrentIndex((int)settings->m_mapType);
|
||||
ui->maptilerAPIKey->setText(m_settings->m_maptilerAPIKey);
|
||||
ui->navAids->setChecked(settings->m_displayNavAids);
|
||||
ui->atcCallsigns->setChecked(settings->m_atcCallsigns);
|
||||
ui->photos->setChecked(settings->m_displayPhotos);
|
||||
ui->verboseModelMatching->setChecked(settings->m_verboseModelMatching);
|
||||
ui->airfieldElevation->setValue(settings->m_airfieldElevation);
|
||||
ui->favourLivery->setChecked(settings->m_favourLivery);
|
||||
ui->transitionAltitude->setValue(settings->m_transitionAlt);
|
||||
for (auto i = ADSBDemodSettings::m_palettes.cbegin(), end = ADSBDemodSettings::m_palettes.cend(); i != end; ++i) {
|
||||
ui->flightPathPalette->addItem(i.key());
|
||||
}
|
||||
ui->flightPathPalette->setCurrentText(settings->m_flightPathPaletteName);
|
||||
}
|
||||
|
||||
ADSBDemodDisplayDialog::~ADSBDemodDisplayDialog()
|
||||
@ -82,35 +86,130 @@ ADSBDemodDisplayDialog::~ADSBDemodDisplayDialog()
|
||||
|
||||
void ADSBDemodDisplayDialog::accept()
|
||||
{
|
||||
m_settings->m_removeTimeout = ui->timeout->value();
|
||||
m_settings->m_aircraftMinZoom = ui->aircraftMinZoom->value();
|
||||
m_settings->m_airportRange = ui->airportRange->value();
|
||||
m_settings->m_airportMinimumSize = (ADSBDemodSettings::AirportType)ui->airportSize->currentIndex();
|
||||
m_settings->m_displayHeliports = ui->heliports->isChecked();
|
||||
m_settings->m_siUnits = ui->units->currentIndex() == 0 ? false : true;
|
||||
m_settings->m_displayDemodStats = ui->displayStats->isChecked();
|
||||
m_settings->m_autoResizeTableColumns = ui->autoResizeTableColumns->isChecked();
|
||||
m_settings->m_aviationstackAPIKey = ui->aviationstackAPIKey->text();
|
||||
m_settings->m_checkWXAPIKey = ui->checkWXAPIKey->text();
|
||||
m_settings->m_airspaces = QStringList();
|
||||
if (m_settings->m_removeTimeout != ui->timeout->value())
|
||||
{
|
||||
m_settings->m_removeTimeout = ui->timeout->value();
|
||||
m_settingsKeys.append("removeTimeout");
|
||||
}
|
||||
if (m_settings->m_aircraftMinZoom != ui->aircraftMinZoom->value())
|
||||
{
|
||||
m_settings->m_aircraftMinZoom = ui->aircraftMinZoom->value();
|
||||
m_settingsKeys.append("aircraftMinZoom");
|
||||
}
|
||||
if (m_settings->m_airportRange != ui->airportRange->value())
|
||||
{
|
||||
m_settings->m_airportRange = ui->airportRange->value();
|
||||
m_settingsKeys.append("airportRange");
|
||||
}
|
||||
if (m_settings->m_airportMinimumSize != (ADSBDemodSettings::AirportType)ui->airportSize->currentIndex())
|
||||
{
|
||||
m_settings->m_airportMinimumSize = (ADSBDemodSettings::AirportType)ui->airportSize->currentIndex();
|
||||
m_settingsKeys.append("airportMinimumSize");
|
||||
}
|
||||
if (m_settings->m_displayHeliports != ui->heliports->isChecked())
|
||||
{
|
||||
m_settings->m_displayHeliports = ui->heliports->isChecked();
|
||||
m_settingsKeys.append("displayHeliports");
|
||||
}
|
||||
if (m_settings->m_siUnits != (ui->units->currentIndex() == 0 ? false : true))
|
||||
{
|
||||
m_settings->m_siUnits = ui->units->currentIndex() == 0 ? false : true;
|
||||
m_settingsKeys.append("siUnits");
|
||||
}
|
||||
if (m_settings->m_autoResizeTableColumns != ui->autoResizeTableColumns->isChecked())
|
||||
{
|
||||
m_settings->m_autoResizeTableColumns = ui->autoResizeTableColumns->isChecked();
|
||||
m_settingsKeys.append("autoResizeTableColumns");
|
||||
}
|
||||
if (m_settings->m_aviationstackAPIKey != ui->aviationstackAPIKey->text())
|
||||
{
|
||||
m_settings->m_aviationstackAPIKey = ui->aviationstackAPIKey->text();
|
||||
m_settingsKeys.append("aviationstackAPIKey");
|
||||
}
|
||||
if (m_settings->m_checkWXAPIKey != ui->checkWXAPIKey->text())
|
||||
{
|
||||
m_settings->m_checkWXAPIKey = ui->checkWXAPIKey->text();
|
||||
m_settingsKeys.append("checkWXAPIKey");
|
||||
}
|
||||
QStringList airspaces;
|
||||
for (int i = 0; i < ui->airspaces->count(); i++)
|
||||
{
|
||||
QListWidgetItem *item = ui->airspaces->item(i);
|
||||
if (item->checkState() == Qt::Checked) {
|
||||
m_settings->m_airspaces.append(item->text());
|
||||
airspaces.append(item->text());
|
||||
}
|
||||
}
|
||||
m_settings->m_airspaceRange = ui->airspaceRange->value();
|
||||
m_settings->m_mapProvider = ui->mapProvider->currentText();
|
||||
m_settings->m_mapType = (ADSBDemodSettings::MapType)ui->mapType->currentIndex();
|
||||
m_settings->m_displayNavAids = ui->navAids->isChecked();
|
||||
m_settings->m_atcCallsigns = ui->atcCallsigns->isChecked();
|
||||
m_settings->m_displayPhotos = ui->photos->isChecked();
|
||||
m_settings->m_verboseModelMatching = ui->verboseModelMatching->isChecked();
|
||||
m_settings->m_airfieldElevation = ui->airfieldElevation->value();
|
||||
m_settings->m_transitionAlt = ui->transitionAltitude->value();
|
||||
m_settings->m_tableFontName = m_fontName;
|
||||
m_settings->m_tableFontSize = m_fontSize;
|
||||
if (m_settings->m_airspaces != airspaces)
|
||||
{
|
||||
m_settings->m_airspaces = airspaces;
|
||||
m_settingsKeys.append("airspaces");
|
||||
}
|
||||
if (m_settings->m_airspaceRange != ui->airspaceRange->value())
|
||||
{
|
||||
m_settings->m_airspaceRange = ui->airspaceRange->value();
|
||||
m_settingsKeys.append("airspaceRange");
|
||||
}
|
||||
if (m_settings->m_mapProvider != ui->mapProvider->currentText())
|
||||
{
|
||||
m_settings->m_mapProvider = ui->mapProvider->currentText();
|
||||
m_settingsKeys.append("mapProvider");
|
||||
}
|
||||
if (m_settings->m_mapType != (ADSBDemodSettings::MapType)ui->mapType->currentIndex())
|
||||
{
|
||||
m_settings->m_mapType = (ADSBDemodSettings::MapType)ui->mapType->currentIndex();
|
||||
m_settingsKeys.append("mapType");
|
||||
}
|
||||
if (m_settings->m_maptilerAPIKey != ui->maptilerAPIKey->text())
|
||||
{
|
||||
m_settings->m_maptilerAPIKey = ui->maptilerAPIKey->text();
|
||||
m_settingsKeys.append("maptilerAPIKey");
|
||||
}
|
||||
if (m_settings->m_displayNavAids != ui->navAids->isChecked())
|
||||
{
|
||||
m_settings->m_displayNavAids = ui->navAids->isChecked();
|
||||
m_settingsKeys.append("displayNavAids");
|
||||
}
|
||||
if (m_settings->m_atcCallsigns != ui->atcCallsigns->isChecked())
|
||||
{
|
||||
m_settings->m_atcCallsigns = ui->atcCallsigns->isChecked();
|
||||
m_settingsKeys.append("atcCallsigns");
|
||||
}
|
||||
if (m_settings->m_displayPhotos != ui->photos->isChecked())
|
||||
{
|
||||
m_settings->m_displayPhotos = ui->photos->isChecked();
|
||||
m_settingsKeys.append("displayPhotos");
|
||||
}
|
||||
if (m_settings->m_verboseModelMatching != ui->verboseModelMatching->isChecked())
|
||||
{
|
||||
m_settings->m_verboseModelMatching = ui->verboseModelMatching->isChecked();
|
||||
m_settingsKeys.append("verboseModelMatching");
|
||||
}
|
||||
if (m_settings->m_favourLivery != ui->favourLivery->isChecked())
|
||||
{
|
||||
m_settings->m_favourLivery = ui->favourLivery->isChecked();
|
||||
m_settingsKeys.append("favourLivery");
|
||||
}
|
||||
if (m_settings->m_transitionAlt != ui->transitionAltitude->value())
|
||||
{
|
||||
m_settings->m_transitionAlt = ui->transitionAltitude->value();
|
||||
m_settingsKeys.append("transitionAlt");
|
||||
}
|
||||
if (m_settings->m_tableFontName != m_fontName)
|
||||
{
|
||||
m_settings->m_tableFontName = m_fontName;
|
||||
m_settingsKeys.append("tableFontName");
|
||||
}
|
||||
if (m_settings->m_tableFontSize != m_fontSize)
|
||||
{
|
||||
m_settings->m_tableFontSize = m_fontSize;
|
||||
m_settingsKeys.append("tableFontSize");
|
||||
}
|
||||
if (m_settings->m_flightPathPaletteName != ui->flightPathPalette->currentText())
|
||||
{
|
||||
m_settings->m_flightPathPaletteName = ui->flightPathPalette->currentText();
|
||||
m_settingsKeys.append("flightPathPaletteName");
|
||||
m_settings->applyPalette();
|
||||
}
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,8 @@ public:
|
||||
explicit ADSBDemodDisplayDialog(ADSBDemodSettings *settings, QWidget* parent = 0);
|
||||
~ADSBDemodDisplayDialog();
|
||||
|
||||
const QStringList& getSettingsKeys() const { return m_settingsKeys; };
|
||||
|
||||
private slots:
|
||||
void accept();
|
||||
void on_font_clicked();
|
||||
@ -35,6 +37,7 @@ private slots:
|
||||
private:
|
||||
Ui::ADSBDemodDisplayDialog* ui;
|
||||
ADSBDemodSettings *m_settings;
|
||||
QStringList m_settingsKeys;
|
||||
QString m_fontName;
|
||||
int m_fontSize;
|
||||
};
|
||||
|
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>417</width>
|
||||
<height>467</height>
|
||||
<height>505</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
@ -124,22 +124,16 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="displayStatsLabel">
|
||||
<widget class="QLabel" name="verboseModelMatchingLabel">
|
||||
<property name="text">
|
||||
<string>Display demodulator statistics</string>
|
||||
<string>Log 3D model matching information</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QCheckBox" name="displayStats">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<widget class="QCheckBox" name="verboseModelMatching">
|
||||
<property name="toolTip">
|
||||
<string>Display demodulator statistics</string>
|
||||
<string>Log information about how aircraft are matched to 3D models</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
@ -147,16 +141,16 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="verboseModelMatchingLabel">
|
||||
<widget class="QLabel" name="favourLiveryLabel">
|
||||
<property name="text">
|
||||
<string>Log 3D model matching information</string>
|
||||
<string>Favour airline livery over aircraft type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QCheckBox" name="verboseModelMatching">
|
||||
<widget class="QCheckBox" name="favourLivery">
|
||||
<property name="toolTip">
|
||||
<string>Log information about how aircraft are matched to 3D models</string>
|
||||
<string>Favour airline livery over aircraft type for 3D models</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
@ -192,36 +186,13 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="airfieldElevationLabel">
|
||||
<property name="text">
|
||||
<string>Airfield barometric altitude (ft)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QSpinBox" name="airfieldElevation">
|
||||
<property name="toolTip">
|
||||
<string>Barometric altitude reported by aircraft when on airfield surface</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-10000</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>30000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="transitionAltitudeLabel">
|
||||
<property name="text">
|
||||
<string>Transition altitude (ft)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<item row="9" column="1">
|
||||
<widget class="QSpinBox" name="transitionAltitude">
|
||||
<property name="toolTip">
|
||||
<string>Transition altitude in feet</string>
|
||||
@ -232,6 +203,9 @@
|
||||
<property name="maximum">
|
||||
<number>20000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>6000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -303,14 +277,14 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="aircraftMinZoomLabel">
|
||||
<property name="text">
|
||||
<string>Zoom level for aircraft scaling</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="aircraftMinZoom">
|
||||
<property name="toolTip">
|
||||
<string>When map zoom (0 min zoom - 15 max zoom) is higher than this value, aircraft icon size will be scaled</string>
|
||||
@ -320,14 +294,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="airportSizeLabel">
|
||||
<property name="text">
|
||||
<string>Display airports with size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="airportSize">
|
||||
<property name="toolTip">
|
||||
<string>Sets the minimum airport size that will be displayed on the map</string>
|
||||
@ -349,14 +323,14 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="heliportsLabel">
|
||||
<property name="text">
|
||||
<string>Display heliports</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<item row="5" column="1">
|
||||
<widget class="QCheckBox" name="heliports">
|
||||
<property name="toolTip">
|
||||
<string>When checked, heliports are displayed on the map</string>
|
||||
@ -366,14 +340,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="airportRangeLabel">
|
||||
<property name="text">
|
||||
<string>Airport display distance (km)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<item row="6" column="1">
|
||||
<widget class="QSpinBox" name="airportRange">
|
||||
<property name="toolTip">
|
||||
<string>Displays airports within the specified distance in kilometres from My Position</string>
|
||||
@ -383,14 +357,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="airspacesLabel">
|
||||
<property name="text">
|
||||
<string>Airspaces to display</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<item row="7" column="1">
|
||||
<widget class="QListWidget" name="airspaces">
|
||||
<property name="toolTip">
|
||||
<string>Airspace categories to display</string>
|
||||
@ -547,14 +521,14 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="airspaceRangeLabel">
|
||||
<property name="text">
|
||||
<string>Airspace display distance (km)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<item row="8" column="1">
|
||||
<widget class="QSpinBox" name="airspaceRange">
|
||||
<property name="toolTip">
|
||||
<string>Displays airspace within the specified distance in kilometres from My Position</string>
|
||||
@ -564,14 +538,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="displayNavAids">
|
||||
<property name="text">
|
||||
<string>Display NAVAIDs</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<item row="9" column="1">
|
||||
<widget class="QCheckBox" name="navAids">
|
||||
<property name="toolTip">
|
||||
<string>Display NAVAIDs such as VORs and NDBs</string>
|
||||
@ -581,7 +555,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<item row="10" column="1">
|
||||
<widget class="QCheckBox" name="atcCallsigns">
|
||||
<property name="toolTip">
|
||||
<string>Use ATC callsigns (SPEEDBIRD) rather than ICAO (BAW) for aircraft labels on map</string>
|
||||
@ -591,13 +565,44 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="atcCallsignsLabel">
|
||||
<property name="text">
|
||||
<string>Use ATC callsigns on map</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QComboBox" name="flightPathPalette">
|
||||
<property name="toolTip">
|
||||
<string>Colour palette to use for aircraft flight paths</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="flightPathPaletteLabel">
|
||||
<property name="text">
|
||||
<string>Flight path palette</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Maptiler API key</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="maptilerAPIKey">
|
||||
<property name="toolTip">
|
||||
<string>API key for Maptiler (https://maptiler.com) for satellite map</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
@ -607,10 +612,10 @@
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <QTextToSpeech>
|
||||
#include <QRandomGenerator>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QtCharts>
|
||||
|
||||
#include "channel/channelgui.h"
|
||||
#include "dsp/dsptypes.h"
|
||||
@ -56,11 +57,17 @@ class WebAPIAdapterInterface;
|
||||
class HttpDownloadManager;
|
||||
class ADSBDemodGUI;
|
||||
class ADSBOSMTemplateServer;
|
||||
class CheckList;
|
||||
class AircraftModel;
|
||||
|
||||
namespace Ui {
|
||||
class ADSBDemodGUI;
|
||||
}
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
using namespace QtCharts;
|
||||
#endif
|
||||
|
||||
// Custom widget to allow formatted decimal numbers to be sorted numerically
|
||||
class CustomDoubleTableWidgetItem : public QTableWidgetItem
|
||||
{
|
||||
@ -89,12 +96,16 @@ struct Aircraft {
|
||||
QString m_icaoHex;
|
||||
QString m_callsign; // Flight callsign
|
||||
QString m_flight; // Guess at flight number
|
||||
bool m_globalPosition; // Position has been determined from global decode
|
||||
Real m_latitude; // Latitude in decimal degrees
|
||||
Real m_longitude; // Longitude in decimal degrees
|
||||
int m_altitude; // Altitude in feet
|
||||
float m_radius; // Horizontal containment radius limit (Rc) in metres
|
||||
int m_altitude; // Altitude in feet (will be 0 if on surface)
|
||||
int m_pressureAltitude; // Pressure altitude in feet for Map PFD altimeter (can be negative on surface)
|
||||
bool m_onSurface; // Indicates if on surface or airborne
|
||||
bool m_altitudeGNSS; // Altitude is GNSS HAE (Height above WGS-84 ellipsoid) rather than barometric alitute (relative to 29.92 Hg)
|
||||
float m_heading; // Heading or track in degrees
|
||||
float m_heading; // Heading in degrees magnetic
|
||||
float m_track; // Track in degrees true?
|
||||
int m_verticalRate; // Vertical climb rate in ft/min
|
||||
QString m_emitterCategory; // Aircraft type
|
||||
QString m_status; // Aircraft status
|
||||
@ -102,23 +113,37 @@ struct Aircraft {
|
||||
Real m_range; // Distance from station to aircraft
|
||||
Real m_azimuth; // Azimuth from station to aircraft
|
||||
Real m_elevation; // Elevation from station to aircraft
|
||||
QDateTime m_time; // When last updated
|
||||
QDateTime m_rxTime; // When last frame received (can be long ago if reading from log file)
|
||||
QDateTime m_updateTime; // Last time we updated data for this aircraft (used for determining when to remove an aircraft)
|
||||
|
||||
int m_selAltitude; // Selected altitude in MCP/FCU or FMS in feet
|
||||
int m_selHeading; // Selected heading in MCP/FCU in degrees
|
||||
int m_baro; // Aircraft baro setting in mb (Mode-S)
|
||||
float m_baro; // Aircraft baro setting in mb (Mode-S)
|
||||
float m_roll; // In degrees
|
||||
int m_groundspeed; // In knots
|
||||
float m_turnRate; // In degrees per second
|
||||
int m_trueAirspeed; // In knots
|
||||
int m_indicatedAirspeed; // In knots
|
||||
float m_mach; // Mach number
|
||||
bool m_autopilot;
|
||||
bool m_vnavMode;
|
||||
bool m_altHoldMode;
|
||||
bool m_approachMode;
|
||||
bool m_lnavMode;
|
||||
bool m_tcasOperational; // Appears only to be true if TA/RA, false if TA ONLY
|
||||
|
||||
bool m_bdsCapabilities[16][16]; // BDS capabilities are indicaited by BDS 1.7
|
||||
int m_adsbVersion;
|
||||
bool m_nicSupplementA;
|
||||
bool m_nicSupplementB;
|
||||
bool m_nicSupplementC;
|
||||
|
||||
bool m_positionValid; // Indicates if we have valid data for the above fields
|
||||
bool m_altitudeValid;
|
||||
bool m_pressureAltitudeValid;
|
||||
bool m_onSurfaceValid;
|
||||
bool m_headingValid;
|
||||
bool m_trackValid;
|
||||
bool m_verticalRateValid;
|
||||
bool m_selAltitudeValid;
|
||||
bool m_selHeadingValid;
|
||||
@ -129,16 +154,30 @@ struct Aircraft {
|
||||
bool m_trueAirspeedValid;
|
||||
bool m_indicatedAirspeedValid;
|
||||
bool m_machValid;
|
||||
bool m_autopilotValid;
|
||||
bool m_vnavModeValid;
|
||||
bool m_altHoldModeValid;
|
||||
bool m_approachModeValid;
|
||||
bool m_lnavModeValid;
|
||||
bool m_tcasOperationalValid;
|
||||
|
||||
bool m_bdsCapabilitiesValid;
|
||||
bool m_adsbVersionValid;
|
||||
bool m_nicSupplementAValid;
|
||||
bool m_nicSupplementBValid;
|
||||
bool m_nicSupplementCValid;
|
||||
|
||||
// State for calculating position using two CPR frames
|
||||
bool m_cprValid[2];
|
||||
Real m_cprLat[2];
|
||||
Real m_cprLong[2];
|
||||
double m_cprLat[2];
|
||||
double m_cprLong[2];
|
||||
QDateTime m_cprTime[2];
|
||||
|
||||
int m_adsbFrameCount; // Number of ADS-B frames for this aircraft
|
||||
int m_modesFrameCount; // Number of Mode-S frames for this aircraft
|
||||
int m_nonTransponderFrameCount;
|
||||
int m_tisBFrameCount;
|
||||
int m_adsrFrameCount;
|
||||
float m_minCorrelation;
|
||||
float m_maxCorrelation;
|
||||
float m_correlation;
|
||||
@ -148,8 +187,12 @@ struct Aircraft {
|
||||
bool m_isHighlighted; // Are we highlighting this aircraft in the table and map
|
||||
bool m_showAll;
|
||||
|
||||
QVariantList m_coordinates; // Coordinates we've recorded the aircraft at
|
||||
QList<QVariantList> m_coordinates; // Coordinates we've recorded the aircraft at, split up in to altitude ranges
|
||||
QList<QVariantList> m_recentCoordinates; // Last 20 seconds of coordinates for ATC mode
|
||||
QList<QDateTime> m_coordinateDateTimes;
|
||||
QList<int> m_coordinateColors; // 0-7 index to 8 color palette according to altitude
|
||||
QList<int> m_recentCoordinateColors;
|
||||
int m_lastColor;
|
||||
|
||||
AircraftInformation *m_aircraftInfo; // Info about the aircraft from the database
|
||||
QString m_aircraft3DModel; // 3D model for map based on aircraft type
|
||||
@ -159,6 +202,7 @@ struct Aircraft {
|
||||
ADSBDemodGUI *m_gui;
|
||||
QString m_flagIconURL;
|
||||
QString m_airlineIconURL;
|
||||
QString m_sideviewIconURL;
|
||||
|
||||
// For animation on 3D map
|
||||
float m_runwayAltitude;
|
||||
@ -168,10 +212,14 @@ struct Aircraft {
|
||||
bool m_rotorStarted; // Rotors started on 'Rotorcraft'
|
||||
bool m_engineStarted; // Engines started (typically propellors)
|
||||
QDateTime m_positionDateTime;
|
||||
QDateTime m_orientationDateTime;
|
||||
QDateTime m_orientationDateTime; // FIXME
|
||||
QDateTime m_headingDateTime;
|
||||
QDateTime m_prevHeadingDateTime;
|
||||
int m_prevHeading;
|
||||
QDateTime m_trackDateTime;
|
||||
QDateTime m_altitudeDateTime;
|
||||
QDateTime m_indicatedAirspeedDateTime;
|
||||
QDateTime m_prevTrackDateTime;
|
||||
int m_prevTrack;
|
||||
float m_trackWhenHeadingSet;
|
||||
float m_pitchEst; // Estimated pitch based on vertical rate
|
||||
float m_rollEst; // Estimated roll based on rate of change in heading
|
||||
|
||||
@ -182,30 +230,48 @@ struct Aircraft {
|
||||
QTableWidgetItem *m_callsignItem;
|
||||
QTableWidgetItem* m_atcCallsignItem;
|
||||
QTableWidgetItem *m_modelItem;
|
||||
QTableWidgetItem *m_typeItem;
|
||||
QTableWidgetItem *m_sideviewItem;
|
||||
QTableWidgetItem *m_airlineItem;
|
||||
QTableWidgetItem *m_latitudeItem;
|
||||
QTableWidgetItem *m_longitudeItem;
|
||||
QTableWidgetItem *m_altitudeItem;
|
||||
QTableWidgetItem *m_headingItem;
|
||||
QTableWidgetItem *m_trackItem;
|
||||
QTableWidgetItem *m_verticalRateItem;
|
||||
CustomDoubleTableWidgetItem *m_rangeItem;
|
||||
QTableWidgetItem *m_azElItem;
|
||||
QTableWidgetItem *m_emitterCategoryItem;
|
||||
QTableWidgetItem *m_statusItem;
|
||||
QTableWidgetItem *m_squawkItem;
|
||||
QTableWidgetItem *m_identItem;
|
||||
QTableWidgetItem *m_registrationItem;
|
||||
QTableWidgetItem *m_countryItem;
|
||||
QTableWidgetItem *m_registeredItem;
|
||||
QTableWidgetItem *m_manufacturerNameItem;
|
||||
QTableWidgetItem *m_ownerItem;
|
||||
QTableWidgetItem *m_operatorICAOItem;
|
||||
QTableWidgetItem *m_interogatorCodeItem;
|
||||
QTableWidgetItem *m_timeItem;
|
||||
QTableWidgetItem *m_totalFrameCountItem;
|
||||
QTableWidgetItem *m_adsbFrameCountItem;
|
||||
QTableWidgetItem *m_modesFrameCountItem;
|
||||
QTableWidgetItem *m_nonTransponderItem;
|
||||
QTableWidgetItem *m_tisBFrameCountItem;
|
||||
QTableWidgetItem *m_adsrFrameCountItem;
|
||||
QTableWidgetItem *m_radiusItem;
|
||||
QTableWidgetItem *m_nacpItem;
|
||||
QTableWidgetItem *m_nacvItem;
|
||||
QTableWidgetItem *m_gvaItem;
|
||||
QTableWidgetItem *m_nicItem;
|
||||
QTableWidgetItem *m_nicBaroItem;
|
||||
QTableWidgetItem *m_silItem;
|
||||
QTableWidgetItem *m_correlationItem;
|
||||
QTableWidgetItem *m_rssiItem;
|
||||
QTableWidgetItem *m_flightStatusItem;
|
||||
QTableWidgetItem *m_depItem;
|
||||
QTableWidgetItem *m_arrItem;
|
||||
QTableWidgetItem *m_stopsItem;
|
||||
QTableWidgetItem *m_stdItem;
|
||||
QTableWidgetItem *m_etdItem;
|
||||
QTableWidgetItem *m_atdItem;
|
||||
@ -218,6 +284,13 @@ struct Aircraft {
|
||||
QTableWidgetItem *m_apItem;
|
||||
QTableWidgetItem *m_vModeItem;
|
||||
QTableWidgetItem *m_lModeItem;
|
||||
QTableWidgetItem *m_tcasItem;
|
||||
QTableWidgetItem *m_acasItem;
|
||||
QTableWidgetItem *m_raItem;
|
||||
QTableWidgetItem *m_maxSpeedItem;
|
||||
QTableWidgetItem *m_versionItem;
|
||||
QTableWidgetItem *m_lengthItem;
|
||||
QTableWidgetItem *m_widthItem;
|
||||
QTableWidgetItem *m_rollItem;
|
||||
QTableWidgetItem *m_groundspeedItem;
|
||||
QTableWidgetItem *m_turnRateItem;
|
||||
@ -231,16 +304,18 @@ struct Aircraft {
|
||||
QTableWidgetItem *m_staticPressureItem;
|
||||
QTableWidgetItem *m_staticAirTempItem;
|
||||
QTableWidgetItem *m_humidityItem;
|
||||
QTableWidgetItem *m_tisBItem;
|
||||
|
||||
Aircraft(ADSBDemodGUI *gui) :
|
||||
m_icao(0),
|
||||
m_globalPosition(false),
|
||||
m_latitude(0),
|
||||
m_longitude(0),
|
||||
m_radius(0.0f),
|
||||
m_altitude(0),
|
||||
m_onSurface(false),
|
||||
m_altitudeGNSS(false),
|
||||
m_heading(0),
|
||||
m_track(0),
|
||||
m_verticalRate(0),
|
||||
m_azimuth(0),
|
||||
m_elevation(0),
|
||||
@ -253,9 +328,22 @@ struct Aircraft {
|
||||
m_trueAirspeed(0),
|
||||
m_indicatedAirspeed(0),
|
||||
m_mach(0.0f),
|
||||
m_autopilot(false),
|
||||
m_vnavMode(false),
|
||||
m_altHoldMode(false),
|
||||
m_approachMode(false),
|
||||
m_lnavMode(false),
|
||||
m_tcasOperational(false),
|
||||
m_adsbVersion(0),
|
||||
m_nicSupplementA(false),
|
||||
m_nicSupplementB(false),
|
||||
m_nicSupplementC(false),
|
||||
m_positionValid(false),
|
||||
m_altitudeValid(false),
|
||||
m_pressureAltitudeValid(false),
|
||||
m_onSurfaceValid(false),
|
||||
m_headingValid(false),
|
||||
m_trackValid(false),
|
||||
m_verticalRateValid(false),
|
||||
m_selAltitudeValid(false),
|
||||
m_selHeadingValid(false),
|
||||
@ -266,9 +354,22 @@ struct Aircraft {
|
||||
m_trueAirspeedValid(false),
|
||||
m_indicatedAirspeedValid(false),
|
||||
m_machValid(false),
|
||||
m_autopilotValid(false),
|
||||
m_vnavModeValid(false),
|
||||
m_altHoldModeValid(false),
|
||||
m_approachModeValid(false),
|
||||
m_lnavModeValid(false),
|
||||
m_tcasOperationalValid(false),
|
||||
m_bdsCapabilitiesValid(false),
|
||||
m_adsbVersionValid(false),
|
||||
m_nicSupplementAValid(false),
|
||||
m_nicSupplementBValid(false),
|
||||
m_nicSupplementCValid(false),
|
||||
m_adsbFrameCount(0),
|
||||
m_modesFrameCount(0),
|
||||
m_nonTransponderFrameCount(0),
|
||||
m_tisBFrameCount(0),
|
||||
m_adsrFrameCount(0),
|
||||
m_minCorrelation(INFINITY),
|
||||
m_maxCorrelation(-INFINITY),
|
||||
m_correlation(0.0f),
|
||||
@ -302,9 +403,12 @@ struct Aircraft {
|
||||
m_callsignItem = new QTableWidgetItem();
|
||||
m_atcCallsignItem = new QTableWidgetItem();
|
||||
m_modelItem = new QTableWidgetItem();
|
||||
m_typeItem = new QTableWidgetItem();
|
||||
m_sideviewItem = new QTableWidgetItem();
|
||||
m_airlineItem = new QTableWidgetItem();
|
||||
m_altitudeItem = new QTableWidgetItem();
|
||||
m_headingItem = new QTableWidgetItem();
|
||||
m_trackItem = new QTableWidgetItem();
|
||||
m_verticalRateItem = new QTableWidgetItem();
|
||||
m_rangeItem = new CustomDoubleTableWidgetItem();
|
||||
m_azElItem = new QTableWidgetItem();
|
||||
@ -313,19 +417,34 @@ struct Aircraft {
|
||||
m_emitterCategoryItem = new QTableWidgetItem();
|
||||
m_statusItem = new QTableWidgetItem();
|
||||
m_squawkItem = new QTableWidgetItem();
|
||||
m_identItem = new QTableWidgetItem();
|
||||
m_registrationItem = new QTableWidgetItem();
|
||||
m_countryItem = new QTableWidgetItem();
|
||||
m_registeredItem = new QTableWidgetItem();
|
||||
m_manufacturerNameItem = new QTableWidgetItem();
|
||||
m_ownerItem = new QTableWidgetItem();
|
||||
m_operatorICAOItem = new QTableWidgetItem();
|
||||
m_interogatorCodeItem = new QTableWidgetItem();
|
||||
m_timeItem = new QTableWidgetItem();
|
||||
m_totalFrameCountItem = new QTableWidgetItem();
|
||||
m_adsbFrameCountItem = new QTableWidgetItem();
|
||||
m_modesFrameCountItem = new QTableWidgetItem();
|
||||
m_nonTransponderItem = new QTableWidgetItem();
|
||||
m_tisBFrameCountItem = new QTableWidgetItem();
|
||||
m_adsrFrameCountItem = new QTableWidgetItem();
|
||||
m_radiusItem = new QTableWidgetItem();
|
||||
m_nacpItem = new QTableWidgetItem();
|
||||
m_nacvItem = new QTableWidgetItem();
|
||||
m_gvaItem = new QTableWidgetItem();
|
||||
m_nicItem = new QTableWidgetItem();
|
||||
m_nicBaroItem = new QTableWidgetItem();
|
||||
m_silItem = new QTableWidgetItem();
|
||||
m_correlationItem = new QTableWidgetItem();
|
||||
m_rssiItem = new QTableWidgetItem();
|
||||
m_flightStatusItem = new QTableWidgetItem();
|
||||
m_depItem = new QTableWidgetItem();
|
||||
m_arrItem = new QTableWidgetItem();
|
||||
m_stopsItem = new QTableWidgetItem();
|
||||
m_stdItem = new QTableWidgetItem();
|
||||
m_etdItem = new QTableWidgetItem();
|
||||
m_atdItem = new QTableWidgetItem();
|
||||
@ -338,6 +457,13 @@ struct Aircraft {
|
||||
m_apItem = new QTableWidgetItem();
|
||||
m_vModeItem = new QTableWidgetItem();
|
||||
m_lModeItem = new QTableWidgetItem();
|
||||
m_tcasItem = new QTableWidgetItem();
|
||||
m_acasItem = new QTableWidgetItem();
|
||||
m_raItem = new QTableWidgetItem();
|
||||
m_maxSpeedItem = new QTableWidgetItem();
|
||||
m_versionItem = new QTableWidgetItem();
|
||||
m_lengthItem = new QTableWidgetItem();
|
||||
m_widthItem = new QTableWidgetItem();
|
||||
m_rollItem = new QTableWidgetItem();
|
||||
m_groundspeedItem = new QTableWidgetItem();
|
||||
m_turnRateItem = new QTableWidgetItem();
|
||||
@ -351,16 +477,15 @@ struct Aircraft {
|
||||
m_staticPressureItem = new QTableWidgetItem();
|
||||
m_staticAirTempItem = new QTableWidgetItem();
|
||||
m_humidityItem = new QTableWidgetItem();
|
||||
m_tisBItem = new QTableWidgetItem();
|
||||
}
|
||||
|
||||
QString getImage() const;
|
||||
QString getText(const ADSBDemodSettings *settings, bool all=false) const;
|
||||
// Label to use for aircraft on map
|
||||
QString getLabel(const ADSBDemodSettings *settings) const;
|
||||
QString getLabel(const ADSBDemodSettings *settings, QDateTime& dateTime) const;
|
||||
|
||||
// Name to use when selected as a target (E.g. for use as target name in Rotator Controller)
|
||||
QString targetName()
|
||||
QString targetName() const
|
||||
{
|
||||
if (!m_callsign.isEmpty())
|
||||
return QString("Callsign: %1").arg(m_callsign);
|
||||
@ -368,6 +493,71 @@ struct Aircraft {
|
||||
return QString("ICAO: %1").arg(m_icao, 0, 16);
|
||||
}
|
||||
|
||||
void setOnSurface(const QDateTime& dateTime);
|
||||
void setAltitude(int altitudeFt, bool gnss, const QDateTime& dateTime, const ADSBDemodSettings& settings);
|
||||
void setVerticalRate(int verticalRate, const ADSBDemodSettings& settings);
|
||||
void setGroundspeed(float groundspeed, const ADSBDemodSettings& settings);
|
||||
void setTrueAirspeed(int airspeed, const ADSBDemodSettings& settings);
|
||||
void setIndicatedAirspeed(int airspeed, const QDateTime& dateTime, const ADSBDemodSettings& settings);
|
||||
void setTrack(float track, const QDateTime& dateTime);
|
||||
void setHeading(float heading, const QDateTime& dateTime);
|
||||
void addCoordinate(const QDateTime& dateTime, AircraftModel *model);
|
||||
void clearCoordinates(AircraftModel *model);
|
||||
};
|
||||
|
||||
class AircraftPathModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using QAbstractListModel::QAbstractListModel;
|
||||
enum MarkerRoles{
|
||||
coordinatesRole = Qt::UserRole + 1,
|
||||
colorRole = Qt::UserRole + 2,
|
||||
};
|
||||
|
||||
AircraftPathModel(AircraftModel *aircraftModel, Aircraft *aircraft) :
|
||||
m_aircraftModel(aircraftModel),
|
||||
m_aircraft(aircraft),
|
||||
m_paths(0),
|
||||
m_showFullPath(false),
|
||||
m_showATCPath(false)
|
||||
{
|
||||
settingsUpdated();
|
||||
}
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override {
|
||||
(void) parent;
|
||||
return m_paths;
|
||||
}
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
void add();
|
||||
void updateLast();
|
||||
void removed();
|
||||
void clear();
|
||||
void settingsUpdated();
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override
|
||||
{
|
||||
(void) index;
|
||||
return Qt::ItemIsEnabled;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> roleNames() const {
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[coordinatesRole] = "coordinates";
|
||||
roles[colorRole] = "color";
|
||||
return roles;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
AircraftModel *m_aircraftModel;
|
||||
Aircraft *m_aircraft;
|
||||
int m_paths; // Should match m_aircraft->m_coordinates.count()
|
||||
bool m_showFullPath;
|
||||
bool m_showATCPath;
|
||||
};
|
||||
|
||||
// Aircraft data model used by QML map item
|
||||
@ -385,12 +575,16 @@ public:
|
||||
aircraftPathRole = Qt::UserRole + 6,
|
||||
showAllRole = Qt::UserRole + 7,
|
||||
highlightedRole = Qt::UserRole + 8,
|
||||
targetRole = Qt::UserRole + 9
|
||||
targetRole = Qt::UserRole + 9,
|
||||
radiusRole = Qt::UserRole + 10,
|
||||
showRadiusRole = Qt::UserRole + 11,
|
||||
aircraftPathModelRole = Qt::UserRole + 12,
|
||||
};
|
||||
|
||||
Q_INVOKABLE void addAircraft(Aircraft *aircraft) {
|
||||
beginInsertRows(QModelIndex(), rowCount(), rowCount());
|
||||
m_aircrafts.append(aircraft);
|
||||
m_pathModels.append(new AircraftPathModel(this, aircraft));
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
@ -409,7 +603,8 @@ public:
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
|
||||
}
|
||||
|
||||
void aircraftUpdated(Aircraft *aircraft) {
|
||||
void aircraftUpdated(Aircraft *aircraft)
|
||||
{
|
||||
int row = m_aircrafts.indexOf(aircraft);
|
||||
if (row >= 0)
|
||||
{
|
||||
@ -418,30 +613,72 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void allAircraftUpdated() {
|
||||
/*
|
||||
// Not sure why this doesn't work - it should be more efficient
|
||||
// than the following code
|
||||
emit dataChanged(index(0), index(rowCount()));
|
||||
*/
|
||||
for (int i = 0; i < m_aircrafts.count(); i++)
|
||||
void highlightChanged(Aircraft *aircraft)
|
||||
{
|
||||
int row = m_aircrafts.indexOf(aircraft);
|
||||
if (row >= 0)
|
||||
{
|
||||
QModelIndex idx = index(i);
|
||||
m_pathModels[row]->settingsUpdated();
|
||||
QModelIndex idx = index(row);
|
||||
emit dataChanged(idx, idx);
|
||||
}
|
||||
}
|
||||
|
||||
void removeAircraft(Aircraft *aircraft) {
|
||||
void clearCoords(Aircraft *aircraft)
|
||||
{
|
||||
int row = m_aircrafts.indexOf(aircraft);
|
||||
if (row >= 0) {
|
||||
m_pathModels[row]->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void aircraftCoordsUpdated(Aircraft *aircraft)
|
||||
{
|
||||
int row = m_aircrafts.indexOf(aircraft);
|
||||
if (row >= 0) {
|
||||
m_pathModels[row]->updateLast();
|
||||
}
|
||||
}
|
||||
|
||||
void aircraftCoordsAdded(Aircraft *aircraft)
|
||||
{
|
||||
int row = m_aircrafts.indexOf(aircraft);
|
||||
if (row >= 0) {
|
||||
m_pathModels[row]->add();
|
||||
}
|
||||
}
|
||||
|
||||
void aircraftCoordsRemoved(Aircraft *aircraft)
|
||||
{
|
||||
int row = m_aircrafts.indexOf(aircraft);
|
||||
if (row >= 0) {
|
||||
m_pathModels[row]->removed();
|
||||
}
|
||||
}
|
||||
|
||||
void allAircraftUpdated()
|
||||
{
|
||||
emit dataChanged(index(0), index(rowCount()-1));
|
||||
|
||||
for (int i = 0; i < m_aircrafts.count(); i++) {
|
||||
m_pathModels[i]->settingsUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
void removeAircraft(Aircraft *aircraft)
|
||||
{
|
||||
int row = m_aircrafts.indexOf(aircraft);
|
||||
if (row >= 0)
|
||||
{
|
||||
beginRemoveRows(QModelIndex(), row, row);
|
||||
m_aircrafts.removeAt(row);
|
||||
delete m_pathModels.takeAt(row);
|
||||
endRemoveRows();
|
||||
}
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> roleNames() const {
|
||||
QHash<int, QByteArray> roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[positionRole] = "position";
|
||||
roles[headingRole] = "heading";
|
||||
@ -452,22 +689,12 @@ public:
|
||||
roles[showAllRole] = "showAll";
|
||||
roles[highlightedRole] = "highlighted";
|
||||
roles[targetRole] = "target";
|
||||
roles[radiusRole] = "containmentRadius";
|
||||
roles[aircraftPathModelRole] = "aircraftPathModel";
|
||||
return roles;
|
||||
}
|
||||
|
||||
void setFlightPaths(bool flightPaths)
|
||||
{
|
||||
m_flightPaths = flightPaths;
|
||||
allAircraftUpdated();
|
||||
}
|
||||
|
||||
void setAllFlightPaths(bool allFlightPaths)
|
||||
{
|
||||
m_allFlightPaths = allFlightPaths;
|
||||
allAircraftUpdated();
|
||||
}
|
||||
|
||||
void setSettings(const ADSBDemodSettings *settings)
|
||||
void setSettings(const ADSBDemodSettings *settings)
|
||||
{
|
||||
m_settings = settings;
|
||||
allAircraftUpdated();
|
||||
@ -487,11 +714,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
const ADSBDemodSettings *m_settings;
|
||||
|
||||
private:
|
||||
QList<Aircraft *> m_aircrafts;
|
||||
bool m_flightPaths;
|
||||
bool m_allFlightPaths;
|
||||
const ADSBDemodSettings *m_settings;
|
||||
QList<AircraftPathModel *> m_pathModels;
|
||||
};
|
||||
|
||||
// Airport data model used by QML map item
|
||||
@ -667,26 +894,34 @@ public:
|
||||
airspacePolygonRole = Qt::UserRole + 6
|
||||
};
|
||||
|
||||
Q_INVOKABLE void addAirspace(Airspace *airspace) {
|
||||
Q_INVOKABLE void addAirspace(Airspace *airspace)
|
||||
{
|
||||
beginInsertRows(QModelIndex(), rowCount(), rowCount());
|
||||
m_airspaces.append(airspace);
|
||||
// Convert QPointF to QVariantList of QGeoCoordinates
|
||||
QVariantList polygon;
|
||||
for (const auto p : airspace->m_polygon)
|
||||
{
|
||||
QGeoCoordinate coord(p.y(), p.x(), airspace->topHeightInMetres());
|
||||
polygon.push_back(QVariant::fromValue(coord));
|
||||
}
|
||||
m_polygons.append(polygon);
|
||||
updatePolygon(airspace, -1);
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override {
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return m_airspaces.count();
|
||||
}
|
||||
|
||||
void removeAllAirspaces() {
|
||||
void removeAirspace(Airspace *airspace)
|
||||
{
|
||||
int idx = m_airspaces.indexOf(airspace);
|
||||
if (idx >= 0)
|
||||
{
|
||||
beginRemoveRows(QModelIndex(), idx, idx);
|
||||
m_airspaces.removeAt(idx);
|
||||
m_polygons.removeAt(idx);
|
||||
endRemoveRows();
|
||||
}
|
||||
}
|
||||
|
||||
void removeAllAirspaces()
|
||||
{
|
||||
if (m_airspaces.count() > 0)
|
||||
{
|
||||
beginRemoveRows(QModelIndex(), 0, m_airspaces.count() - 1);
|
||||
@ -696,6 +931,23 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void airspaceUpdated(const Airspace *airspace)
|
||||
{
|
||||
int row = m_airspaces.indexOf(airspace);
|
||||
if (row >= 0)
|
||||
{
|
||||
updatePolygon(airspace, row);
|
||||
|
||||
QModelIndex idx = index(row);
|
||||
emit dataChanged(idx, idx);
|
||||
}
|
||||
}
|
||||
|
||||
bool contains(const Airspace *airspace)
|
||||
{
|
||||
return m_airspaces.contains(airspace);
|
||||
}
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
bool setData(const QModelIndex &index, const QVariant& value, int role = Qt::EditRole) override;
|
||||
@ -706,7 +958,8 @@ public:
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> roleNames() const {
|
||||
QHash<int, QByteArray> roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[nameRole] = "name";
|
||||
roles[detailsRole] = "details";
|
||||
@ -718,8 +971,25 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
QList<Airspace *> m_airspaces;
|
||||
QList<const Airspace *> m_airspaces;
|
||||
QList<QVariantList> m_polygons;
|
||||
|
||||
void updatePolygon(const Airspace *airspace, int row)
|
||||
{
|
||||
// Convert QPointF to QVariantList of QGeoCoordinates
|
||||
QVariantList polygon;
|
||||
for (const auto p : airspace->m_polygon)
|
||||
{
|
||||
QGeoCoordinate coord(p.y(), p.x(), airspace->topHeightInMetres());
|
||||
polygon.push_back(QVariant::fromValue(coord));
|
||||
}
|
||||
if (row == -1) {
|
||||
m_polygons.append(polygon);
|
||||
} else {
|
||||
m_polygons.replace(row, polygon);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// NavAid model used for each NavAid on the map
|
||||
@ -811,7 +1081,7 @@ public:
|
||||
{
|
||||
m_aircraftRegExp.optimize();
|
||||
}
|
||||
|
||||
|
||||
virtual ~ModelMatch() = default;
|
||||
|
||||
virtual bool match(const QString &aircraft, const QString &manufacturer, QString &model)
|
||||
@ -867,6 +1137,23 @@ protected:
|
||||
class ADSBDemodGUI : public ChannelGUI {
|
||||
Q_OBJECT
|
||||
|
||||
struct Interogator {
|
||||
Real m_minLatitude;
|
||||
Real m_maxLatitude;
|
||||
Real m_minLongitude;
|
||||
Real m_maxLongitude;
|
||||
bool m_valid;
|
||||
Airspace m_airspace;
|
||||
|
||||
Interogator() :
|
||||
m_valid(false)
|
||||
{
|
||||
}
|
||||
|
||||
void update(int ic, Aircraft *aircraft, AirspaceModel *airspaceModel, CheckList *checkList, bool display);
|
||||
void calcPoly();
|
||||
};
|
||||
|
||||
public:
|
||||
static ADSBDemodGUI* create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel);
|
||||
virtual void destroy();
|
||||
@ -911,6 +1198,7 @@ private:
|
||||
ChannelMarker m_channelMarker;
|
||||
RollupState m_rollupState;
|
||||
ADSBDemodSettings m_settings;
|
||||
QStringList m_settingsKeys;
|
||||
qint64 m_deviceCenterFrequency;
|
||||
int m_basebandSampleRate;
|
||||
bool m_basicSettingsShown;
|
||||
@ -922,6 +1210,7 @@ private:
|
||||
|
||||
QHash<int, Aircraft *> m_aircraft; // Hashed on ICAO
|
||||
QSharedPointer<const QHash<int, AircraftInformation *>> m_aircraftInfo;
|
||||
QSharedPointer<const QHash<QString, AircraftRouteInformation *>> m_routeInfo; // Hashed on callsign
|
||||
QSharedPointer<const QHash<int, AirportInformation *>> m_airportInfo; // Hashed on id
|
||||
AircraftModel m_aircraftModel;
|
||||
AirportModel m_airportModel;
|
||||
@ -935,12 +1224,85 @@ private:
|
||||
Aircraft *m_trackAircraft; // Aircraft we want to track in Channel Report
|
||||
MovingAverageUtil<float, double, 10> m_correlationAvg;
|
||||
MovingAverageUtil<float, double, 10> m_correlationOnesAvg;
|
||||
MovingAverageUtil<float, double, 100> m_qnhAvg;
|
||||
|
||||
Aircraft *m_highlightAircraft; // Aircraft we want to highlight, when selected in table
|
||||
|
||||
float m_currentAirportRange; // Current settings, so we only update if changed
|
||||
ADSBDemodSettings::AirportType m_currentAirportMinimumSize;
|
||||
bool m_currentDisplayHeliports;
|
||||
|
||||
static const int m_maxRangeDeg = 5;
|
||||
QList<float> m_maxRange[2];
|
||||
Airspace m_coverageAirspace[2];
|
||||
|
||||
Interogator m_interogators[ADSB_IC_MAX];
|
||||
|
||||
enum StatsRow {
|
||||
ADSB_FRAMES,
|
||||
MODE_S_FRAMES,
|
||||
TOTAL_FRAMES,
|
||||
ADSB_RATE,
|
||||
MODE_S_RATE,
|
||||
TOTAL_RATE,
|
||||
DATA_RATE,
|
||||
CORRELATOR_MATCHES,
|
||||
PERCENT_VALID,
|
||||
PREAMBLE_FAILS,
|
||||
CRC_FAILS,
|
||||
TYPE_FAILS,
|
||||
INVALID_FAILS,
|
||||
ICAO_FAILS,
|
||||
RANGE_FAILS,
|
||||
ALT_FAILS,
|
||||
AVERAGE_CORRELATION,
|
||||
TC_0,
|
||||
TC_1_4,
|
||||
TC_5_8,
|
||||
TC_9_18,
|
||||
TC_19,
|
||||
TC_20_22,
|
||||
TC_24,
|
||||
TC_28,
|
||||
TC_29,
|
||||
TC_31,
|
||||
TC_UNUSED,
|
||||
DF0,
|
||||
DF4,
|
||||
DF5,
|
||||
DF11,
|
||||
DF16,
|
||||
DF17,
|
||||
DF18,
|
||||
DF19,
|
||||
DF20_21,
|
||||
DF22,
|
||||
DF24,
|
||||
MAX_RANGE,
|
||||
MAX_ALTITUDE,
|
||||
MAX_RATE
|
||||
};
|
||||
|
||||
qint64 m_rangeFails;
|
||||
qint64 m_altFails;
|
||||
QDateTime m_frameRateTime;
|
||||
qint64 m_adsbFrameRateCount;
|
||||
qint64 m_modesFrameRateCount;
|
||||
qint64 m_totalBytes;
|
||||
float m_maxRangeStat;
|
||||
float m_maxAltitudeStat;
|
||||
float m_maxRateState;
|
||||
qint64 m_dfStats[32];
|
||||
qint64 m_tcStats[32];
|
||||
QChart *m_chart;
|
||||
QLineSeries *m_adsbFrameRateSeries;
|
||||
QLineSeries *m_modesFrameRateSeries;
|
||||
QLineSeries *m_aircraftSeries;
|
||||
QDateTimeAxis *m_xAxis;
|
||||
QValueAxis *m_fpsYAxis;
|
||||
QValueAxis *m_aircraftYAxis;
|
||||
QDateTime m_averageTime;
|
||||
|
||||
#ifdef QT_TEXTTOSPEECH_FOUND
|
||||
QTextToSpeech *m_speech;
|
||||
#endif
|
||||
@ -976,19 +1338,22 @@ private:
|
||||
static const QString m_flightStatuses[];
|
||||
static const QString m_hazardSeverity[];
|
||||
static const QString m_fomSources[];
|
||||
static const QString m_nacvStrings[];
|
||||
|
||||
explicit ADSBDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = 0);
|
||||
virtual ~ADSBDemodGUI();
|
||||
|
||||
QString maptilerAPIKey() const;
|
||||
|
||||
void blockApplySettings(bool block);
|
||||
void applySettings(bool force = false);
|
||||
void displaySettings();
|
||||
void applySetting(const QString& settingsKey);
|
||||
void applySettings(const QStringList& settingsKeys, bool force = false);
|
||||
void applyAllSettings();
|
||||
void displaySettings(const QStringList& settingsKeys, bool force);
|
||||
bool handleMessage(const Message& message);
|
||||
void makeUIConnections();
|
||||
void updateAbsoluteCenterFrequency();
|
||||
|
||||
void updatePosition(Aircraft *aircraft);
|
||||
bool updateLocalPosition(Aircraft *aircraft, double latitude, double longitude, bool surfacePosition);
|
||||
void clearFromMap(const QString& name);
|
||||
void sendToMap(Aircraft *aircraft, QList<SWGSDRangel::SWGMapAnimation *> *animations);
|
||||
Aircraft *getAircraft(int icao, bool &newAircraft);
|
||||
@ -1003,10 +1368,24 @@ private:
|
||||
float correlationOnes,
|
||||
unsigned crc,
|
||||
bool updateModel);
|
||||
void decodeModeS(const QByteArray data, int df, Aircraft *aircraft);
|
||||
|
||||
void decodeID(const QByteArray& data, QString& emitterCategory, QString& callsign);
|
||||
void decodeGroundspeed(const QByteArray& data, float& v, float& h);
|
||||
void decodeAirspeed(const QByteArray& data, bool& tas, int& as, bool& hdgValid, float& hdg);
|
||||
void decodeVerticalRate(const QByteArray& data, int& verticalRate);
|
||||
void updateAircraftPosition(Aircraft *aircraft, double latitude, double longitude, const QDateTime& dateTime);
|
||||
bool validateGlobalPosition(double latitude, double longitude, bool countFailure);
|
||||
bool validateLocalPosition(double latitude, double longitude, bool surfacePosition, bool countFailure);
|
||||
bool decodeGlobalPosition(int f, const double cprLat[2], const double cprLong[2], const QDateTime cprTime[2], double& latitude, double& longitude, bool countFailure);
|
||||
bool decodeLocalPosition(int f, double cprLat, double cprLong, bool onSurface, const Aircraft *aircraft, double& latitude, double& longitude, bool countFailure);
|
||||
void decodeCpr(const QByteArray& data, int& f, double& latCpr, double& lonCpr) const;
|
||||
bool decodeAltitude(const QByteArray& data, int& altFt) const;
|
||||
void decodeModeSAltitude(const QByteArray& data, const QDateTime dateTime, Aircraft *aircraft);
|
||||
void decodeModeS(const QByteArray data, const QDateTime dateTime, int df, Aircraft *aircraft);
|
||||
void decodeCommB(const QByteArray data, const QDateTime dateTime, int df, Aircraft *aircraft, bool &updatedCallsign);
|
||||
QList<SWGSDRangel::SWGMapAnimation *> *animate(QDateTime dateTime, Aircraft *aircraft);
|
||||
SWGSDRangel::SWGMapAnimation *gearAnimation(QDateTime startDateTime, bool up);
|
||||
SWGSDRangel::SWGMapAnimation *gearAngle(QDateTime startDateTime, bool flat);
|
||||
SWGSDRangel::SWGMapAnimation *flapsAnimation(QDateTime startDateTime, float currentFlaps, float flaps);
|
||||
SWGSDRangel::SWGMapAnimation *slatsAnimation(QDateTime startDateTime, bool retract);
|
||||
SWGSDRangel::SWGMapAnimation *rotorAnimation(QDateTime startDateTime, bool stop);
|
||||
@ -1019,18 +1398,18 @@ private:
|
||||
QString subAircraftString(Aircraft *aircraft, const QString &string);
|
||||
void resizeTable();
|
||||
QString getDataDir();
|
||||
void readAirportDB(const QString& filename);
|
||||
void readAirportFrequenciesDB(const QString& filename);
|
||||
void update3DModels();
|
||||
void updateAirports();
|
||||
void updateAirspaces();
|
||||
void updateNavAids();
|
||||
void updateChannelList();
|
||||
void removeAircraft(QHash<int, Aircraft *>::iterator& i, Aircraft *aircraft);
|
||||
QAction *createCheckableItem(QString& text, int idx, bool checked);
|
||||
Aircraft* findAircraftByFlight(const QString& flight);
|
||||
QString dataTimeToShortString(QDateTime dt);
|
||||
void initFlightInformation();
|
||||
void initAviationWeather();
|
||||
void setShowContainmentRadius(bool show);
|
||||
void applyMapSettings();
|
||||
void updatePhotoText(Aircraft *aircraft);
|
||||
void updatePhotoFlightInformation(Aircraft *aircraft);
|
||||
@ -1042,16 +1421,33 @@ private:
|
||||
void applyImportSettings();
|
||||
void sendAircraftReport();
|
||||
void updatePosition(float latitude, float longitude, float altitude);
|
||||
void clearOldHeading(Aircraft *aircraft, const QDateTime& dateTime, float newTrack);
|
||||
void updateQNH(const Aircraft *aircraft, float qnh);
|
||||
void setCallsign(Aircraft *aircraft, const QString& callsign);
|
||||
|
||||
void initCoverageMap();
|
||||
void clearCoverageMap();
|
||||
void updateCoverageMap(float azimuth, float elevation, float distance, float altitude);
|
||||
|
||||
void leaveEvent(QEvent*);
|
||||
void enterEvent(EnterEventType*);
|
||||
|
||||
void updateDFStats(int df);
|
||||
bool updateTCStats(int tc, int row, int low, int high);
|
||||
void resetStats();
|
||||
void plotChart();
|
||||
int countActiveAircraft();
|
||||
void averageSeries(QLineSeries *series, const QDateTime& startTime, const QDateTime& endTime);
|
||||
void legendMarkerClicked();
|
||||
|
||||
private slots:
|
||||
void on_deltaFrequency_changed(qint64 value);
|
||||
void on_rfBW_valueChanged(int value);
|
||||
void on_threshold_valueChanged(int value);
|
||||
void on_chipsThreshold_valueChanged(int value);
|
||||
void on_phaseSteps_valueChanged(int value);
|
||||
void on_tapsPerPhase_valueChanged(int value);
|
||||
void statsTable_customContextMenuRequested(QPoint pos);
|
||||
void adsbData_customContextMenuRequested(QPoint point);
|
||||
void on_adsbData_cellClicked(int row, int column);
|
||||
void on_adsbData_cellDoubleClicked(int row, int column);
|
||||
@ -1060,18 +1456,24 @@ private slots:
|
||||
void columnSelectMenu(QPoint pos);
|
||||
void columnSelectMenuChecked(bool checked = false);
|
||||
void on_spb_currentIndexChanged(int value);
|
||||
void on_correlateFullPreamble_clicked(bool checked);
|
||||
void on_demodModeS_clicked(bool checked);
|
||||
void on_feed_clicked(bool checked);
|
||||
void on_notifications_clicked();
|
||||
void on_flightInfo_clicked();
|
||||
void on_findOnMapFeature_clicked();
|
||||
void on_getOSNDB_clicked();
|
||||
void on_deleteAircraft_clicked();
|
||||
void on_getAircraftDB_clicked();
|
||||
void on_getAirportDB_clicked();
|
||||
void on_getAirspacesDB_clicked();
|
||||
void on_coverage_clicked(bool checked);
|
||||
void on_displayChart_clicked(bool checked);
|
||||
void on_stats_clicked(bool checked);
|
||||
void on_flightPaths_clicked(bool checked);
|
||||
void on_allFlightPaths_clicked(bool checked);
|
||||
void on_atcLabels_clicked(bool checked);
|
||||
void on_displayOrientation_clicked(bool checked);
|
||||
void on_displayRadius_clicked(bool checked);
|
||||
void on_ic_globalCheckStateChanged(int state);
|
||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||
void onMenuDialogCalled(const QPoint& p);
|
||||
void handleInputMessages();
|
||||
@ -1098,6 +1500,12 @@ private slots:
|
||||
void devicePositionChanged(float latitude, float longitude, float altitude);
|
||||
void requestMetar(const QString& icao);
|
||||
void weatherUpdated(const AviationWeather::METAR &metar);
|
||||
void on_manualQNH_clicked(bool checked);
|
||||
void on_qnh_valueChanged(int value);
|
||||
void clearCoverage(const QPoint& p);
|
||||
void clearStats(const QPoint& p);
|
||||
void clearChart(const QPoint& p);
|
||||
void resetChartAxes();
|
||||
|
||||
signals:
|
||||
void homePositionChanged();
|
||||
|
@ -3,7 +3,13 @@
|
||||
<file>icons/aircraft.png</file>
|
||||
<file>icons/airport.png</file>
|
||||
<file>icons/controltower.png</file>
|
||||
<file>icons/coverage.png</file>
|
||||
<file>icons/allflightpaths.png</file>
|
||||
<file>icons/vor.png</file>
|
||||
<file>icons/stats.png</file>
|
||||
<file>icons/chart.png</file>
|
||||
<file>icons/horizontal.png</file>
|
||||
<file>icons/vertical.png</file>
|
||||
<file>icons/radius.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -5,14 +5,22 @@
|
||||
<file>map/map_6_strict.qml</file>
|
||||
<file>map/ModifiedMapView.qml</file>
|
||||
<file>map/MapStation.qml</file>
|
||||
<file>map/aircraft_2engine.png</file>
|
||||
<file>map/aircraft_2enginesmall.png</file>
|
||||
<file>map/aircraft_4engine.png</file>
|
||||
<file>map/aircraft_small.png</file>
|
||||
<file>map/aircraft_large.png</file>
|
||||
<file>map/aircraft_heavy_2engine.png</file>
|
||||
<file>map/aircraft_heavy_4engine.png</file>
|
||||
<file>map/aircraft_helicopter.png</file>
|
||||
<file>map/aircraft_light.png</file>
|
||||
<file>map/aircraft_space.png</file>
|
||||
<file>map/aircraft_drone.png</file>
|
||||
<file>map/aircraft_fighter.png</file>
|
||||
<file>map/aircraft_glider.png</file>
|
||||
<file>map/spitfire.png</file>
|
||||
<file>map/a400m.png</file>
|
||||
<file>map/f35.png</file>
|
||||
<file>map/apache.png</file>
|
||||
<file>map/chinook.png</file>
|
||||
<file>map/eurofighter.png</file>
|
||||
<file>map/airport_large.png</file>
|
||||
<file>map/airport_medium.png</file>
|
||||
<file>map/airport_small.png</file>
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
// Map main ADS-B table column numbers to combo box indices
|
||||
std::vector<int> ADSBDemodNotificationDialog::m_columnMap = {
|
||||
ADSB_COL_ICAO, ADSB_COL_CALLSIGN, ADSB_COL_MODEL,
|
||||
ADSB_COL_ICAO, ADSB_COL_CALLSIGN, ADSB_COL_MODEL, ADSB_COL_TYPE,
|
||||
ADSB_COL_ALTITUDE, ADSB_COL_GROUND_SPEED, ADSB_COL_RANGE,
|
||||
ADSB_COL_CATEGORY, ADSB_COL_STATUS, ADSB_COL_SQUAWK,
|
||||
ADSB_COL_REGISTRATION, ADSB_COL_MANUFACTURER, ADSB_COL_OWNER, ADSB_COL_OPERATOR_ICAO
|
||||
@ -117,6 +117,7 @@ void ADSBDemodNotificationDialog::addRow(ADSBDemodSettings::NotificationSettings
|
||||
match->addItem("ICAO ID");
|
||||
match->addItem("Callsign");
|
||||
match->addItem("Aircraft");
|
||||
match->addItem("Type");
|
||||
match->addItem("Alt (ft)");
|
||||
match->addItem("GS (kn)");
|
||||
match->addItem("D (km)");
|
||||
|
@ -36,7 +36,8 @@ void ADSBDemodSettings::resetToDefaults()
|
||||
{
|
||||
m_inputFrequencyOffset = 0;
|
||||
m_rfBandwidth = 2*1300000;
|
||||
m_correlationThreshold = 10.0f; //<! ones/zero powers correlation threshold in dB
|
||||
m_correlationThreshold = 7.0f; //<! ones/zero powers correlation threshold in dB
|
||||
m_chipsThreshold = 0;
|
||||
m_samplesPerBit = 4;
|
||||
m_removeTimeout = 60;
|
||||
m_feedEnabled = false;
|
||||
@ -73,13 +74,13 @@ void ADSBDemodSettings::resetToDefaults()
|
||||
m_tableFontName = "Liberation Sans";
|
||||
m_tableFontSize = 9;
|
||||
m_displayDemodStats = false;
|
||||
m_correlateFullPreamble = true;
|
||||
m_demodModeS = true;
|
||||
m_autoResizeTableColumns = false;
|
||||
m_interpolatorPhaseSteps = 4; // Higher than these two values will struggle to run in real-time
|
||||
m_interpolatorTapsPerPhase = 3.5f; // without gaining much improvement in PER
|
||||
m_aviationstackAPIKey = "";
|
||||
m_checkWXAPIKey = "";
|
||||
m_maptilerAPIKey = "";
|
||||
for (int i = 0; i < ADSBDEMOD_COLUMNS; i++)
|
||||
{
|
||||
m_columnIndexes[i] = i;
|
||||
@ -98,13 +99,24 @@ void ADSBDemodSettings::resetToDefaults()
|
||||
m_displayNavAids = true;
|
||||
m_displayPhotos = true;
|
||||
m_verboseModelMatching = false;
|
||||
m_airfieldElevation = 0;
|
||||
m_aircraftMinZoom = 11;
|
||||
m_workspaceIndex = 0;
|
||||
m_hidden = false;
|
||||
m_atcLabels = true;
|
||||
m_atcCallsigns = true;
|
||||
m_transitionAlt = 6000; // Depends on airport. 18,000 in USA
|
||||
m_qnh = 1013.25;
|
||||
m_manualQNH = false;
|
||||
m_displayCoverage = false;
|
||||
m_displayChart = false;
|
||||
m_displayOrientation = false;
|
||||
m_displayRadius = false;
|
||||
for (int i = 0; i < ADSB_IC_MAX; i++) {
|
||||
m_displayIC[i] = false;
|
||||
}
|
||||
m_flightPathPaletteName = "Spectral";
|
||||
applyPalette();
|
||||
m_favourLivery = true;
|
||||
}
|
||||
|
||||
QByteArray ADSBDemodSettings::serialize() const
|
||||
@ -141,7 +153,6 @@ QByteArray ADSBDemodSettings::serialize() const
|
||||
s.writeString(25, m_tableFontName);
|
||||
s.writeS32(26, m_tableFontSize);
|
||||
s.writeBool(27, m_displayDemodStats);
|
||||
s.writeBool(28, m_correlateFullPreamble);
|
||||
s.writeBool(29, m_demodModeS);
|
||||
s.writeBool(30, m_autoResizeTableColumns);
|
||||
s.writeS32(31, m_interpolatorPhaseSteps);
|
||||
@ -165,7 +176,6 @@ QByteArray ADSBDemodSettings::serialize() const
|
||||
}
|
||||
|
||||
s.writeBool(44, m_verboseModelMatching);
|
||||
s.writeS32(45, m_airfieldElevation);
|
||||
|
||||
s.writeBool(46, m_exportClientEnabled);
|
||||
s.writeBool(47, m_exportServerEnabled);
|
||||
@ -192,6 +202,19 @@ QByteArray ADSBDemodSettings::serialize() const
|
||||
s.writeS32(67, m_transitionAlt);
|
||||
s.writeString(68, m_amDemod);
|
||||
|
||||
s.writeFloat(69, m_qnh);
|
||||
s.writeBool(70, m_manualQNH);
|
||||
|
||||
s.writeBool(71, m_displayCoverage);
|
||||
s.writeBool(72, m_displayChart);
|
||||
s.writeBool(73, m_displayOrientation);
|
||||
s.writeBool(74, m_displayRadius);
|
||||
s.writeString(75, m_flightPathPaletteName);
|
||||
s.writeS32(76, m_chipsThreshold);
|
||||
s.writeBool(77, m_favourLivery);
|
||||
|
||||
s.writeString(78, m_maptilerAPIKey);
|
||||
|
||||
for (int i = 0; i < ADSBDEMOD_COLUMNS; i++) {
|
||||
s.writeS32(100 + i, m_columnIndexes[i]);
|
||||
}
|
||||
@ -229,7 +252,7 @@ bool ADSBDemodSettings::deserialize(const QByteArray& data)
|
||||
d.readS32(1, &tmp, 0);
|
||||
m_inputFrequencyOffset = tmp;
|
||||
d.readReal(2, &m_rfBandwidth, 2*1300000);
|
||||
d.readReal(3, &m_correlationThreshold, 0.0f);
|
||||
d.readReal(3, &m_correlationThreshold, 7.0f);
|
||||
d.readS32(4, &m_samplesPerBit, 4);
|
||||
d.readS32(5, &m_removeTimeout, 60);
|
||||
d.readBool(6, &m_feedEnabled, false);
|
||||
@ -268,7 +291,6 @@ bool ADSBDemodSettings::deserialize(const QByteArray& data)
|
||||
d.readString(25, &m_tableFontName, "Liberation Sans");
|
||||
d.readS32(26, &m_tableFontSize, 9);
|
||||
d.readBool(27, &m_displayDemodStats, false);
|
||||
d.readBool(28, &m_correlateFullPreamble, true);
|
||||
d.readBool(29, &m_demodModeS, true);
|
||||
d.readBool(30, &m_autoResizeTableColumns, false);
|
||||
d.readS32(31, &m_interpolatorPhaseSteps, 4);
|
||||
@ -296,7 +318,6 @@ bool ADSBDemodSettings::deserialize(const QByteArray& data)
|
||||
}
|
||||
|
||||
d.readBool(44, &m_verboseModelMatching, false);
|
||||
d.readS32(45, &m_airfieldElevation, 0);
|
||||
|
||||
d.readBool(46, &m_exportClientEnabled, true);
|
||||
d.readBool(47, &m_exportServerEnabled, true);
|
||||
@ -328,6 +349,21 @@ bool ADSBDemodSettings::deserialize(const QByteArray& data)
|
||||
d.readS32(67, &m_transitionAlt, 6000);
|
||||
d.readString(68, &m_amDemod);
|
||||
|
||||
d.readFloat(69, &m_qnh, 1013.25);
|
||||
d.readBool(70, &m_manualQNH, false);
|
||||
|
||||
d.readBool(71, &m_displayCoverage, false);
|
||||
d.readBool(72, &m_displayChart, false);
|
||||
d.readBool(73, &m_displayOrientation, false);
|
||||
d.readBool(74, &m_displayRadius, false);
|
||||
d.readString(75, &m_flightPathPaletteName, "Spectral");
|
||||
d.readS32(76, &m_chipsThreshold, 0);
|
||||
d.readBool(77, &m_favourLivery, true);
|
||||
|
||||
d.readString(78, &m_maptilerAPIKey, "");
|
||||
|
||||
applyPalette();
|
||||
|
||||
#ifdef LINUX
|
||||
if (m_mapProvider == "osm") {
|
||||
m_mapProvider = "mapboxgl";
|
||||
@ -401,3 +437,509 @@ void ADSBDemodSettings::NotificationSettings::updateRegularExpression()
|
||||
qDebug() << "ADSBDemod: Regular expression is not valid: " << m_regExp;
|
||||
}
|
||||
}
|
||||
|
||||
void ADSBDemodSettings::applySettings(const QStringList& settingsKeys, const ADSBDemodSettings& settings)
|
||||
{
|
||||
if (settingsKeys.contains("inputFrequencyOffset")) {
|
||||
m_inputFrequencyOffset = settings.m_inputFrequencyOffset;
|
||||
}
|
||||
if (settingsKeys.contains("rfBandwidth")) {
|
||||
m_rfBandwidth = settings.m_rfBandwidth;
|
||||
}
|
||||
if (settingsKeys.contains("correlationThreshold")) {
|
||||
m_correlationThreshold = settings.m_correlationThreshold;
|
||||
}
|
||||
if (settingsKeys.contains("chipsThreshold")) {
|
||||
m_chipsThreshold = settings.m_chipsThreshold;
|
||||
}
|
||||
if (settingsKeys.contains("samplesPerBit")) {
|
||||
m_samplesPerBit = settings.m_samplesPerBit;
|
||||
}
|
||||
if (settingsKeys.contains("removeTimeout")) {
|
||||
m_removeTimeout = settings.m_removeTimeout;
|
||||
}
|
||||
if (settingsKeys.contains("feedEnabled")) {
|
||||
m_feedEnabled = settings.m_feedEnabled;
|
||||
}
|
||||
if (settingsKeys.contains("exportClientEnabled")) {
|
||||
m_exportClientEnabled = settings.m_exportClientEnabled;
|
||||
}
|
||||
if (settingsKeys.contains("exportClientHost")) {
|
||||
m_exportClientHost = settings.m_exportClientHost;
|
||||
}
|
||||
if (settingsKeys.contains("exportClientPort")) {
|
||||
m_exportClientPort = settings.m_exportClientPort;
|
||||
}
|
||||
if (settingsKeys.contains("exportClientFormat")) {
|
||||
m_exportClientFormat = settings.m_exportClientFormat;
|
||||
}
|
||||
if (settingsKeys.contains("exportServerEnabled")) {
|
||||
m_exportServerEnabled = settings.m_exportServerEnabled;
|
||||
}
|
||||
if (settingsKeys.contains("exportServerPort")) {
|
||||
m_exportServerPort = settings.m_exportServerPort;
|
||||
}
|
||||
if (settingsKeys.contains("importEnabled")) {
|
||||
m_importEnabled = settings.m_importEnabled;
|
||||
}
|
||||
if (settingsKeys.contains("importHost")) {
|
||||
m_importHost = settings.m_importHost;
|
||||
}
|
||||
if (settingsKeys.contains("importUsername")) {
|
||||
m_importUsername = settings.m_importUsername;
|
||||
}
|
||||
if (settingsKeys.contains("importPassword")) {
|
||||
m_importPassword = settings.m_importPassword;
|
||||
}
|
||||
if (settingsKeys.contains("importParameters")) {
|
||||
m_importParameters = settings.m_importParameters;
|
||||
}
|
||||
if (settingsKeys.contains("importPeriod")) {
|
||||
m_importPeriod = settings.m_importPeriod;
|
||||
}
|
||||
if (settingsKeys.contains("importMinLatitude")) {
|
||||
m_importMinLatitude = settings.m_importMinLatitude;
|
||||
}
|
||||
if (settingsKeys.contains("importMaxLatitude")) {
|
||||
m_importMaxLatitude = settings.m_importMaxLatitude;
|
||||
}
|
||||
if (settingsKeys.contains("importMinLongitude")) {
|
||||
m_importMinLongitude = settings.m_importMinLongitude;
|
||||
}
|
||||
if (settingsKeys.contains("importMaxLongitude")) {
|
||||
m_importMaxLongitude = settings.m_importMaxLongitude;
|
||||
}
|
||||
if (settingsKeys.contains("rgbColor")) {
|
||||
m_rgbColor = settings.m_rgbColor;
|
||||
}
|
||||
if (settingsKeys.contains("title")) {
|
||||
m_title = settings.m_title;
|
||||
}
|
||||
if (settingsKeys.contains("useReverseAPI")) {
|
||||
m_useReverseAPI = settings.m_useReverseAPI;
|
||||
}
|
||||
if (settingsKeys.contains("reverseAPIAddress")) {
|
||||
m_reverseAPIAddress = settings.m_reverseAPIAddress;
|
||||
}
|
||||
if (settingsKeys.contains("reverseAPIPort")) {
|
||||
m_reverseAPIPort = settings.m_reverseAPIPort;
|
||||
}
|
||||
if (settingsKeys.contains("reverseAPIDeviceIndex")) {
|
||||
m_reverseAPIDeviceIndex = settings.m_reverseAPIDeviceIndex;
|
||||
}
|
||||
if (settingsKeys.contains("columnIndexes")) {
|
||||
std::copy(std::begin(settings.m_columnIndexes), std::end(settings.m_columnIndexes), std::begin(m_columnIndexes));
|
||||
}
|
||||
if (settingsKeys.contains("columnSizes")) {
|
||||
std::copy(std::begin(settings.m_columnSizes), std::end(settings.m_columnIndexes), std::begin(m_columnSizes));
|
||||
}
|
||||
if (settingsKeys.contains("airportRange")) {
|
||||
m_airportRange = settings.m_airportRange;
|
||||
}
|
||||
if (settingsKeys.contains("airportMinimumSize")) {
|
||||
m_airportMinimumSize = settings.m_airportMinimumSize;
|
||||
}
|
||||
if (settingsKeys.contains("displayHeliports")) {
|
||||
m_displayHeliports = settings.m_displayHeliports;
|
||||
}
|
||||
if (settingsKeys.contains("flightPaths")) {
|
||||
m_flightPaths = settings.m_flightPaths;
|
||||
}
|
||||
if (settingsKeys.contains("allFlightPaths")) {
|
||||
m_allFlightPaths = settings.m_allFlightPaths;
|
||||
}
|
||||
if (settingsKeys.contains("siUnits")) {
|
||||
m_siUnits = settings.m_siUnits;
|
||||
}
|
||||
if (settingsKeys.contains("tableFontName")) {
|
||||
m_tableFontName = settings.m_tableFontName;
|
||||
}
|
||||
if (settingsKeys.contains("tableFontSize")) {
|
||||
m_tableFontSize = settings.m_tableFontSize;
|
||||
}
|
||||
if (settingsKeys.contains("displayDemodStats")) {
|
||||
m_displayDemodStats = settings.m_displayDemodStats;
|
||||
}
|
||||
if (settingsKeys.contains("demodModeS")) {
|
||||
m_demodModeS = settings.m_demodModeS;
|
||||
}
|
||||
if (settingsKeys.contains("amDemod")) {
|
||||
m_amDemod = settings.m_amDemod;
|
||||
}
|
||||
if (settingsKeys.contains("autoResizeTableColumns")) {
|
||||
m_autoResizeTableColumns = settings.m_autoResizeTableColumns;
|
||||
}
|
||||
if (settingsKeys.contains("interpolatorPhaseSteps")) {
|
||||
m_interpolatorPhaseSteps = settings.m_interpolatorPhaseSteps;
|
||||
}
|
||||
if (settingsKeys.contains("interpolatorTapsPerPhase")) {
|
||||
m_interpolatorTapsPerPhase = settings.m_interpolatorTapsPerPhase;
|
||||
}
|
||||
if (settingsKeys.contains("notificationSettings")) {
|
||||
m_notificationSettings = settings.m_notificationSettings;
|
||||
}
|
||||
if (settingsKeys.contains("aviationstackAPIKey")) {
|
||||
m_aviationstackAPIKey = settings.m_aviationstackAPIKey;
|
||||
}
|
||||
if (settingsKeys.contains("checkWXAPIKey")) {
|
||||
m_checkWXAPIKey = settings.m_checkWXAPIKey;
|
||||
}
|
||||
if (settingsKeys.contains("maptilerAPIKey")) {
|
||||
m_maptilerAPIKey = settings.m_maptilerAPIKey;
|
||||
}
|
||||
if (settingsKeys.contains("logFilename")) {
|
||||
m_logFilename = settings.m_logFilename;
|
||||
}
|
||||
if (settingsKeys.contains("logEnabled")) {
|
||||
m_logEnabled = settings.m_logEnabled;
|
||||
}
|
||||
if (settingsKeys.contains("airspaces")) {
|
||||
m_airspaces = settings.m_airspaces;
|
||||
}
|
||||
if (settingsKeys.contains("airspaceRange")) {
|
||||
m_airspaceRange = settings.m_airspaceRange;
|
||||
}
|
||||
if (settingsKeys.contains("mapProvider")) {
|
||||
m_mapProvider = settings.m_mapProvider;
|
||||
}
|
||||
if (settingsKeys.contains("mapType")) {
|
||||
m_mapType = settings.m_mapType;
|
||||
}
|
||||
if (settingsKeys.contains("displayNavAids")) {
|
||||
m_displayNavAids = settings.m_displayNavAids;
|
||||
}
|
||||
if (settingsKeys.contains("displayPhotos")) {
|
||||
m_displayPhotos = settings.m_displayPhotos;
|
||||
}
|
||||
if (settingsKeys.contains("verboseModelMatching")) {
|
||||
m_verboseModelMatching = settings.m_verboseModelMatching;
|
||||
}
|
||||
if (settingsKeys.contains("aircraftMinZoom")) {
|
||||
m_aircraftMinZoom = settings.m_aircraftMinZoom;
|
||||
}
|
||||
if (settingsKeys.contains("atcLabels")) {
|
||||
m_atcLabels = settings.m_atcLabels;
|
||||
}
|
||||
if (settingsKeys.contains("atcCallsigns")) {
|
||||
m_atcCallsigns = settings.m_atcCallsigns;
|
||||
}
|
||||
if (settingsKeys.contains("transitionAlt")) {
|
||||
m_transitionAlt = settings.m_transitionAlt;
|
||||
}
|
||||
if (settingsKeys.contains("qnh")) {
|
||||
m_qnh = settings.m_qnh;
|
||||
}
|
||||
if (settingsKeys.contains("manualQNH")) {
|
||||
m_manualQNH = settings.m_manualQNH;
|
||||
}
|
||||
if (settingsKeys.contains("displayCoverage")) {
|
||||
m_displayCoverage = settings.m_displayCoverage;
|
||||
}
|
||||
if (settingsKeys.contains("displayChart")) {
|
||||
m_displayChart = settings.m_displayChart;
|
||||
}
|
||||
if (settingsKeys.contains("displayOrientation")) {
|
||||
m_displayOrientation = settings.m_displayOrientation;
|
||||
}
|
||||
if (settingsKeys.contains("displayRadius")) {
|
||||
m_displayRadius = settings.m_displayRadius;
|
||||
}
|
||||
if (settingsKeys.contains("flightPathPaletteName"))
|
||||
{
|
||||
m_flightPathPaletteName = settings.m_flightPathPaletteName;
|
||||
applyPalette();
|
||||
}
|
||||
if (settingsKeys.contains("favourLivery")) {
|
||||
m_favourLivery = settings.m_favourLivery;
|
||||
}
|
||||
}
|
||||
|
||||
QString ADSBDemodSettings::getDebugString(const QStringList& settingsKeys, bool force) const
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
|
||||
if (settingsKeys.contains("inputFrequencyOffset") || force) {
|
||||
ostr << " m_inputFrequencyOffset: " << m_inputFrequencyOffset;
|
||||
}
|
||||
if (settingsKeys.contains("rfBandwidth") || force) {
|
||||
ostr << " m_rfBandwidth: " << m_rfBandwidth;
|
||||
}
|
||||
if (settingsKeys.contains("correlationThreshold") || force) {
|
||||
ostr << " m_correlationThreshold: " << m_correlationThreshold;
|
||||
}
|
||||
if (settingsKeys.contains("chipsThreshold") || force) {
|
||||
ostr << " m_chipsThreshold: " << m_chipsThreshold;
|
||||
}
|
||||
if (settingsKeys.contains("samplesPerBit") || force) {
|
||||
ostr << " m_samplesPerBit: " << m_samplesPerBit;
|
||||
}
|
||||
if (settingsKeys.contains("removeTimeout") || force) {
|
||||
ostr << " m_removeTimeout: " << m_removeTimeout;
|
||||
}
|
||||
if (settingsKeys.contains("feedEnabled") || force) {
|
||||
ostr << " m_feedEnabled: " << m_feedEnabled;
|
||||
}
|
||||
if (settingsKeys.contains("exportClientEnabled") || force) {
|
||||
ostr << " m_exportClientEnabled: " << m_exportClientEnabled;
|
||||
}
|
||||
if (settingsKeys.contains("exportClientHost") || force) {
|
||||
ostr << " m_exportClientHost: " << m_exportClientHost.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("exportClientPort") || force) {
|
||||
ostr << " m_exportClientPort: " << m_exportClientPort;
|
||||
}
|
||||
if (settingsKeys.contains("exportClientFormat") || force) {
|
||||
ostr << " m_exportClientFormat: " << m_exportClientFormat;
|
||||
}
|
||||
if (settingsKeys.contains("exportServerEnabled") || force) {
|
||||
ostr << " m_exportServerEnabled: " << m_exportServerEnabled;
|
||||
}
|
||||
if (settingsKeys.contains("exportServerPort") || force) {
|
||||
ostr << " m_exportServerPort: " << m_exportServerPort;
|
||||
}
|
||||
if (settingsKeys.contains("importEnabled") || force) {
|
||||
ostr << " m_importEnabled: " << m_importEnabled;
|
||||
}
|
||||
if (settingsKeys.contains("importHost") || force) {
|
||||
ostr << " m_importHost: " << m_importHost.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("importUsername") || force) {
|
||||
ostr << " m_importUsername: " << m_importUsername.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("importPassword") || force) {
|
||||
ostr << " m_importPassword: " << m_importPassword.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("importParameters") || force) {
|
||||
ostr << " m_importParameters: " << m_importParameters.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("importPeriod") || force) {
|
||||
ostr << " m_importPeriod: " << m_importPeriod;
|
||||
}
|
||||
if (settingsKeys.contains("importMinLatitude") || force) {
|
||||
ostr << " m_importMinLatitude: " << m_importMinLatitude.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("importMaxLatitude") || force) {
|
||||
ostr << " m_importMaxLatitude: " << m_importMaxLatitude.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("importMinLongitude") || force) {
|
||||
ostr << " m_importMinLongitude: " << m_importMinLongitude.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("importMaxLongitude") || force) {
|
||||
ostr << " m_importMaxLongitude: " << m_importMaxLongitude.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("title") || force) {
|
||||
ostr << " m_title: " << m_title.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("useReverseAPI") || force) {
|
||||
ostr << " m_useReverseAPI: " << m_useReverseAPI;
|
||||
}
|
||||
if (settingsKeys.contains("reverseAPIAddress") || force) {
|
||||
ostr << " m_reverseAPIAddress: " << m_reverseAPIAddress.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("reverseAPIPort") || force) {
|
||||
ostr << " m_reverseAPIPort: " << m_reverseAPIPort;
|
||||
}
|
||||
if (settingsKeys.contains("reverseAPIDeviceIndex") || force) {
|
||||
ostr << " m_reverseAPIDeviceIndex: " << m_reverseAPIDeviceIndex;
|
||||
}
|
||||
if (settingsKeys.contains("airportRange") || force) {
|
||||
ostr << " m_airportRange: " << m_airportRange;
|
||||
}
|
||||
if (settingsKeys.contains("airportMinimumSize") || force) {
|
||||
ostr << " m_airportMinimumSize: " << m_airportMinimumSize;
|
||||
}
|
||||
if (settingsKeys.contains("displayHeliports") || force) {
|
||||
ostr << " m_displayHeliports: " << m_displayHeliports;
|
||||
}
|
||||
if (settingsKeys.contains("flightPaths") || force) {
|
||||
ostr << " m_flightPaths: " << m_flightPaths;
|
||||
}
|
||||
if (settingsKeys.contains("allFlightPaths") || force) {
|
||||
ostr << " m_allFlightPaths: " << m_allFlightPaths;
|
||||
}
|
||||
if (settingsKeys.contains("siUnits") || force) {
|
||||
ostr << " m_siUnits: " << m_siUnits;
|
||||
}
|
||||
if (settingsKeys.contains("tableFontName") || force) {
|
||||
ostr << " m_tableFontName: " << m_tableFontName.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("tableFontSize") || force) {
|
||||
ostr << " m_tableFontSize: " << m_tableFontSize;
|
||||
}
|
||||
if (settingsKeys.contains("displayDemodStats") || force) {
|
||||
ostr << " m_displayDemodStats: " << m_displayDemodStats;
|
||||
}
|
||||
if (settingsKeys.contains("demodModeS") || force) {
|
||||
ostr << " m_demodModeS: " << m_demodModeS;
|
||||
}
|
||||
if (settingsKeys.contains("amDemod") || force) {
|
||||
ostr << " m_amDemod: " << m_amDemod.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("autoResizeTableColumns") || force) {
|
||||
ostr << " m_autoResizeTableColumns: " << m_autoResizeTableColumns;
|
||||
}
|
||||
if (settingsKeys.contains("interpolatorPhaseSteps") || force) {
|
||||
ostr << " m_interpolatorPhaseSteps: " << m_interpolatorPhaseSteps;
|
||||
}
|
||||
if (settingsKeys.contains("notificationSettings") || force) {
|
||||
//ostr << " m_notificationSettings: " << m_notificationSettings.join(",").toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("aviationstackAPIKey") || force) {
|
||||
ostr << " m_aviationstackAPIKey: " << m_aviationstackAPIKey.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("checkWXAPIKey") || force) {
|
||||
ostr << " m_checkWXAPIKey: " << m_checkWXAPIKey.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("maptilerAPIKey") || force) {
|
||||
ostr << " m_maptilerAPIKey: " << m_maptilerAPIKey.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("logFilename") || force) {
|
||||
ostr << " m_logFilename: " << m_logFilename.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("logEnabled") || force) {
|
||||
ostr << " m_logEnabled: " << m_logEnabled;
|
||||
}
|
||||
if (settingsKeys.contains("airspaces") || force) {
|
||||
ostr << " m_airspaces: " << m_airspaces.join(",").toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("airspaceRange") || force) {
|
||||
ostr << " m_airspaceRange: " << m_airspaceRange;
|
||||
}
|
||||
if (settingsKeys.contains("mapProvider") || force) {
|
||||
ostr << " m_mapProvider: " << m_mapProvider.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("mapType") || force) {
|
||||
ostr << " m_mapType: " << m_mapType;
|
||||
}
|
||||
if (settingsKeys.contains("displayNavAids") || force) {
|
||||
ostr << " m_displayNavAids: " << m_displayNavAids;
|
||||
}
|
||||
if (settingsKeys.contains("displayPhotos") || force) {
|
||||
ostr << " m_displayPhotos: " << m_displayPhotos;
|
||||
}
|
||||
if (settingsKeys.contains("verboseModelMatching") || force) {
|
||||
ostr << " m_verboseModelMatching: " << m_verboseModelMatching;
|
||||
}
|
||||
if (settingsKeys.contains("aircraftMinZoom") || force) {
|
||||
ostr << " m_aircraftMinZoom: " << m_aircraftMinZoom;
|
||||
}
|
||||
if (settingsKeys.contains("atcLabels") || force) {
|
||||
ostr << " m_atcLabels: " << m_atcLabels;
|
||||
}
|
||||
if (settingsKeys.contains("atcCallsigns") || force) {
|
||||
ostr << " m_atcCallsigns: " << m_atcCallsigns;
|
||||
}
|
||||
if (settingsKeys.contains("transitionAlt") || force) {
|
||||
ostr << " m_transitionAlt: " << m_transitionAlt;
|
||||
}
|
||||
if (settingsKeys.contains("qnh") || force) {
|
||||
ostr << " m_qnh: " << m_qnh;
|
||||
}
|
||||
if (settingsKeys.contains("manualQNH") || force) {
|
||||
ostr << " m_manualQNH: " << m_manualQNH;
|
||||
}
|
||||
if (settingsKeys.contains("displayCoverage") || force) {
|
||||
ostr << " m_displayCoverage: " << m_displayCoverage;
|
||||
}
|
||||
if (settingsKeys.contains("displayChart") || force) {
|
||||
ostr << " m_displayChart: " << m_displayChart;
|
||||
}
|
||||
if (settingsKeys.contains("displayOrientation") || force) {
|
||||
ostr << " m_displayOrientation: " << m_displayOrientation;
|
||||
}
|
||||
if (settingsKeys.contains("displayRadius") || force) {
|
||||
ostr << " m_displayRadius: " << m_displayRadius;
|
||||
}
|
||||
if (settingsKeys.contains("flightPathPaletteName") || force) {
|
||||
ostr << " m_flightPathPaletteName: " << m_flightPathPaletteName.toStdString();
|
||||
}
|
||||
if (settingsKeys.contains("favourLivery") || force) {
|
||||
ostr << " m_favourLivery: " << m_favourLivery;
|
||||
}
|
||||
|
||||
return QString(ostr.str().c_str());
|
||||
}
|
||||
|
||||
void ADSBDemodSettings::applyPalette()
|
||||
{
|
||||
if (m_palettes.contains(m_flightPathPaletteName)) {
|
||||
m_flightPathPalette = m_palettes.value(m_flightPathPaletteName);
|
||||
} else {
|
||||
m_flightPathPalette = m_rainbowPalette;
|
||||
}
|
||||
}
|
||||
|
||||
const QVariant ADSBDemodSettings::m_rainbowPalette[8] = {
|
||||
QVariant(QColor(0xff, 0x00, 0x00)),
|
||||
QVariant(QColor(0xff, 0x7f, 0x00)),
|
||||
QVariant(QColor(0xff, 0xff, 0x00)),
|
||||
QVariant(QColor(0xf7, 0xff, 0x00)),
|
||||
QVariant(QColor(0x00, 0xff, 0x00)),
|
||||
QVariant(QColor(0x00, 0xff, 0x7f)),
|
||||
QVariant(QColor(0x00, 0xff, 0xff)),
|
||||
QVariant(QColor(0x00, 0x7f, 0xff)),
|
||||
};
|
||||
|
||||
const QVariant ADSBDemodSettings::m_pastelPalette[8] = {
|
||||
QVariant(QColor(0xff, 0xad, 0xad)),
|
||||
QVariant(QColor(0xff, 0xd6, 0xa5)),
|
||||
QVariant(QColor(0xfd, 0xff, 0xb6)),
|
||||
QVariant(QColor(0xca, 0xff, 0xbf)),
|
||||
QVariant(QColor(0x9b, 0xf6, 0xff)),
|
||||
QVariant(QColor(0xa0, 0xc4, 0xff)),
|
||||
QVariant(QColor(0xbd, 0xb2, 0xff)),
|
||||
QVariant(QColor(0xff, 0xc6, 0xff)),
|
||||
};
|
||||
|
||||
const QVariant ADSBDemodSettings::m_spectralPalette[8] = {
|
||||
QVariant(QColor(0xd5, 0x3e, 0x4f)),
|
||||
QVariant(QColor(0xf4, 0x6d, 0x43)),
|
||||
QVariant(QColor(0xfd, 0xae, 0x61)),
|
||||
QVariant(QColor(0xfe, 0xe0, 0x8b)),
|
||||
QVariant(QColor(0xe6, 0xf5, 0x98)),
|
||||
QVariant(QColor(0xab, 0xdd, 0xa4)),
|
||||
QVariant(QColor(0x66, 0xc2, 0xa5)),
|
||||
QVariant(QColor(0x32, 0x88, 0xbd)),
|
||||
};
|
||||
|
||||
const QVariant ADSBDemodSettings::m_bluePalette[8] = {
|
||||
QVariant(QColor(0xde, 0xeb, 0xf7)),
|
||||
QVariant(QColor(0xc6, 0xdb, 0xef)),
|
||||
QVariant(QColor(0x9e, 0xca, 0xe1)),
|
||||
QVariant(QColor(0x6b, 0xae, 0xd6)),
|
||||
QVariant(QColor(0x42, 0x92, 0xc6)),
|
||||
QVariant(QColor(0x21, 0x71, 0xb5)),
|
||||
QVariant(QColor(0x08, 0x51, 0x9c)),
|
||||
QVariant(QColor(0x08, 0x30, 0x6b)),
|
||||
};
|
||||
|
||||
const QVariant ADSBDemodSettings::m_purplePalette[8] = {
|
||||
QVariant(QColor(0xcc, 0xaf, 0xf2)),
|
||||
QVariant(QColor(0xb6, 0x99, 0xe0)),
|
||||
QVariant(QColor(0xa0, 0x84, 0xcf)),
|
||||
QVariant(QColor(0x8a, 0x6f, 0xbd)),
|
||||
QVariant(QColor(0x76, 0x5a, 0xac)),
|
||||
QVariant(QColor(0x62, 0x45, 0x9a)),
|
||||
QVariant(QColor(0x4f, 0x30, 0x89)),
|
||||
QVariant(QColor(0x3e, 0x18, 0x78)),
|
||||
};
|
||||
|
||||
const QVariant ADSBDemodSettings::m_greyPalette[8] = {
|
||||
QVariant(QColor(0x80, 0x80, 0x80)),
|
||||
QVariant(QColor(0x80, 0x80, 0x80)),
|
||||
QVariant(QColor(0x80, 0x80, 0x80)),
|
||||
QVariant(QColor(0x80, 0x80, 0x80)),
|
||||
QVariant(QColor(0x80, 0x80, 0x80)),
|
||||
QVariant(QColor(0x80, 0x80, 0x80)),
|
||||
QVariant(QColor(0x80, 0x80, 0x80)),
|
||||
QVariant(QColor(0x80, 0x80, 0x80)),
|
||||
};
|
||||
|
||||
const QHash<QString, const QVariant *> ADSBDemodSettings::m_palettes = {
|
||||
{"Rainbow", &ADSBDemodSettings::m_rainbowPalette[0]},
|
||||
{"Pastel", &ADSBDemodSettings::m_pastelPalette[0]},
|
||||
{"Spectral", &ADSBDemodSettings::m_spectralPalette[0]},
|
||||
{"Blues", &ADSBDemodSettings::m_bluePalette[0]},
|
||||
{"Purples", &ADSBDemodSettings::m_purplePalette[0]},
|
||||
{"Grey", &ADSBDemodSettings::m_greyPalette[0]},
|
||||
};
|
@ -29,63 +29,89 @@
|
||||
class Serializable;
|
||||
|
||||
// Number of columns in the table
|
||||
#define ADSBDEMOD_COLUMNS 54
|
||||
#define ADSBDEMOD_COLUMNS 78
|
||||
|
||||
// ADS-B table columns
|
||||
#define ADSB_COL_ICAO 0
|
||||
#define ADSB_COL_CALLSIGN 1
|
||||
#define ADSB_COL_ATC_CALLSIGN 2
|
||||
#define ADSB_COL_MODEL 3
|
||||
#define ADSB_COL_AIRLINE 4
|
||||
#define ADSB_COL_COUNTRY 5
|
||||
#define ADSB_COL_GROUND_SPEED 6
|
||||
#define ADSB_COL_TRUE_AIRSPEED 7
|
||||
#define ADSB_COL_INDICATED_AIRSPEED 8
|
||||
#define ADSB_COL_MACH 9
|
||||
#define ADSB_COL_SEL_ALTITUDE 10
|
||||
#define ADSB_COL_ALTITUDE 11
|
||||
#define ADSB_COL_VERTICALRATE 12
|
||||
#define ADSB_COL_SEL_HEADING 13
|
||||
#define ADSB_COL_HEADING 14
|
||||
#define ADSB_COL_TURNRATE 15
|
||||
#define ADSB_COL_ROLL 16
|
||||
#define ADSB_COL_RANGE 17
|
||||
#define ADSB_COL_AZEL 18
|
||||
#define ADSB_COL_CATEGORY 19
|
||||
#define ADSB_COL_STATUS 20
|
||||
#define ADSB_COL_SQUAWK 21
|
||||
#define ADSB_COL_REGISTRATION 22
|
||||
#define ADSB_COL_REGISTERED 23
|
||||
#define ADSB_COL_MANUFACTURER 24
|
||||
#define ADSB_COL_OWNER 25
|
||||
#define ADSB_COL_OPERATOR_ICAO 26
|
||||
#define ADSB_COL_AP 27
|
||||
#define ADSB_COL_V_MODE 28
|
||||
#define ADSB_COL_L_MODE 29
|
||||
#define ADSB_COL_BARO 30
|
||||
#define ADSB_COL_HEADWIND 31
|
||||
#define ADSB_COL_EST_AIR_TEMP 32
|
||||
#define ADSB_COL_WIND_SPEED 33
|
||||
#define ADSB_COL_WIND_DIR 34
|
||||
#define ADSB_COL_STATIC_PRESSURE 35
|
||||
#define ADSB_COL_STATIC_AIR_TEMP 36
|
||||
#define ADSB_COL_HUMIDITY 37
|
||||
#define ADSB_COL_LATITUDE 38
|
||||
#define ADSB_COL_LONGITUDE 39
|
||||
#define ADSB_COL_TIME 40
|
||||
#define ADSB_COL_FRAMECOUNT 41
|
||||
#define ADSB_COL_TIS_B 42
|
||||
#define ADSB_COL_CORRELATION 43
|
||||
#define ADSB_COL_RSSI 44
|
||||
#define ADSB_COL_FLIGHT_STATUS 45
|
||||
#define ADSB_COL_DEP 46
|
||||
#define ADSB_COL_ARR 47
|
||||
#define ADSB_COL_STD 48
|
||||
#define ADSB_COL_ETD 49
|
||||
#define ADSB_COL_ATD 50
|
||||
#define ADSB_COL_STA 51
|
||||
#define ADSB_COL_ETA 52
|
||||
#define ADSB_COL_ATA 53
|
||||
#define ADSB_COL_TYPE 4
|
||||
#define ADSB_COL_SIDEVIEW 5
|
||||
#define ADSB_COL_AIRLINE 6
|
||||
#define ADSB_COL_COUNTRY 7
|
||||
#define ADSB_COL_GROUND_SPEED 8
|
||||
#define ADSB_COL_TRUE_AIRSPEED 9
|
||||
#define ADSB_COL_INDICATED_AIRSPEED 10
|
||||
#define ADSB_COL_MACH 11
|
||||
#define ADSB_COL_SEL_ALTITUDE 12
|
||||
#define ADSB_COL_ALTITUDE 13
|
||||
#define ADSB_COL_VERTICALRATE 14
|
||||
#define ADSB_COL_SEL_HEADING 15
|
||||
#define ADSB_COL_HEADING 16
|
||||
#define ADSB_COL_TRACK 17
|
||||
#define ADSB_COL_TURNRATE 18
|
||||
#define ADSB_COL_ROLL 19
|
||||
#define ADSB_COL_RANGE 20
|
||||
#define ADSB_COL_AZEL 21
|
||||
#define ADSB_COL_CATEGORY 22
|
||||
#define ADSB_COL_STATUS 23
|
||||
#define ADSB_COL_SQUAWK 24
|
||||
#define ADSB_COL_IDENT 25
|
||||
#define ADSB_COL_REGISTRATION 26
|
||||
#define ADSB_COL_REGISTERED 27
|
||||
#define ADSB_COL_MANUFACTURER 28
|
||||
#define ADSB_COL_OWNER 29
|
||||
#define ADSB_COL_OPERATOR_ICAO 30
|
||||
#define ADSB_COL_AP 31
|
||||
#define ADSB_COL_V_MODE 32
|
||||
#define ADSB_COL_L_MODE 33
|
||||
#define ADSB_COL_TCAS 34
|
||||
#define ADSB_COL_ACAS 35
|
||||
#define ADSB_COL_RA 36
|
||||
#define ADSB_COL_MAX_SPEED 37
|
||||
#define ADSB_COL_VERSION 38
|
||||
#define ADSB_COL_LENGTH 39
|
||||
#define ADSB_COL_WIDTH 40
|
||||
#define ADSB_COL_BARO 41
|
||||
#define ADSB_COL_HEADWIND 42
|
||||
#define ADSB_COL_EST_AIR_TEMP 43
|
||||
#define ADSB_COL_WIND_SPEED 44
|
||||
#define ADSB_COL_WIND_DIR 45
|
||||
#define ADSB_COL_STATIC_PRESSURE 46
|
||||
#define ADSB_COL_STATIC_AIR_TEMP 47
|
||||
#define ADSB_COL_HUMIDITY 48
|
||||
#define ADSB_COL_LATITUDE 49
|
||||
#define ADSB_COL_LONGITUDE 50
|
||||
#define ADSB_COL_IC 51
|
||||
#define ADSB_COL_TIME 52
|
||||
#define ADSB_COL_FRAMECOUNT 53
|
||||
#define ADSB_COL_ADSB_FRAMECOUNT 54
|
||||
#define ADSB_COL_MODES_FRAMECOUNT 55
|
||||
#define ADSB_COL_NON_TRANSPONDER 56
|
||||
#define ADSB_COL_TIS_B_FRAMECOUNT 57
|
||||
#define ADSB_COL_ADSR_FRAMECOUNT 58
|
||||
#define ADSB_COL_RADIUS 59
|
||||
#define ADSB_COL_NACP 60
|
||||
#define ADSB_COL_NACV 61
|
||||
#define ADSB_COL_GVA 62
|
||||
#define ADSB_COL_NIC 63
|
||||
#define ADSB_COL_NIC_BARO 64
|
||||
#define ADSB_COL_SIL 65
|
||||
#define ADSB_COL_CORRELATION 66
|
||||
#define ADSB_COL_RSSI 67
|
||||
#define ADSB_COL_FLIGHT_STATUS 68
|
||||
#define ADSB_COL_DEP 69
|
||||
#define ADSB_COL_ARR 70
|
||||
#define ADSB_COL_STOPS 71
|
||||
#define ADSB_COL_STD 72
|
||||
#define ADSB_COL_ETD 73
|
||||
#define ADSB_COL_ATD 74
|
||||
#define ADSB_COL_STA 75
|
||||
#define ADSB_COL_ETA 76
|
||||
#define ADSB_COL_ATA 77
|
||||
|
||||
#define ADSB_IC_MAX 63
|
||||
|
||||
struct ADSBDemodSettings
|
||||
{
|
||||
@ -104,6 +130,7 @@ struct ADSBDemodSettings
|
||||
int32_t m_inputFrequencyOffset;
|
||||
Real m_rfBandwidth;
|
||||
Real m_correlationThreshold; //!< Correlation power threshold in dB
|
||||
int m_chipsThreshold; //!< How many chips in preamble can be incorrect for Mode S
|
||||
int m_samplesPerBit;
|
||||
int m_removeTimeout; //!< Time in seconds before removing an aircraft, unless a new frame is received
|
||||
|
||||
@ -159,7 +186,6 @@ struct ADSBDemodSettings
|
||||
QString m_tableFontName; //!< Font to use for table
|
||||
int m_tableFontSize;
|
||||
bool m_displayDemodStats;
|
||||
bool m_correlateFullPreamble;
|
||||
bool m_demodModeS; //!< Demodulate all Mode-S frames, not just ADS-B
|
||||
QString m_amDemod; //!< AM Demod to tune to selected ATC frequency
|
||||
bool m_autoResizeTableColumns;
|
||||
@ -169,6 +195,7 @@ struct ADSBDemodSettings
|
||||
QList<NotificationSettings *> m_notificationSettings;
|
||||
QString m_aviationstackAPIKey; //!< aviationstack.com API key
|
||||
QString m_checkWXAPIKey; //!< checkwxapi.com API key
|
||||
QString m_maptilerAPIKey; //!< maptiler.com API key (for osm/satellite map)
|
||||
|
||||
QString m_logFilename;
|
||||
bool m_logEnabled;
|
||||
@ -186,13 +213,24 @@ struct ADSBDemodSettings
|
||||
bool m_displayPhotos;
|
||||
Serializable *m_rollupState;
|
||||
bool m_verboseModelMatching;
|
||||
int m_airfieldElevation; //!< QFE in ft so aircraft takeoff/land from correct position
|
||||
int m_aircraftMinZoom;
|
||||
|
||||
bool m_atcLabels;
|
||||
bool m_atcCallsigns;
|
||||
int m_transitionAlt;
|
||||
|
||||
float m_qnh;
|
||||
bool m_manualQNH;
|
||||
bool m_displayCoverage;
|
||||
bool m_displayChart;
|
||||
bool m_displayOrientation;
|
||||
bool m_displayRadius;
|
||||
bool m_displayIC[ADSB_IC_MAX];
|
||||
QString m_flightPathPaletteName;
|
||||
bool m_favourLivery; //!< Favour airline livery over aircraft type when exact 3D model isn't available
|
||||
|
||||
const QVariant *m_flightPathPalette;
|
||||
|
||||
ADSBDemodSettings();
|
||||
void resetToDefaults();
|
||||
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
|
||||
@ -201,6 +239,18 @@ struct ADSBDemodSettings
|
||||
bool deserialize(const QByteArray& data);
|
||||
QByteArray serializeNotificationSettings(QList<NotificationSettings *> notificationSettings) const;
|
||||
void deserializeNotificationSettings(const QByteArray& data, QList<NotificationSettings *>& notificationSettings);
|
||||
void applySettings(const QStringList& settingsKeys, const ADSBDemodSettings& settings);
|
||||
QString getDebugString(const QStringList& settingsKeys, bool force = false) const;
|
||||
void applyPalette();
|
||||
|
||||
static const QVariant m_rainbowPalette[8];
|
||||
static const QVariant m_pastelPalette[8];
|
||||
static const QVariant m_spectralPalette[8];
|
||||
static const QVariant m_bluePalette[8];
|
||||
static const QVariant m_purplePalette[8];
|
||||
static const QVariant m_greyPalette[8];
|
||||
|
||||
static const QHash<QString, const QVariant *> m_palettes;
|
||||
};
|
||||
|
||||
#endif /* PLUGINS_CHANNELRX_DEMODADSB_ADSBDEMODSETTINGS_H_ */
|
||||
|
@ -19,14 +19,16 @@
|
||||
#include <QTime>
|
||||
#include <QDebug>
|
||||
|
||||
#include "util/profiler.h"
|
||||
|
||||
#include "adsbdemodsink.h"
|
||||
#include "adsbdemodsinkworker.h"
|
||||
#include "adsbdemod.h"
|
||||
#include "adsb.h"
|
||||
|
||||
ADSBDemodSink::ADSBDemodSink() :
|
||||
m_channelSampleRate(6000000),
|
||||
m_channelFrequencyOffset(0),
|
||||
m_feedTime(0.0),
|
||||
m_sampleBuffer{nullptr, nullptr, nullptr},
|
||||
m_worker(this),
|
||||
m_writeBuffer(0),
|
||||
@ -37,7 +39,7 @@ ADSBDemodSink::ADSBDemodSink() :
|
||||
m_magsqCount(0),
|
||||
m_messageQueueToGUI(nullptr)
|
||||
{
|
||||
applySettings(m_settings, true);
|
||||
applySettings(m_settings, QStringList(), true);
|
||||
applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true);
|
||||
for (int i = 0; i < m_buffers; i++)
|
||||
m_bufferWrite[i].release(1);
|
||||
@ -53,7 +55,7 @@ ADSBDemodSink::~ADSBDemodSink()
|
||||
void ADSBDemodSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end)
|
||||
{
|
||||
// Start timing how long we are in this function
|
||||
m_startPoint = boost::chrono::steady_clock::now();
|
||||
PROFILER_START();
|
||||
|
||||
// Optimise for common case, where no resampling or frequency offset
|
||||
if ((m_interpolatorDistance == 1.0f) && (m_channelFrequencyOffset == 0))
|
||||
@ -113,8 +115,7 @@ void ADSBDemodSink::feed(const SampleVector::const_iterator& begin, const Sample
|
||||
}
|
||||
|
||||
// Calculate number of seconds in this function
|
||||
boost::chrono::duration<double> sec = boost::chrono::steady_clock::now() - m_startPoint;
|
||||
m_feedTime += sec.count();
|
||||
PROFILER_STOP("ADSB feed");
|
||||
}
|
||||
|
||||
void ADSBDemodSink::processOneSample(Real magsq)
|
||||
@ -127,8 +128,17 @@ void ADSBDemodSink::processOneSample(Real magsq)
|
||||
m_writeIdx++;
|
||||
if (!m_bufferDateTimeValid[m_writeBuffer])
|
||||
{
|
||||
m_bufferFirstSampleDateTime[m_writeBuffer] = QDateTime::currentDateTime();
|
||||
QDateTime dateTime = QDateTime::currentDateTime();
|
||||
if (m_minFirstSampleDateTime.isValid() && (dateTime < m_minFirstSampleDateTime)) {
|
||||
dateTime = m_minFirstSampleDateTime;
|
||||
}
|
||||
m_bufferFirstSampleDateTime[m_writeBuffer] = dateTime;
|
||||
m_bufferDateTimeValid[m_writeBuffer] = true;
|
||||
|
||||
// Make sure timestamps from different buffers are in order, even if we receive samples faster than real time
|
||||
const qint64 samplesPerSecondMSec = ADS_B_BITS_PER_SECOND * m_settings.m_samplesPerBit / 1000;
|
||||
const qint64 offsetMSec = m_bufferSize / samplesPerSecondMSec;
|
||||
m_minFirstSampleDateTime = dateTime.addMSecs(offsetMSec);
|
||||
}
|
||||
if (m_writeIdx >= m_bufferSize)
|
||||
{
|
||||
@ -138,15 +148,9 @@ void ADSBDemodSink::processOneSample(Real magsq)
|
||||
if (m_writeBuffer >= m_buffers)
|
||||
m_writeBuffer = 0;
|
||||
|
||||
// Don't include time spent waiting for a buffer
|
||||
boost::chrono::duration<double> sec = boost::chrono::steady_clock::now() - m_startPoint;
|
||||
m_feedTime += sec.count();
|
||||
|
||||
if (m_worker.isRunning())
|
||||
m_bufferWrite[m_writeBuffer].acquire();
|
||||
|
||||
m_startPoint = boost::chrono::steady_clock::now();
|
||||
|
||||
m_writeIdx = m_samplesPerFrame - 1; // Leave space for copying samples from previous buffer
|
||||
|
||||
m_bufferDateTimeValid[m_writeBuffer] = false;
|
||||
@ -247,37 +251,46 @@ void ADSBDemodSink::applyChannelSettings(int channelSampleRate, int channelFrequ
|
||||
m_channelFrequencyOffset = channelFrequencyOffset;
|
||||
}
|
||||
|
||||
void ADSBDemodSink::applySettings(const ADSBDemodSettings& settings, bool force)
|
||||
void ADSBDemodSink::applySettings(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force)
|
||||
{
|
||||
qDebug() << "ADSBDemodSink::applySettings:"
|
||||
<< " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset
|
||||
<< " m_rfBandwidth: " << settings.m_rfBandwidth
|
||||
<< " m_correlationThreshold: " << settings.m_correlationThreshold
|
||||
<< " m_correlateFullPreamble: " << settings.m_correlateFullPreamble
|
||||
<< " m_demodModeS: " << settings.m_demodModeS
|
||||
<< " m_samplesPerBit: " << settings.m_samplesPerBit
|
||||
<< " force: " << force;
|
||||
|
||||
if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth)
|
||||
|| (settings.m_samplesPerBit != m_settings.m_samplesPerBit)
|
||||
|| (settings.m_interpolatorPhaseSteps != m_settings.m_interpolatorPhaseSteps)
|
||||
|| (settings.m_interpolatorTapsPerPhase != m_settings.m_interpolatorTapsPerPhase)
|
||||
if ((settingsKeys.contains("rfBandwidth") && (settings.m_rfBandwidth != m_settings.m_rfBandwidth))
|
||||
|| (settingsKeys.contains("samplesPerBit") && (settings.m_samplesPerBit != m_settings.m_samplesPerBit))
|
||||
|| (settingsKeys.contains("interpolatorPhaseSteps") && (settings.m_interpolatorPhaseSteps != m_settings.m_interpolatorPhaseSteps))
|
||||
|| (settingsKeys.contains("interpolatorTapsPerPhase") && (settings.m_interpolatorTapsPerPhase != m_settings.m_interpolatorTapsPerPhase))
|
||||
|| force)
|
||||
{
|
||||
m_interpolator.create(m_settings.m_interpolatorPhaseSteps, m_channelSampleRate, settings.m_rfBandwidth / 2.2, m_settings.m_interpolatorTapsPerPhase);
|
||||
m_interpolatorDistanceRemain = 0;
|
||||
m_interpolatorDistance = (Real) m_channelSampleRate / (Real) (ADS_B_BITS_PER_SECOND * settings.m_samplesPerBit);
|
||||
m_interpolatorDistance = (Real) m_channelSampleRate / (Real) (ADS_B_BITS_PER_SECOND * settings.m_samplesPerBit);
|
||||
}
|
||||
|
||||
if ((settings.m_samplesPerBit != m_settings.m_samplesPerBit) || force)
|
||||
if ((settingsKeys.contains("samplesPerBit") && (settings.m_samplesPerBit != m_settings.m_samplesPerBit)) || force)
|
||||
{
|
||||
init(settings.m_samplesPerBit);
|
||||
}
|
||||
|
||||
// Forward to worker
|
||||
ADSBDemodSinkWorker::MsgConfigureADSBDemodSinkWorker *msg = ADSBDemodSinkWorker::MsgConfigureADSBDemodSinkWorker::create(
|
||||
settings, force);
|
||||
settings, settingsKeys, force);
|
||||
m_worker.getInputMessageQueue()->push(msg);
|
||||
|
||||
m_settings = settings;
|
||||
if (force) {
|
||||
m_settings = settings;
|
||||
} else {
|
||||
m_settings.applySettings(settingsKeys, settings);
|
||||
}
|
||||
}
|
||||
|
||||
void ADSBDemodSink::resetStats()
|
||||
{
|
||||
ADSBDemod::MsgResetStats* msg = ADSBDemod::MsgResetStats::create();
|
||||
m_worker.getInputMessageQueue()->push(msg);
|
||||
}
|
||||
|
@ -19,9 +19,6 @@
|
||||
#ifndef INCLUDE_ADSBDEMODSINK_H
|
||||
#define INCLUDE_ADSBDEMODSINK_H
|
||||
|
||||
#define BOOST_CHRONO_HEADER_ONLY
|
||||
#include <boost/chrono/chrono.hpp>
|
||||
|
||||
#include "dsp/channelsamplesink.h"
|
||||
#include "dsp/nco.h"
|
||||
#include "dsp/interpolator.h"
|
||||
@ -55,11 +52,12 @@ public:
|
||||
}
|
||||
|
||||
void applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force = false);
|
||||
void applySettings(const ADSBDemodSettings& settings, bool force = false);
|
||||
void applySettings(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force = false);
|
||||
void setMessageQueueToGUI(MessageQueue *messageQueue) { m_messageQueueToGUI = messageQueue; }
|
||||
void setMessageQueueToWorker(MessageQueue *messageQueue) { m_messageQueueToWorker = messageQueue; }
|
||||
void startWorker();
|
||||
void stopWorker();
|
||||
void resetStats();
|
||||
|
||||
private:
|
||||
friend ADSBDemodSinkWorker;
|
||||
@ -83,9 +81,6 @@ private:
|
||||
Real m_interpolatorDistance;
|
||||
Real m_interpolatorDistanceRemain;
|
||||
|
||||
boost::chrono::steady_clock::time_point m_startPoint;
|
||||
double m_feedTime; //!< Time spent in feed()
|
||||
|
||||
// Triple buffering for sharing sample data between two threads
|
||||
// Top area of each buffer is not used by writer, as it's used by the reader
|
||||
// for copying the last few samples of the previous buffer, so it can
|
||||
@ -96,6 +91,7 @@ private:
|
||||
QSemaphore m_bufferWrite[3]; //!< Semaphore to control write access to the buffers
|
||||
QSemaphore m_bufferRead[3]; //!< Semaphore to control read access from the buffers
|
||||
QDateTime m_bufferFirstSampleDateTime[3]; //!< Time for first sample in the buffer
|
||||
QDateTime m_minFirstSampleDateTime;
|
||||
bool m_bufferDateTimeValid[3];
|
||||
ADSBDemodSinkWorker m_worker; //!< Worker thread that does the actual demodulation
|
||||
int m_writeBuffer; //!< Which of the 3 buffers we're writing in to
|
||||
|
@ -15,30 +15,288 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define BOOST_CHRONO_HEADER_ONLY
|
||||
#include <boost/chrono/chrono.hpp>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "util/db.h"
|
||||
#include "util/profiler.h"
|
||||
#include "util/units.h"
|
||||
#include "util/osndb.h"
|
||||
#include "util/popcount.h"
|
||||
|
||||
#include "adsbdemodreport.h"
|
||||
#include "adsbdemodsink.h"
|
||||
#include "adsbdemodsinkworker.h"
|
||||
#include "adsbdemodsettings.h"
|
||||
#include "adsbdemod.h"
|
||||
#include "adsb.h"
|
||||
|
||||
MESSAGE_CLASS_DEFINITION(ADSBDemodSinkWorker::MsgConfigureADSBDemodSinkWorker, Message)
|
||||
|
||||
const Real ADSBDemodSinkWorker::m_correlationScale = 3.0f;
|
||||
|
||||
static int grayToBinary(int gray, int bits)
|
||||
{
|
||||
int binary = 0;
|
||||
for (int i = bits - 1; i >= 0; i--) {
|
||||
binary = binary | ((((1 << (i+1)) & binary) >> 1) ^ ((1 << i) & gray));
|
||||
}
|
||||
return binary;
|
||||
}
|
||||
|
||||
static int gillhamToFeet(int n)
|
||||
{
|
||||
int c1 = (n >> 10) & 1;
|
||||
int a1 = (n >> 9) & 1;
|
||||
int c2 = (n >> 8) & 1;
|
||||
int a2 = (n >> 7) & 1;
|
||||
int c4 = (n >> 6) & 1;
|
||||
int a4 = (n >> 5) & 1;
|
||||
int b1 = (n >> 4) & 1;
|
||||
int b2 = (n >> 3) & 1;
|
||||
int d2 = (n >> 2) & 1;
|
||||
int b4 = (n >> 1) & 1;
|
||||
int d4 = n & 1;
|
||||
|
||||
int n500 = grayToBinary((d2 << 7) | (d4 << 6) | (a1 << 5) | (a2 << 4) | (a4 << 3) | (b1 << 2) | (b2 << 1) | b4, 4);
|
||||
int n100 = grayToBinary((c1 << 2) | (c2 << 1) | c4, 3) - 1;
|
||||
|
||||
if (n100 == 6) {
|
||||
n100 = 4;
|
||||
}
|
||||
if (n500 %2 != 0) {
|
||||
n100 = 4 - n100;
|
||||
}
|
||||
|
||||
return -1200 + n500*500 + n100*100;
|
||||
}
|
||||
|
||||
static int decodeModeSAltitude(const QByteArray& data)
|
||||
{
|
||||
int altitude = 0; // Altitude in feet
|
||||
int altitudeCode = ((data[2] & 0x1f) << 8) | (data[3] & 0xff);
|
||||
|
||||
if (altitudeCode & 0x40) // M bit indicates metres
|
||||
{
|
||||
int altitudeMetres = ((altitudeCode & 0x1f80) >> 1) | (altitudeCode & 0x3f);
|
||||
altitude = Units::metresToFeet(altitudeMetres);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove M and Q bits
|
||||
int altitudeFix = ((altitudeCode & 0x1f80) >> 2) | ((altitudeCode & 0x20) >> 1) | (altitudeCode & 0xf);
|
||||
|
||||
// Convert to feet
|
||||
if (altitudeCode & 0x10) {
|
||||
altitude = altitudeFix * 25 - 1000;
|
||||
} else {
|
||||
altitude = gillhamToFeet(altitudeFix);
|
||||
}
|
||||
}
|
||||
return altitude;
|
||||
}
|
||||
|
||||
void ADSBDemodSinkWorker::handleModeS(unsigned char *data, int bytes, unsigned icao, int df, int firstIndex, unsigned short preamble, Real preambleCorrelation, Real correlationOnes, const QDateTime& dateTime, unsigned crc)
|
||||
{
|
||||
// Ignore downlink formats we can't decode / unlikely
|
||||
if ((df != 19) && (df != 22) && (df < 24))
|
||||
{
|
||||
QList<RXRecord> l;
|
||||
|
||||
if (m_modeSOnlyIcaos.contains(icao))
|
||||
{
|
||||
l = m_modeSOnlyIcaos.value(icao);
|
||||
if (abs(l.last().m_firstIndex - firstIndex) < 4) {
|
||||
return; // Duplicate
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Stop hash table from getting too big - clear every 10 seconds or so
|
||||
QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||
if (m_lastClear.secsTo(currentDateTime) >= 10)
|
||||
{
|
||||
//qDebug() << "Clearing ModeS only hash. size=" << m_modeSOnlyIcaos.size();
|
||||
m_modeSOnlyIcaos.clear();
|
||||
m_lastClear = currentDateTime;
|
||||
}
|
||||
}
|
||||
|
||||
RXRecord rx;
|
||||
rx.m_data = QByteArray((char*)data, bytes);
|
||||
rx.m_firstIndex = firstIndex;
|
||||
rx.m_preamble = preamble;
|
||||
rx.m_preambleCorrelation = preambleCorrelation;
|
||||
rx.m_correlationOnes = correlationOnes;
|
||||
rx.m_dateTime = dateTime;
|
||||
rx.m_crc = crc;
|
||||
l.append(rx);
|
||||
m_modeSOnlyIcaos.insert(icao, l);
|
||||
|
||||
// Have we heard from the same address several times in the last 10 seconds?
|
||||
if (l.size() >= 5)
|
||||
{
|
||||
// Check all frames have consistent altitudes and identifiers
|
||||
bool idConsistent = true;
|
||||
bool altitudeConsistent = true;
|
||||
int altitude = -1;
|
||||
int id = -1;
|
||||
|
||||
for (int i = 0; i < l.size(); i++)
|
||||
{
|
||||
int df2 = ((l[i].m_data[0] >> 3) & ADS_B_DF_MASK);
|
||||
|
||||
if ((df2 == 0) || (df2 == 4) || (df2 == 16) || (df2 == 20))
|
||||
{
|
||||
int curAltitude = decodeModeSAltitude(l[i].m_data);
|
||||
if (altitude == -1)
|
||||
{
|
||||
altitude = curAltitude;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (abs(curAltitude - altitude) > 1000) {
|
||||
altitudeConsistent = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((df2 == 5) || (df2 == 21))
|
||||
{
|
||||
int curId = ((data[2] & 0x1f) << 8) | (data[3] & 0xff); // No decode - we just want to know if it changes
|
||||
|
||||
if (id == -1)
|
||||
{
|
||||
id = curId;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (id != curId) {
|
||||
idConsistent = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: We could optionally check to see if aircraft ICAO is in db, but the db isn't complete
|
||||
|
||||
if (altitudeConsistent && idConsistent)
|
||||
{
|
||||
// Forward all frames
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
forwardFrame((const unsigned char *) l[i].m_data.data(), l[i].m_data.size(), l[i].m_preambleCorrelation, l[i].m_correlationOnes, l[i].m_dateTime, l[i].m_crc);
|
||||
}
|
||||
|
||||
m_icaos.insert(icao, l.back().m_dateTime.toMSecsSinceEpoch());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_modeSOnlyIcaos.remove(icao);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if a Mode S frame has reserved bits set or reserved field values
|
||||
// Refer: Annex 10 Volume IV
|
||||
bool ADSBDemodSinkWorker::modeSValid(unsigned char *data, unsigned df)
|
||||
{
|
||||
bool invalid = false;
|
||||
|
||||
if (df == 0)
|
||||
{
|
||||
invalid = ((data[0] & 0x1) | (data[1] & 0x18) | (data[2] & 0x60)) != 0;
|
||||
}
|
||||
else if ((df == 4) || (df == 20))
|
||||
{
|
||||
unsigned fs = data[0] & 0x3;
|
||||
unsigned dr = (data[1] >> 3) & 0x1f;
|
||||
|
||||
invalid = (fs == 6) || (fs == 7) || ((dr >= 8) && (dr <= 15));
|
||||
}
|
||||
else if ((df == 5) || (df == 21))
|
||||
{
|
||||
unsigned fs = data[0] & 0x3;
|
||||
unsigned dr = (data[1] >> 3) & 0x1f;
|
||||
|
||||
invalid = (fs == 6) || (fs == 7) || ((dr >= 8) && (dr <= 15)) || ((data[3] & 0x40) != 0);
|
||||
}
|
||||
else if (df == 11)
|
||||
{
|
||||
unsigned ca = data[0] & 0x7;
|
||||
|
||||
invalid = ((ca >= 1) && (ca <= 3));
|
||||
}
|
||||
else if (df == 16)
|
||||
{
|
||||
invalid = ((data[0] & 0x3) | (data[1] & 0x18) | (data[2] & 0x60)) != 0;
|
||||
}
|
||||
|
||||
return invalid;
|
||||
}
|
||||
|
||||
// Check if valid ICAO address - i.e. not a reserved address - see Table 9-1 in Annex X Volume III
|
||||
bool ADSBDemodSinkWorker::icaoValid(unsigned icao)
|
||||
{
|
||||
unsigned msn = (icao >> 20) & 0xf;
|
||||
|
||||
return (icao != 0) && (msn != 0xf) && (msn != 0xb) && (msn != 0xd);
|
||||
}
|
||||
|
||||
// Is it less than a minute since the last received frame for this ICAO
|
||||
bool ADSBDemodSinkWorker::icaoHeardRecently(unsigned icao, const QDateTime &dateTime)
|
||||
{
|
||||
const int timeLimitMSec = 60*1000;
|
||||
|
||||
if (m_icaos.contains(icao))
|
||||
{
|
||||
if ((dateTime.toMSecsSinceEpoch() - m_icaos.value(icao)) < timeLimitMSec) {
|
||||
return true;
|
||||
} else {
|
||||
m_icaos.remove(icao);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ADSBDemodSinkWorker::forwardFrame(const unsigned char *data, int size, float preambleCorrelation, float correlationOnes, const QDateTime& dateTime, unsigned crc)
|
||||
{
|
||||
// Pass to GUI
|
||||
if (m_sink->getMessageQueueToGUI())
|
||||
{
|
||||
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
|
||||
QByteArray((char*)data, size),
|
||||
preambleCorrelation,
|
||||
correlationOnes,
|
||||
dateTime,
|
||||
crc);
|
||||
m_sink->getMessageQueueToGUI()->push(msg);
|
||||
}
|
||||
// Pass to worker to feed to other servers
|
||||
if (m_sink->getMessageQueueToWorker())
|
||||
{
|
||||
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
|
||||
QByteArray((char*)data, size),
|
||||
preambleCorrelation,
|
||||
correlationOnes,
|
||||
dateTime,
|
||||
crc);
|
||||
m_sink->getMessageQueueToWorker()->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void ADSBDemodSinkWorker::run()
|
||||
{
|
||||
int readBuffer = 0;
|
||||
m_lastClear = QDateTime::currentDateTime();
|
||||
|
||||
// Acquire first buffer
|
||||
m_sink->m_bufferRead[readBuffer].acquire();
|
||||
|
||||
if (isInterruptionRequested()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Start recording how much time is spent processing in this method
|
||||
boost::chrono::steady_clock::time_point startPoint = boost::chrono::steady_clock::now();
|
||||
PROFILER_START();
|
||||
|
||||
// Check for updated settings
|
||||
handleInputMessages();
|
||||
@ -52,8 +310,6 @@ void ADSBDemodSinkWorker::run()
|
||||
<< " samplesPerFrame: " << samplesPerFrame
|
||||
<< " samplesPerChip: " << samplesPerChip
|
||||
<< " samplesPerBit: " << samplesPerBit
|
||||
<< " correlateFullPreamble: " << m_settings.m_correlateFullPreamble
|
||||
<< " correlationScale: " << m_correlationScale
|
||||
<< " correlationThreshold: " << m_settings.m_correlationThreshold;
|
||||
|
||||
int readIdx = m_sink->m_samplesPerFrame - 1;
|
||||
@ -64,61 +320,33 @@ void ADSBDemodSinkWorker::run()
|
||||
|
||||
// Correlate received signal with expected preamble
|
||||
// chip+ indexes are 0, 2, 7, 9
|
||||
// correlating over first 6 bits gives a reduction in per-sample
|
||||
// processing, but more than doubles the number of false matches
|
||||
Real preambleCorrelationOnes = 0.0;
|
||||
Real preambleCorrelationZeros = 0.0;
|
||||
if (m_settings.m_correlateFullPreamble)
|
||||
for (int i = 0; i < samplesPerChip; i++)
|
||||
{
|
||||
for (int i = 0; i < samplesPerChip; i++)
|
||||
{
|
||||
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 0*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 1*samplesPerChip + i];
|
||||
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 0*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 1*samplesPerChip + i];
|
||||
|
||||
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 2*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 3*samplesPerChip + i];
|
||||
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 2*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 3*samplesPerChip + i];
|
||||
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 4*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 5*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 4*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 5*samplesPerChip + i];
|
||||
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 6*samplesPerChip + i];
|
||||
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 7*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 6*samplesPerChip + i];
|
||||
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 7*samplesPerChip + i];
|
||||
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 8*samplesPerChip + i];
|
||||
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 9*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 8*samplesPerChip + i];
|
||||
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 9*samplesPerChip + i];
|
||||
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 10*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 11*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 10*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 11*samplesPerChip + i];
|
||||
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 12*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 13*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 12*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 13*samplesPerChip + i];
|
||||
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 14*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 15*samplesPerChip + i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < samplesPerChip; i++)
|
||||
{
|
||||
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 0*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 1*samplesPerChip + i];
|
||||
|
||||
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 2*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 3*samplesPerChip + i];
|
||||
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 4*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 5*samplesPerChip + i];
|
||||
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 6*samplesPerChip + i];
|
||||
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 7*samplesPerChip + i];
|
||||
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 8*samplesPerChip + i];
|
||||
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 9*samplesPerChip + i];
|
||||
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 10*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 11*samplesPerChip + i];
|
||||
}
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 14*samplesPerChip + i];
|
||||
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 15*samplesPerChip + i];
|
||||
}
|
||||
|
||||
// Use the ratio of ones power over zeros power, as we don't care how powerful the signal
|
||||
@ -139,6 +367,7 @@ void ADSBDemodSinkWorker::run()
|
||||
int firstIdx = startIdx;
|
||||
|
||||
m_demodStats.m_correlatorMatches++;
|
||||
|
||||
// Skip over preamble
|
||||
startIdx += samplesPerBit*ADS_B_PREAMBLE_BITS;
|
||||
|
||||
@ -148,6 +377,7 @@ void ADSBDemodSinkWorker::run()
|
||||
int currentBit;
|
||||
unsigned char currentByte = 0;
|
||||
int df;
|
||||
int firstIndex = 0;
|
||||
|
||||
for (int bit = 0; bit < ADS_B_ES_BITS; bit++)
|
||||
{
|
||||
@ -166,6 +396,9 @@ void ADSBDemodSinkWorker::run()
|
||||
currentByte |= currentBit << (7-(bit & 0x7));
|
||||
if ((bit & 0x7) == 0x7)
|
||||
{
|
||||
if (byteIdx == 0) {
|
||||
firstIndex = startIdx;
|
||||
}
|
||||
data[byteIdx++] = currentByte;
|
||||
currentByte = 0;
|
||||
// Don't try to demodulate any further, if this isn't an ADS-B frame
|
||||
@ -179,6 +412,10 @@ void ADSBDemodSinkWorker::run()
|
||||
}
|
||||
}
|
||||
|
||||
Real preambleCorrelationScaled = preambleCorrelation * m_correlationScale;
|
||||
Real correlationOnes = preambleCorrelationOnes / samplesPerChip;
|
||||
QDateTime dateTime = rxDateTime(firstIdx, readBuffer);
|
||||
|
||||
// Is ADS-B?
|
||||
df = ((data[0] >> 3) & ADS_B_DF_MASK);
|
||||
if ((df == 17) || (df == 18))
|
||||
@ -189,109 +426,177 @@ void ADSBDemodSinkWorker::run()
|
||||
m_crc.calculate(data, ADS_B_ES_BYTES-3);
|
||||
if (parity == m_crc.get())
|
||||
{
|
||||
// Got a valid frame
|
||||
m_demodStats.m_adsbFrames++;
|
||||
// Get 24-bit ICAO and save in hash of ICAOs that have been seen
|
||||
// Get 24-bit ICAO
|
||||
unsigned icao = ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | (data[3] & 0xff);
|
||||
m_icaos.insert(icao, true);
|
||||
// Don't try to re-demodulate the same frame
|
||||
// We could possibly allow a partial overlap here
|
||||
readIdx += (ADS_B_ES_BITS+ADS_B_PREAMBLE_BITS)*ADS_B_CHIPS_PER_BIT*samplesPerChip - 1;
|
||||
// Pass to GUI
|
||||
if (m_sink->getMessageQueueToGUI())
|
||||
|
||||
if (icaoValid(icao))
|
||||
{
|
||||
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
|
||||
QByteArray((char*)data, sizeof(data)),
|
||||
preambleCorrelation * m_correlationScale,
|
||||
preambleCorrelationOnes / samplesPerChip,
|
||||
rxDateTime(firstIdx, readBuffer),
|
||||
m_crc.get());
|
||||
m_sink->getMessageQueueToGUI()->push(msg);
|
||||
// Got a valid frame
|
||||
m_demodStats.m_adsbFrames++;
|
||||
// Save in hash of ICAOs that have been seen
|
||||
m_icaos.insert(icao, dateTime.toMSecsSinceEpoch());
|
||||
// Don't try to re-demodulate the same frame
|
||||
// We could possibly allow a partial overlap here
|
||||
readIdx += (ADS_B_ES_BITS+ADS_B_PREAMBLE_BITS)*ADS_B_CHIPS_PER_BIT*samplesPerChip - 1;
|
||||
forwardFrame(data, sizeof(data), preambleCorrelationScaled, correlationOnes, dateTime, m_crc.get());
|
||||
}
|
||||
// Pass to worker to feed to other servers
|
||||
if (m_sink->getMessageQueueToWorker())
|
||||
else
|
||||
{
|
||||
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
|
||||
QByteArray((char*)data, sizeof(data)),
|
||||
preambleCorrelation * m_correlationScale,
|
||||
preambleCorrelationOnes / samplesPerChip,
|
||||
rxDateTime(firstIdx, readBuffer),
|
||||
m_crc.get());
|
||||
m_sink->getMessageQueueToWorker()->push(msg);
|
||||
m_demodStats.m_icaoFails++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_demodStats.m_crcFails++;
|
||||
}
|
||||
}
|
||||
else if (m_settings.m_demodModeS)
|
||||
{
|
||||
int bytes;
|
||||
// Decode premable, as correlation alone results in too many false positives for Mode S frames
|
||||
startIdx = readIdx;
|
||||
unsigned short preamble = 0;
|
||||
QVector<float> preambleChips(16);
|
||||
|
||||
// Determine number of bytes in frame depending on downlink format
|
||||
if ((df == 0) || (df == 4) || (df == 5) || (df == 11)) {
|
||||
bytes = 56/8;
|
||||
} else if ((df == 16) || (df == 20) || (df == 21) || (df >= 24)) {
|
||||
bytes = 112/8;
|
||||
} else {
|
||||
bytes = 0;
|
||||
}
|
||||
if (bytes > 0)
|
||||
for (int bit = 0; bit < ADS_B_PREAMBLE_BITS; bit++)
|
||||
{
|
||||
// Extract received parity
|
||||
int parity = (data[bytes-3] << 16) | (data[bytes-2] << 8) | data[bytes-1];
|
||||
// Calculate CRC on received frame
|
||||
m_crc.init();
|
||||
m_crc.calculate(data, bytes-3);
|
||||
int crc = m_crc.get();
|
||||
// DF4 / DF5 / DF20 / DF21 have ICAO address XORed in to parity.
|
||||
// Extract ICAO from parity and see if it matches an aircraft we've already
|
||||
// received an ADS-B frame from
|
||||
if ((df == 4) || (df == 5) || (df == 20) || (df == 21))
|
||||
preambleChips[bit*2] = 0.0f;
|
||||
preambleChips[bit*2+1] = 0.0f;
|
||||
for (int i = 0; i < samplesPerChip; i++)
|
||||
{
|
||||
unsigned icao = (parity ^ crc) & 0xffffff;
|
||||
if (m_icaos.contains(icao)) {
|
||||
crc ^= icao;
|
||||
}
|
||||
preambleChips[bit*2] += m_sink->m_sampleBuffer[readBuffer][startIdx+i];
|
||||
preambleChips[bit*2+1] += m_sink->m_sampleBuffer[readBuffer][startIdx+samplesPerChip+i];
|
||||
}
|
||||
// For DF11, the last 7 bits may have an address/interogration identifier (II)
|
||||
// XORed in, so we ignore those bits
|
||||
if ((parity == crc) || ((df == 11) && ((parity & 0xffff80) == (crc & 0xffff80))))
|
||||
|
||||
startIdx += samplesPerBit;
|
||||
}
|
||||
startIdx = firstIdx;
|
||||
|
||||
float onesAvg = (preambleChips[0] + preambleChips[2] + preambleChips[7] + preambleChips[9]) / 4.0f;
|
||||
float zerosAvg = (preambleChips[1] + preambleChips[3] + preambleChips[4] + preambleChips[5] + preambleChips[6] + preambleChips[8]
|
||||
+ preambleChips[10] + + preambleChips[11] + preambleChips[12] + preambleChips[13] + preambleChips[14] + preambleChips[15]) / 12.0f;
|
||||
float midPoint = zerosAvg + (onesAvg - zerosAvg) / 2.0f;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
unsigned chip = preambleChips[i] > midPoint;
|
||||
preamble |= chip << (15-i);
|
||||
}
|
||||
|
||||
// qDebug() << "Preamble" << preambleChips << "zerosAvg" << zerosAvg << "onesAvg" << onesAvg << "midPoint" << midPoint << "chips" << Qt::hex << preamble;
|
||||
|
||||
const unsigned short expectedPreamble = 0xa140;
|
||||
int preambleDifferences = popcount(expectedPreamble ^ preamble);
|
||||
|
||||
if (preambleDifferences <= m_settings.m_chipsThreshold)
|
||||
{
|
||||
int bytes;
|
||||
|
||||
// Determine number of bytes in frame depending on downlink format
|
||||
if ((df == 0) || (df == 4) || (df == 5) || (df == 11)) {
|
||||
bytes = 56/8;
|
||||
} else if ((df == 16) || (df == 19) || (df == 20) || (df == 21) || (df == 22) || ((df >= 24) && (df <= 27))) {
|
||||
bytes = 112/8;
|
||||
} else {
|
||||
bytes = 0;
|
||||
}
|
||||
|
||||
if (bytes > 0)
|
||||
{
|
||||
m_demodStats.m_modesFrames++;
|
||||
// Pass to GUI (only pass formats it can decode)
|
||||
if (m_sink->getMessageQueueToGUI() && ((df == 4) || (df == 5) || (df == 20) || (df == 21)))
|
||||
bool invalid = modeSValid(data, df);
|
||||
|
||||
if (!invalid)
|
||||
{
|
||||
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
|
||||
QByteArray((char*)data, bytes),
|
||||
preambleCorrelation * m_correlationScale,
|
||||
preambleCorrelationOnes / samplesPerChip,
|
||||
rxDateTime(firstIdx, readBuffer),
|
||||
m_crc.get());
|
||||
m_sink->getMessageQueueToGUI()->push(msg);
|
||||
// Extract received parity
|
||||
int parity = (data[bytes-3] << 16) | (data[bytes-2] << 8) | data[bytes-1];
|
||||
// Calculate CRC on received frame
|
||||
m_crc.init();
|
||||
m_crc.calculate(data, bytes-3);
|
||||
int crc = m_crc.get();
|
||||
bool forward = false;
|
||||
|
||||
// ICAO address XORed in to parity, apart from DF11
|
||||
// Extract ICAO from parity and see if it matches an aircraft we've already
|
||||
// received an ADS-B or Mode S frame from
|
||||
// For DF11, the last 7 bits may have an iterogration code (II/SI)
|
||||
// XORed in, so we ignore those bits. This does sometimes lead to false-positives
|
||||
if (df != 11)
|
||||
{
|
||||
unsigned icao = (parity ^ crc) & 0xffffff;
|
||||
|
||||
if (icaoValid(icao))
|
||||
{
|
||||
if (icaoHeardRecently(icao, dateTime)) {
|
||||
forward = true;
|
||||
} else {
|
||||
handleModeS(data, bytes, icao, df, firstIndex, preamble, preambleCorrelationScaled, correlationOnes, dateTime, m_crc.get());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_demodStats.m_icaoFails++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ignore IC bits
|
||||
parity &= 0xffff80;
|
||||
crc &= 0xffff80;
|
||||
if (parity == crc)
|
||||
{
|
||||
// Get 24-bit ICAO
|
||||
unsigned icao = ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | (data[3] & 0xff);
|
||||
|
||||
if (icaoValid(icao))
|
||||
{
|
||||
if (icaoHeardRecently(icao, dateTime)) {
|
||||
forward = true;
|
||||
} else {
|
||||
handleModeS(data, bytes, icao, df, firstIndex, preamble, preambleCorrelationScaled, correlationOnes, dateTime, m_crc.get());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_demodStats.m_icaoFails++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_demodStats.m_crcFails++;
|
||||
}
|
||||
}
|
||||
if (forward)
|
||||
{
|
||||
m_demodStats.m_modesFrames++;
|
||||
// Don't try to re-demodulate the same frame
|
||||
// We could possibly allow a partial overlap here
|
||||
readIdx += ((bytes*8)+ADS_B_PREAMBLE_BITS)*ADS_B_CHIPS_PER_BIT*samplesPerChip - 1;
|
||||
forwardFrame(data, bytes, preambleCorrelationScaled, correlationOnes, dateTime, m_crc.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_demodStats.m_crcFails++;
|
||||
}
|
||||
}
|
||||
// Pass to worker to feed to other servers
|
||||
if (m_sink->getMessageQueueToWorker())
|
||||
else
|
||||
{
|
||||
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
|
||||
QByteArray((char*)data, bytes),
|
||||
preambleCorrelation * m_correlationScale,
|
||||
preambleCorrelationOnes / samplesPerChip,
|
||||
rxDateTime(firstIdx, readBuffer),
|
||||
m_crc.get());
|
||||
m_sink->getMessageQueueToWorker()->push(msg);
|
||||
m_demodStats.m_invalidFails++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_demodStats.m_crcFails++;
|
||||
m_demodStats.m_typeFails++;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_demodStats.m_typeFails++;
|
||||
{
|
||||
m_demodStats.m_preambleFails++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_demodStats.m_typeFails++;
|
||||
}
|
||||
}
|
||||
|
||||
readIdx++;
|
||||
if (readIdx > m_sink->m_bufferSize - samplesPerFrame)
|
||||
{
|
||||
@ -300,9 +605,7 @@ void ADSBDemodSinkWorker::run()
|
||||
nextBuffer = 0;
|
||||
|
||||
// Update amount of time spent processing (don't include time spend in acquire)
|
||||
boost::chrono::duration<double> sec = boost::chrono::steady_clock::now() - startPoint;
|
||||
m_demodStats.m_demodTime += sec.count();
|
||||
m_demodStats.m_feedTime = m_sink->m_feedTime;
|
||||
PROFILER_STOP("ADS-B demod");
|
||||
|
||||
// Send stats to GUI
|
||||
if (m_sink->getMessageQueueToGUI())
|
||||
@ -320,7 +623,7 @@ void ADSBDemodSinkWorker::run()
|
||||
handleInputMessages();
|
||||
|
||||
// Resume timing how long we are processing
|
||||
startPoint = boost::chrono::steady_clock::now();
|
||||
PROFILER_RESTART();
|
||||
|
||||
int samplesRemaining = m_sink->m_bufferSize - readIdx;
|
||||
if (samplesRemaining > 0)
|
||||
@ -357,24 +660,27 @@ void ADSBDemodSinkWorker::handleInputMessages()
|
||||
MsgConfigureADSBDemodSinkWorker* cfg = (MsgConfigureADSBDemodSinkWorker*)message;
|
||||
|
||||
ADSBDemodSettings settings = cfg->getSettings();
|
||||
QStringList settingsKeys = cfg->getSettingsKeys();
|
||||
bool force = cfg->getForce();
|
||||
|
||||
if (settings.m_correlateFullPreamble) {
|
||||
m_correlationScale = 3.0;
|
||||
} else {
|
||||
m_correlationScale = 2.0;
|
||||
}
|
||||
|
||||
if ((m_settings.m_correlationThreshold != settings.m_correlationThreshold) || force)
|
||||
if ((settingsKeys.contains("correlationThreshold") && (m_settings.m_correlationThreshold != settings.m_correlationThreshold)) || force)
|
||||
{
|
||||
m_correlationThresholdLinear = CalcDb::powerFromdB(settings.m_correlationThreshold);
|
||||
m_correlationThresholdLinear /= m_correlationScale;
|
||||
qDebug() << "m_correlationThresholdLinear: " << m_correlationThresholdLinear;
|
||||
}
|
||||
|
||||
m_settings = settings;
|
||||
if (force) {
|
||||
m_settings = settings;
|
||||
} else {
|
||||
m_settings.applySettings(settingsKeys, settings);
|
||||
}
|
||||
delete message;
|
||||
}
|
||||
else if (ADSBDemod::MsgResetStats::match(*message))
|
||||
{
|
||||
m_demodStats.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,10 +26,9 @@
|
||||
#include "util/message.h"
|
||||
#include "util/messagequeue.h"
|
||||
#include "adsbdemodstats.h"
|
||||
#include "adsbdemodsettings.h"
|
||||
|
||||
class ADSBDemodSink;
|
||||
struct ADSBDemodSettings;
|
||||
struct ADSBDemodStats;
|
||||
|
||||
class ADSBDemodSinkWorker : public QThread {
|
||||
Q_OBJECT
|
||||
@ -40,20 +39,23 @@ public:
|
||||
|
||||
public:
|
||||
const ADSBDemodSettings& getSettings() const { return m_settings; }
|
||||
const QStringList& getSettingsKeys() const { return m_settingsKeys; }
|
||||
bool getForce() const { return m_force; }
|
||||
|
||||
static MsgConfigureADSBDemodSinkWorker* create(const ADSBDemodSettings& settings, bool force)
|
||||
static MsgConfigureADSBDemodSinkWorker* create(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force)
|
||||
{
|
||||
return new MsgConfigureADSBDemodSinkWorker(settings, force);
|
||||
return new MsgConfigureADSBDemodSinkWorker(settings, settingsKeys, force);
|
||||
}
|
||||
|
||||
private:
|
||||
ADSBDemodSettings m_settings;
|
||||
QStringList m_settingsKeys;
|
||||
bool m_force;
|
||||
|
||||
MsgConfigureADSBDemodSinkWorker(const ADSBDemodSettings& settings, bool force) :
|
||||
MsgConfigureADSBDemodSinkWorker(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force) :
|
||||
Message(),
|
||||
m_settings(settings),
|
||||
m_settingsKeys(settingsKeys),
|
||||
m_force(force)
|
||||
{ }
|
||||
};
|
||||
@ -75,11 +77,29 @@ private:
|
||||
ADSBDemodSink *m_sink;
|
||||
ADSBDemodStats m_demodStats;
|
||||
Real m_correlationThresholdLinear;
|
||||
Real m_correlationScale;
|
||||
static const Real m_correlationScale;
|
||||
crcadsb m_crc; //!< Have as member to avoid recomputing LUT
|
||||
QHash<int, bool> m_icaos; //!< ICAO addresses that have been received
|
||||
QHash<unsigned, qint64> m_icaos; //!< ICAO addresses that have been received and msecsSinceEpoch last heard
|
||||
QDateTime m_lastClear;
|
||||
|
||||
struct RXRecord {
|
||||
QByteArray m_data;
|
||||
int m_firstIndex;
|
||||
unsigned short m_preamble;
|
||||
Real m_preambleCorrelation;
|
||||
Real m_correlationOnes;
|
||||
QDateTime m_dateTime;
|
||||
unsigned m_crc;
|
||||
};
|
||||
|
||||
QHash<int, QList<RXRecord>> m_modeSOnlyIcaos;
|
||||
|
||||
QDateTime rxDateTime(int firstIdx, int readBuffer) const;
|
||||
void handleModeS(unsigned char *data, int bytes, unsigned icao, int df, int firstIndex, unsigned short preamble, Real preambleCorrelation, Real correlationOnes, const QDateTime& dateTime, unsigned crc);
|
||||
void forwardFrame(const unsigned char *data, int size, float preambleCorrelation, float correlationOnes, const QDateTime& dateTime, unsigned crc);
|
||||
bool icaoHeardRecently(unsigned icao, const QDateTime &dateTime);
|
||||
static bool icaoValid(unsigned icao);
|
||||
static bool modeSValid(unsigned char *data, unsigned df);
|
||||
|
||||
};
|
||||
|
||||
|
@ -25,20 +25,27 @@ struct ADSBDemodStats {
|
||||
qint64 m_correlatorMatches; //!< Total number of correlator matches
|
||||
qint64 m_adsbFrames; //!< How many ADS-B frames with correct CRCs
|
||||
qint64 m_modesFrames; //!< How many non-ADS-B Mode-S frames with correct CRCs
|
||||
qint64 m_preambleFails; //!< How many non-ADS-B Mode S frames with errors in preamble
|
||||
qint64 m_crcFails; //!< How many frames we've demoded with incorrect CRCs
|
||||
qint64 m_typeFails; //!< How many frames we've demoded with unknown type (DF) so we can't check CRC
|
||||
double m_demodTime; //!< How long we've spent in run()
|
||||
double m_feedTime; //!< How long we've spent in feed()
|
||||
qint64 m_invalidFails; //!< How many frames we've demoded with reserved bits set
|
||||
qint64 m_icaoFails; //!< How many frames we've demoded with reserved ICAO
|
||||
|
||||
ADSBDemodStats() :
|
||||
m_correlatorMatches(0),
|
||||
m_adsbFrames(0),
|
||||
m_modesFrames(0),
|
||||
m_crcFails(0),
|
||||
m_typeFails(0),
|
||||
m_demodTime(0.0),
|
||||
m_feedTime(0.0)
|
||||
ADSBDemodStats()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
m_correlatorMatches = 0;
|
||||
m_adsbFrames = 0;
|
||||
m_modesFrames = 0;
|
||||
m_preambleFails = 0;
|
||||
m_crcFails = 0;
|
||||
m_typeFails = 0;
|
||||
m_invalidFails = 0;
|
||||
m_icaoFails = 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -150,7 +150,7 @@ bool ADSBDemodWorker::handleMessage(const Message& message)
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
MsgConfigureADSBDemodWorker& cfg = (MsgConfigureADSBDemodWorker&) message;
|
||||
|
||||
applySettings(cfg.getSettings(), cfg.getForce());
|
||||
applySettings(cfg.getSettings(), cfg.getSettingsKeys(), cfg.getForce());
|
||||
return true;
|
||||
}
|
||||
else if (ADSBDemodReport::MsgReportADSB::match(message))
|
||||
@ -165,7 +165,7 @@ bool ADSBDemodWorker::handleMessage(const Message& message)
|
||||
}
|
||||
}
|
||||
|
||||
void ADSBDemodWorker::applySettings(const ADSBDemodSettings& settings, bool force)
|
||||
void ADSBDemodWorker::applySettings(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force)
|
||||
{
|
||||
qDebug() << "ADSBDemodWorker::applySettings:"
|
||||
<< " m_feedEnabled: " << settings.m_feedEnabled
|
||||
@ -179,10 +179,10 @@ void ADSBDemodWorker::applySettings(const ADSBDemodSettings& settings, bool forc
|
||||
<< " m_logFilename: " << settings.m_logFilename
|
||||
<< " force: " << force;
|
||||
|
||||
if ((settings.m_feedEnabled != m_settings.m_feedEnabled)
|
||||
|| (settings.m_exportClientEnabled != m_settings.m_exportClientEnabled)
|
||||
|| (settings.m_exportClientHost != m_settings.m_exportClientHost)
|
||||
|| (settings.m_exportClientPort != m_settings.m_exportClientPort)
|
||||
if ((settingsKeys.contains("feedEnabled") && (settings.m_feedEnabled != m_settings.m_feedEnabled))
|
||||
|| (settingsKeys.contains("exportClientEnabled") && (settings.m_exportClientEnabled != m_settings.m_exportClientEnabled))
|
||||
|| (settingsKeys.contains("exportClientHost") && (settings.m_exportClientHost != m_settings.m_exportClientHost))
|
||||
|| (settingsKeys.contains("exportClientPort") && (settings.m_exportClientPort != m_settings.m_exportClientPort))
|
||||
|| force)
|
||||
{
|
||||
// Close any existing connection
|
||||
@ -195,9 +195,9 @@ void ADSBDemodWorker::applySettings(const ADSBDemodSettings& settings, bool forc
|
||||
}
|
||||
}
|
||||
|
||||
if ((settings.m_feedEnabled != m_settings.m_feedEnabled)
|
||||
|| (settings.m_exportServerEnabled != m_settings.m_exportServerEnabled)
|
||||
|| (settings.m_exportServerPort != m_settings.m_exportServerPort)
|
||||
if ((settingsKeys.contains("feedEnabled") && (settings.m_feedEnabled != m_settings.m_feedEnabled))
|
||||
|| (settingsKeys.contains("exportServerEnabled") && (settings.m_exportServerEnabled != m_settings.m_exportServerEnabled))
|
||||
|| (settingsKeys.contains("exportServerPort") && (settings.m_exportServerPort != m_settings.m_exportServerPort))
|
||||
|| force)
|
||||
{
|
||||
if (m_beastServer.isListening()) {
|
||||
@ -208,8 +208,8 @@ void ADSBDemodWorker::applySettings(const ADSBDemodSettings& settings, bool forc
|
||||
}
|
||||
}
|
||||
|
||||
if ((settings.m_logEnabled != m_settings.m_logEnabled)
|
||||
|| (settings.m_logFilename != m_settings.m_logFilename)
|
||||
if ((settingsKeys.contains("logEnabled") && (settings.m_logEnabled != m_settings.m_logEnabled))
|
||||
|| (settingsKeys.contains("logFilename") && (settings.m_logFilename != m_settings.m_logFilename))
|
||||
|| force)
|
||||
{
|
||||
if (m_logFile.isOpen())
|
||||
@ -238,7 +238,11 @@ void ADSBDemodWorker::applySettings(const ADSBDemodSettings& settings, bool forc
|
||||
}
|
||||
}
|
||||
|
||||
m_settings = settings;
|
||||
if (force) {
|
||||
m_settings = settings;
|
||||
} else {
|
||||
m_settings.applySettings(settingsKeys, settings);
|
||||
}
|
||||
}
|
||||
|
||||
void ADSBDemodWorker::connected()
|
||||
|
@ -61,20 +61,23 @@ public:
|
||||
|
||||
public:
|
||||
const ADSBDemodSettings& getSettings() const { return m_settings; }
|
||||
const QStringList& getSettingsKeys() const { return m_settingsKeys; }
|
||||
bool getForce() const { return m_force; }
|
||||
|
||||
static MsgConfigureADSBDemodWorker* create(const ADSBDemodSettings& settings, bool force)
|
||||
static MsgConfigureADSBDemodWorker* create(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force)
|
||||
{
|
||||
return new MsgConfigureADSBDemodWorker(settings, force);
|
||||
return new MsgConfigureADSBDemodWorker(settings, settingsKeys, force);
|
||||
}
|
||||
|
||||
private:
|
||||
ADSBDemodSettings m_settings;
|
||||
QStringList m_settingsKeys;
|
||||
bool m_force;
|
||||
|
||||
MsgConfigureADSBDemodWorker(const ADSBDemodSettings& settings, bool force) :
|
||||
MsgConfigureADSBDemodWorker(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force) :
|
||||
Message(),
|
||||
m_settings(settings),
|
||||
m_settingsKeys(settingsKeys),
|
||||
m_force(force)
|
||||
{ }
|
||||
};
|
||||
@ -101,7 +104,7 @@ private:
|
||||
ADSBBeastServer m_beastServer;
|
||||
|
||||
bool handleMessage(const Message& cmd);
|
||||
void applySettings(const ADSBDemodSettings& settings, bool force = false);
|
||||
void applySettings(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force = false);
|
||||
void send(const char *data, int length);
|
||||
char *escape(char *p, char c);
|
||||
void handleADSB(QByteArray data, const QDateTime dateTime, float correlation);
|
||||
|
@ -67,14 +67,14 @@ private slots:
|
||||
{
|
||||
xml = QString("\
|
||||
{\
|
||||
\"UrlTemplate\" : \"https://maps.wikimedia.org/osm-intl/%z/%x/%y%1.png\",\
|
||||
\"UrlTemplate\" : \"https://tile.openstreetmap.org/%z/%x/%y.png\",\
|
||||
\"ImageFormat\" : \"png\",\
|
||||
\"QImageFormat\" : \"Indexed8\",\
|
||||
\"ID\" : \"wmf-intl-%2x\",\
|
||||
\"ID\" : \"osm-%1x\",\
|
||||
\"MaximumZoomLevel\" : 18,\
|
||||
\"MapCopyRight\" : \"<a href='https://wikimediafoundation.org/wiki/Terms_of_Use'>WikiMedia Foundation</a>\",\
|
||||
\"DataCopyRight\" : \"<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors\"\
|
||||
}").arg(hiresURL).arg(hires ? 1 : 2);
|
||||
}").arg(hires ? 1 : 2);
|
||||
}
|
||||
else if (tokens[1] == "/satellite")
|
||||
{
|
||||
|
@ -30,7 +30,7 @@
|
||||
const PluginDescriptor ADSBPlugin::m_pluginDescriptor = {
|
||||
ADSBDemod::m_channelId,
|
||||
QStringLiteral("ADS-B Demodulator"),
|
||||
QStringLiteral("7.22.1"),
|
||||
QStringLiteral("7.22.7"),
|
||||
QStringLiteral("(c) Jon Beniston, M7RCE"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
Before Width: | Height: | Size: 5.1 KiB |
BIN
plugins/channelrx/demodadsb/airlinelogos/5AH.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 5.1 KiB |
BIN
plugins/channelrx/demodadsb/airlinelogos/AAF.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 6.7 KiB |
BIN
plugins/channelrx/demodadsb/airlinelogos/AAH.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 5.1 KiB |
BIN
plugins/channelrx/demodadsb/airlinelogos/AAL.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 5.1 KiB |
BIN
plugins/channelrx/demodadsb/airlinelogos/AAQ.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 5.1 KiB |
BIN
plugins/channelrx/demodadsb/airlinelogos/AAR.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 5.1 KiB |
BIN
plugins/channelrx/demodadsb/airlinelogos/AAV.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 5.1 KiB |
BIN
plugins/channelrx/demodadsb/airlinelogos/AAW.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 5.1 KiB |
BIN
plugins/channelrx/demodadsb/airlinelogos/AAY.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 5.1 KiB |
BIN
plugins/channelrx/demodadsb/airlinelogos/AAZ.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 5.1 KiB |
BIN
plugins/channelrx/demodadsb/airlinelogos/AB.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 5.1 KiB |
BIN
plugins/channelrx/demodadsb/airlinelogos/ABA.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 5.1 KiB |