diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index d9a5b5ec56..fbdb49e1a7 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -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) diff --git a/plugins/channelrx/demodadsb/adsbdemodgui.cpp b/plugins/channelrx/demodadsb/adsbdemodgui.cpp index 9f54f4116a..462124b475 100644 --- a/plugins/channelrx/demodadsb/adsbdemodgui.cpp +++ b/plugins/channelrx/demodadsb/adsbdemodgui.cpp @@ -5935,9 +5935,6 @@ void ADSBDemodGUI::applyImportSettings() void ADSBDemodGUI::import() { QString urlString = "https://"; - if (!m_settings.m_importUsername.isEmpty() && !m_settings.m_importPassword.isEmpty()) { - urlString = urlString + m_settings.m_importUsername + ":" + m_settings.m_importPassword + "@"; - } urlString = urlString + m_settings.m_importHost + "/api/states/all"; QChar join = '?'; if (!m_settings.m_importParameters.isEmpty()) @@ -5965,7 +5962,13 @@ void ADSBDemodGUI::import() urlString = urlString + join + "lomax=" + m_settings.m_importMaxLongitude; join = '&'; } - m_networkManager->get(QNetworkRequest(QUrl(urlString))); + QNetworkRequest request = QNetworkRequest(QUrl(urlString)); + if (!m_settings.m_importUsername.isEmpty() && !m_settings.m_importPassword.isEmpty()) + { + QByteArray encoded = (m_settings.m_importUsername + ":" + m_settings.m_importPassword).toLocal8Bit().toBase64(); + request.setRawHeader("Authorization", "Basic " + encoded); + } + m_networkManager->get(request); } // Handle opensky-network API call reply diff --git a/plugins/channelrx/demodadsb/flags.qrc b/plugins/channelrx/demodadsb/flags.qrc index 3c9d5dab4f..0dcf50d6f9 100644 --- a/plugins/channelrx/demodadsb/flags.qrc +++ b/plugins/channelrx/demodadsb/flags.qrc @@ -205,7 +205,7 @@ flags/kazakhstan_mil.bmp flags/kenya.bmp flags/kenya_mil.bmp - flags/khazakstan.bmp + flags/kazakhstan.bmp flags/kiribati.bmp flags/korea_north.bmp flags/korea_north_mil.bmp diff --git a/plugins/channelrx/demodadsb/flags/khazakstan.bmp b/plugins/channelrx/demodadsb/flags/kazakhstan.bmp similarity index 100% rename from plugins/channelrx/demodadsb/flags/khazakstan.bmp rename to plugins/channelrx/demodadsb/flags/kazakhstan.bmp diff --git a/plugins/channelrx/demodadsb/flags/regprefixmap.csv b/plugins/channelrx/demodadsb/flags/regprefixmap.csv index 24cec7561a..d86f9aa6b9 100644 --- a/plugins/channelrx/demodadsb/flags/regprefixmap.csv +++ b/plugins/channelrx/demodadsb/flags/regprefixmap.csv @@ -105,7 +105,7 @@ JA,japan ZJ,jersey JY,jordan 5Y,kenya -UP,khazakstan +UP,kazakhstan T3,kiribati P,korea_north HL,korea-south diff --git a/plugins/channelrx/demodadsb/readme.md b/plugins/channelrx/demodadsb/readme.md index 5b89a0e1c1..b8396dc4bd 100644 --- a/plugins/channelrx/demodadsb/readme.md +++ b/plugins/channelrx/demodadsb/readme.md @@ -133,7 +133,7 @@ As a server: The Beast binary and Hex formats are as detailed here: https://wiki.jetvision.de/wiki/Mode-S_Beast:Data_Output_Formats When Enable import is checked, aircraft data for aircraft anywhere in the world can be imported from OpenSky Network. -A username and password are not required, but when specified, this allows the update period to be reduced to 5 seconds instead of 10 seconds. +A username and password are not required, but when specified, this allows the update period to be reduced to 5 seconds instead of 10 seconds, and 4000 API calls per day instead of 400. To limit network traffic and processing power requirements, a geographical region can be set via the minimum and maximum latitude and longitude fields.

17: Open Notifications Dialog

diff --git a/plugins/channelrx/demoddsc/CMakeLists.txt b/plugins/channelrx/demoddsc/CMakeLists.txt index 21d7fa5e67..a1134d692f 100644 --- a/plugins/channelrx/demoddsc/CMakeLists.txt +++ b/plugins/channelrx/demoddsc/CMakeLists.txt @@ -27,10 +27,12 @@ if(NOT SERVER_MODE) ${demoddsc_SOURCES} dscdemodgui.cpp dscdemodgui.ui + coaststations.cpp ) set(demoddsc_HEADERS ${demoddsc_HEADERS} dscdemodgui.h + coaststations.h ) set(TARGET_NAME ${PLUGINS_PREFIX}demoddsc) diff --git a/plugins/channelrx/demoddsc/coaststations.cpp b/plugins/channelrx/demoddsc/coaststations.cpp new file mode 100644 index 0000000000..992f9deb43 --- /dev/null +++ b/plugins/channelrx/demoddsc/coaststations.cpp @@ -0,0 +1,798 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2024 Jon Beniston, M7RCE // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include "coaststations.h" + +// Map from MMSI to Coast Station Name +// From https://www.itu.int/mmsapp/coaststation/list +const QMap CoastStations { + {"003311000", "AASIAAT RADIO"}, + {"004224102", "ABADAN RADIO"}, + {"004224300", "ABBAS RADIO"}, + {"004225300", "ABBAS RADIO"}, + {"002320004", "ABERDEEN"}, + {"006191000", "ABIDJAN RADIO"}, + {"004225310", "ABOMUSA RADIO"}, + {"003451810", "ACAPULCO, GUERRERO RADIO"}, + {"004224311", "AFTAB RADIO"}, + {"006052110", "AIN TAYA RADIO"}, + {"005251558", "AIR BANGIS RADIO"}, + {"002711000", "AKCAKOCA RADIO"}, + {"002711000", "AKDAG RADIO"}, + {"004030000", "AL BIRK RADIO"}, + {"004030000", "AL LITH RADIO"}, + {"004030000", "AL QUNFUDHAH RADIO"}, + {"004030000", "AL WAJH RADIO"}, + {"006221111", "ALEXANDRIA RADIO"}, + {"006052110", "ALGER RADIO"}, + {"002470064", "ALNG SHORE BASE"}, + {"002470063", "ALNG TERMINAL"}, + {"005250006", "AMBOINA RADIO / PKE"}, + {"004225601", "AMIRABAD RADIO"}, + {"002713000", "ANAMUR RADIO"}, + {"002470119", "ANCONA RADIO"}, + {"007250240", "ANCUD RADIO"}, + {"006053814", "ANNABA RADIO"}, + {"002713000", "ANTALYA TURK RADIO"}, + {"007250050", "ANTOFAGASTA ZONAL RADIO"}, + {"002050485", "ANTWERPEN RADIO"}, + {"004224500", "ANZALI RADIO"}, + {"004225500", "ANZALI RADIO"}, + {"004381234", "AQABA COASTAL RADIO STATION/JYO - AQABA PORT CONTROL/JYP"}, + {"002633000", "ARGA"}, + {"007010111", "ARGENTINA RADIO"}, + {"007250010", "ARICA RADIO"}, + {"002734414", "ARKHANGELSK RADIO"}, + {"002241026", "ARRECIFE RADIO"}, + {"004224202", "ASALUYEH RADIO"}, + {"004225202", "ASALUYEH RADIO"}, + {"002391000", "ASPROPYRGOS ATTIKIS RADIO"}, + {"004224501", "ASTARA RADIO"}, + {"002731147", "ASTRAKHAN AMP"}, + {"002734419", "ASTRAKHAN RADIO MRCC"}, + {"002470120", "AUGUSTA RADIO"}, + {"002711000", "AYVALIK RADIO"}, + {"005743040", "BAC LIEU RADIO"}, + {"005741050", "BACH LONG VY RADIO"}, + {"007250370", "BAHIA FELIX RADIO"}, + {"007250450", "BAHIA FILDES RADIO"}, + {"007250470", "BAHIA PARAISO RADIO"}, + {"007354753", "BAHIA RADIO"}, + {"004224301", "BAHONAR RADIO"}, + {"004231000", "BAKU TRAFFIC CONTROL"}, + {"004233000", "BAKU TRAFFIC CONTROL"}, + {"004234000", "BAKU TRAFFIC CONTROL"}, + {"004235000", "BAKU TRAFFIC CONTROL"}, + {"004236000", "BAKU TRAFFIC CONTROL"}, + {"004237000", "BAKU TRAFFIC CONTROL"}, + {"004238000", "BAKU TRAFFIC CONTROL"}, + {"004239000", "BAKU TRAFFIC CONTROL"}, + {"004232000", "BAKU TRAFFIC CONTROL"}, + {"005250009", "BALIKPAPAN RADIO / PKN"}, + {"005250087", "BALIKPAPAN RADIO / PKN2"}, + {"002711000", "BANDIRMA RADIO"}, + {"005671000", "BANGKOK RADIO"}, + {"005251520", "BANJARMASIN RADIO / PKG"}, + {"002620001", "BAR RADIO"}, + {"002620002", "BAR RADIO"}, + {"002620003", "BAR RADIO"}, + {"002470121", "BARI RADIO"}, + {"004123600", "BASUO RADIO"}, + {"005250012", "BATU AMPAR RADIO"}, + {"005251526", "BAU-BAU RADIO"}, + {"004123400", "BEIHAI RADIO"}, + {"005250003", "BELAWAN RADIO / PKB"}, + {"002320021", "BELFAST"}, + {"005741070", "BEN THUY RADIO"}, + {"005250088", "BENETE RADIO"}, + {"005250034", "BENGKALIS RADIO"}, + {"005250062", "BENGKULU RADIO"}, + {"005250014", "BENOA RADIO / PKD5"}, + {"002723672", "BERDYANSK RADIO"}, + {"005250031", "BIAK RADIO / PKY2"}, + {"005251516", "BIMA RADIO"}, + {"005250026", "BINTUNI RADIO"}, + {"005250005", "BITUNG RADIO / PKM"}, + {"002713000", "BODRUM RADIO"}, + {"005250089", "BONTANG RADIO"}, + {"002470094", "BOSA"}, + {"002111240", "BREMEN RESCUE RADIO"}, + {"003621001", "BRIGAND HILL"}, + {"007010001", "BUENOS AIRES PREFECTURA NAVAL RADIO"}, + {"002731243", "BUKHTA SEVER KRASNOYARSK/BUKHTA-SEVER"}, + {"005330195", "BUKIT ANDRASY"}, + {"005330010", "BUKIT BAKAR"}, + {"005330009", "BUKIT BESAR"}, + {"005330189", "BUKIT KAYU MALAM"}, + {"005330185", "BUKIT KELAPA"}, + {"005330013", "BUKIT KERATONG"}, + {"005330186", "BUKIT LIMA"}, + {"005330012", "BUKIT NYABAU"}, + {"004402101", "BUSAN/SUHYUP"}, + {"004402107", "BUSAN/SUHYUP"}, + {"004402111", "BUSAN/SUHYUP"}, + {"004224200", "BUSHEHR RADIO"}, + {"004225200", "BUSHEHR RADIO"}, + {"005743070", "CA MAU RADIO"}, + {"002241024", "CABO DE GATA RADIO"}, + {"002241026", "CABO DE GATA RADIO"}, + {"002241024", "CABO LA NAO RADIO"}, + {"002470122", "CAGLIARI RADIO"}, + {"007250080", "CALDERA RADIO"}, + {"007600125", "CALLAO RADIO"}, + {"005742090", "CAM RANH RADIO"}, + {"002711000", "CAMLICA RADIO"}, + {"005743050", "CAN THO RADIO"}, + {"002633020", "CANDEEIROS"}, + {"004121203", "CANGZHOU"}, + {"004121202", "CAO FEI DIAN"}, + {"006010001", "CAPE TOWN RADIO"}, + {"007250250", "CASTRO RADIO"}, + {"002470095", "CESENATICO"}, + {"004224401", "CHABAHAR RADIO"}, + {"004225400", "CHABAHAR RADIO"}, + {"007250260", "CHAITEN RADIO"}, + {"007250070", "CHANARAL RADIO"}, + {"007600135", "CHANCAY RADIO"}, + {"006052111", "CHERCHELL RADIO"}, + {"003451120", "CHETUMAL, QUINTANA ROO RADIO"}, + {"007600126", "CHIMBOTE RADIO"}, + {"005250033", "CIGADING RADIO"}, + {"005250030", "CILACAP RADIO / PKR3"}, + {"005250089", "CILACAP RADIO / PKR6"}, + {"005250032", "CIREBON RADIO"}, + {"003450710", "CIUDAD DEL CARMEN, CAMPECHE RADIO"}, + {"002470123", "CIVITAVECCHIA RADIO"}, + {"003621111", "COAST GUARD CONTROL"}, + {"003621112", "COAST GUARD CONTROL"}, + {"003621113", "COAST GUARD CONTROL"}, + {"003621114", "COAST GUARD CONTROL"}, + {"003621117", "COAST GUARD CONTROL"}, + {"003621118", "COAST GUARD CONTROL"}, + {"003621119", "COAST GUARD CONTROL"}, + {"003621120", "COAST GUARD CONTROL"}, + {"003450320", "COATZACOALCOS, VERACRUZ RADIO"}, + {"002713000", "COBANDEDE RADIO"}, + {"007010008", "COMODORO RIVADAVIA PREFECTURA NAVAL RADIO"}, + {"005743060", "CON DAO RADIO"}, + {"007250150", "CONSTITUCION RADIO"}, + {"007250110", "COQUIMBO RADIO"}, + {"007250210", "CORRAL RADIO"}, + {"002241022", "CORUNA RADIO"}, + {"003451110", "COZUMEL, QUINTANA ROO RADIO"}, + {"002470124", "CROTONE RADIO"}, + {"005741020", "CUA ONG RADIO"}, + {"005742010", "CUA VIET RADIO"}, + {"002091000", "CYPRUS RADIO"}, + {"005742030", "DA NANG RADIO"}, + {"005251559", "DABO SINGKEP RADIO"}, + {"004121300", "DALIAN RADIO"}, + {"004030000", "DAMMAM RADIO"}, + {"004224203", "DAYER RADIO"}, + {"004225203", "DAYER RADIO"}, + {"002734427", "DE KASTRI TERMINAL"}, + {"002734447", "DE-KASTRI KHAB/DE-KASTRI-RADIOCENTR"}, + {"007250390", "DELGADA RADIO"}, + {"006052112", "DELLYS RADIO"}, + {"004224205", "DEYLAM RADIO"}, + {"004225205", "DEYLAM RADIO"}, + {"007250440", "DIEGO RAMIREZ RADIO"}, + {"002712000", "DIKMENTEPE RADIO"}, + {"002731107", "DIKSON TAO"}, + {"002733717", "DIKSON TAO"}, + {"002713000", "DILEKTEPE RADIO"}, + {"006211000", "DJIBOUTI RADIO"}, + {"004661010", "DOHA RADIO"}, + {"004121402", "DONG YING RADIO"}, + {"004402606", "DONGHAE/SUHYUP"}, + {"004402607", "DONGHAE/SUHYUP"}, + {"002320010", "DOVER"}, + {"004030000", "DUBA RADIO"}, + {"002380300", "DUBROVNIK RADIO"}, + {"005250004", "DUMAI RADIO / PKP"}, + {"005250083", "DUMAI RADIO / PKP4"}, + {"005742040", "DUNG QUAT RADIO"}, + {"002712000", "DUTMEN RADIO"}, + {"007300301", "ECTVM - BARRANQUILLA - CP03"}, + {"007300101", "ECTVM - BUENAVENTURA- CP01"}, + {"007300501", "ECTVM - CARTAGENA - CP05"}, + {"007300901", "ECTVM - COVEŅAS - CP09"}, + {"007300401", "ECTVM - SANTA MARTA - CP04"}, + {"007300201", "ECTVM - TUMACO - CP02"}, + {"007300801", "ECTVM - TURBO - CP08"}, + {"004700000", "EMIRATES RADIO"}, + {"004701001", "EMIRATES RESCUE (JRCCAD)"}, + {"005251517", "ENDE RADIO / PKD20"}, + {"003450210", "ENSENADA, BAJA CALIFORNIA RADIO"}, + {"007354752", "ESMERALDAS RADIO"}, + {"002734422", "EYSK RADIO CENTR/EYSK-RADIO-CENTR"}, + {"005250026", "FAK-FAK RADIO"}, + {"002320014", "FALMOUTH"}, + {"007250235", "FARO CORONA RADIO"}, + {"007250400", "FARO DUNGENESS RADIO"}, + {"007250410", "FARO ESPIRITU SANTO RADIO"}, + {"007250350", "FARO EVANGELISTAS RADIO"}, + {"007250360", "FARO FAIRWAY RADIO"}, + {"007250290", "FARO GUAFO RADIO"}, + {"007250310", "FARO RAPER RADIO"}, + {"002633090", "FIGUEIRA DA FOZ"}, + {"002241022", "FINISTERRE RADIO"}, + {"002633050", "FOIA"}, + {"002633010", "FREITA"}, + {"003621001", "FRENCH FORT"}, + {"004122600", "FUZHOU RADIO"}, + {"005330190", "GEBENG"}, + {"004224206", "GENAVEH RADIO"}, + {"004225206", "GENAVEH RADIO"}, + {"002470125", "GENOVA RADIO"}, + {"006054119", "GHAZAOUET RADIO"}, + {"002361001", "GIBRALTAR PORT AUTHORITY"}, + {"002734468", "GORKI LEN"}, + {"002733700", "GORKI LEN"}, + {"006191000", "GRAND LAHOU RADIO"}, + {"004123100", "GUANGZHOU RADIO"}, + {"007354750", "GUAYAQUIL RADIO"}, + {"004400201", "GUNSAN RADIO"}, + {"004400501", "GUNSAN RADIO"}, + {"004403501", "GUNSAN RADIO"}, + {"004402501", "GUNSAN/SUHYUP"}, + {"004402502", "GUNSAN/SUHYUP"}, + {"004402503", "GUNSAN/SUHYUP"}, + {"004402504", "GUNSAN/SUHYUP"}, + {"005330003", "GUNUNG BRINCHANG"}, + {"005330001", "GUNUNG JERAI"}, + {"005330005", "GUNUNG LEDANG"}, + {"005251556", "GUNUNG SITOLI RADIO / PKB29"}, + {"005743090", "HA TIEN RADIO"}, + {"005741040", "HAI PHONG RADIO"}, + {"003160016", "HALIFAX COAST GUARD RADIO"}, + {"004310601", "HIROSHIMA COAST GUARD RADIO"}, + {"004030000", "HMB (AZIZYA) RADIO"}, + {"005743030", "HO CHI MINH RADIO"}, + {"004310101", "HOKKAIDO COAST GUARD RADIO"}, + {"002320018", "HOLYHEAD"}, + {"005741030", "HON GAI RADIO"}, + {"005741080", "HON LA RADIO"}, + {"003669993", "HONOLULU"}, + {"002510100", "HORNAFJOERDUR RADIO"}, + {"007600128", "HUACHO RADIO"}, + {"007250090", "HUASCO RADIO"}, + {"005742020", "HUE RADIO"}, + {"002320007", "HUMBER"}, + {"007600132", "ILO RADIO"}, + {"004400003", "INCHEON RADIO"}, + {"004400004", "INCHEON RADIO"}, + {"004403001", "INCHEON RADIO"}, + {"004402001", "INCHEON/SUHYUP"}, + {"004402002", "INCHEON/SUHYUP"}, + {"004402003", "INCHEON/SUHYUP"}, + {"004402004", "INCHEON/SUHYUP"}, + {"002712000", "INEBOLU RADIO"}, + {"003160023", "IQALUIT COAST GUARD RADIO"}, + {"007250020", "IQUIQUE RADIO"}, + {"007600133", "IQUITOS RADIO"}, + {"002510100", "ISAFJOERDUR RADIO"}, + {"002711000", "ISTANBUL TURK RADIO"}, + {"002715000", "IZMIR TURK RADIO"}, + {"005250000", "JAKARTA RADIO / PKX"}, + {"005250086", "JAKARTA RADIO / PKX2"}, + {"005251510", "JAMBI RADIO"}, + {"004225308", "JASK RADIO"}, + {"005250007", "JAYAPURA RADIO / PNK"}, + {"004030000", "JEDDAH RADIO"}, + {"004400701", "JEJU RADIO"}, + {"004400702", "JEJU RADIO"}, + {"004403701", "JEJU RADIO"}, + {"004402701", "JEJU/SUHYUP"}, + {"004402702", "JEJU/SUHYUP"}, + {"004402703", "JEJU/SUHYUP"}, + {"005251583", "JEPARA RADIO"}, + {"002470096", "JESOLO"}, + {"004126620", "JIANGYIN RADIO"}, + {"004030000", "JIZAN RADIO"}, + {"005030001", "JRCC AUSTRALIA"}, + {"003061000", "JRCC CURACAO/DUTCH CARIBBEAN COAST GUARD"}, + {"002653000", "JRCC SWEDEN"}, + {"002760100", "JRCC TALLINN"}, + {"007250130", "JUAN FERNANDEZ RADIO"}, + {"004030000", "JUBAIL RADIO"}, + {"004402602", "JUMOONJIN/SUHYUP"}, + {"004402604", "JUMOONJIN/SUHYUP"}, + {"004311001", "KAGOSHIMA COAST GUARD RADIO"}, + {"005251514", "KALIANGET RADIO"}, + {"002731188", "KAMENNYY C YNAO"}, + {"002731198", "KAMENNYY C YNAO"}, + {"004400602", "KANGNUNG RADIO"}, + {"004400603", "KANGNUNG RADIO"}, + {"004400604", "KANGNUNG RADIO"}, + {"005251582", "KARIMUNJAWA RADIO"}, + {"002711000", "KARTEPE RADIO"}, + {"002711000", "KAYALIDAG RADIO"}, + {"002713000", "KAZAKIN RADIO"}, + {"005330008", "KEMUNING"}, + {"005250019", "KENDARI RADIO / PKF3"}, + {"005251503", "KETAPANG RADIO"}, + {"004030000", "KHAFJI RADIO"}, + {"004224201", "KHARK RADIO"}, + {"004225201", "KHARK RADIO"}, + {"002734429", "KHOLMSK RADIO"}, + {"004225100", "KHOMEINI RADIO"}, + {"004224103", "KHORMUSA RADIO"}, + {"004224101", "KHORRAMSHAHR RADIO"}, + {"004225101", "KHORRAMSHAHR RADIO"}, + {"005743080", "KIEN GIANG RADIO"}, + {"004224303", "KISH RADIO"}, + {"002770330", "KLAIPEDA RESCUE RADIO"}, + {"004310501", "KOBE COAST GUARD RADIO"}, + {"003669899", "KODIAK RADIO"}, + {"005251575", "KOLAKA RADIO"}, + {"006221112", "KOSSEIR RADIO"}, + {"006191000", "KOUAKRO RADIO"}, + {"002734417", "KRASNOE KAL/KALININGRAD RADIO-SKC"}, + {"005330007", "KUALA ROMPIN"}, + {"005251504", "KUALA TANJUNG RADIO"}, + {"005251511", "KUALA TUNGKAL RADIO"}, + {"005251522", "KUMAI RADIO"}, + {"005250010", "KUPANG RADIO / PKK"}, + {"005259991", "KWANDANG RADIO"}, + {"003160022", "LABRADOR COAST GUARD RADIO"}, + {"002470126", "LAMPEDUSA RADIO"}, + {"002241026", "LAS PALMAS RADIO"}, + {"004680011", "LATTAKIA RADIO"}, + {"004224204", "LAVAR RADIO"}, + {"004225204", "LAVAR RADIO"}, + {"003451610", "LAZARO CARDENAS, MICHOACAN RADIO"}, + {"005250022", "LEMBAR RADIO / PKD3"}, + {"004224302", "LENGEH RADIO"}, + {"003160026", "LES ESCOUMINS COAST GUARD RADIO"}, + {"004122300", "LIANYUNGANG RADIO"}, + {"002470127", "LIVORNO RADIO"}, + {"002050480", "LOMBARDSIJDE RADIO"}, + {"002320063", "LONDON COASTGUARD"}, + {"007250120", "LOS VILOS RADIO"}, + {"005330011", "LOWER SERAPI"}, + {"005250005", "LUWUK RADIO"}, + {"005742050", "LY SON RADIO"}, + {"002191000", "LYNGBY RADIO"}, + {"002241022", "MACHICHACO RADIO"}, + {"002712000", "MACKA R/L"}, + {"002241022", "MADRID RADIO"}, + {"002734416", "MAGADAN 4"}, + {"007250380", "MAGALLANES ZONAL RADIO"}, + {"002711000", "MAHYADAG RADIO"}, + {"004310801", "MAIZURU COAST GUARD RADIO"}, + {"005250002", "MAKASSAR RADIO / PKF"}, + {"002734423", "MAKHACHKALA DAG/MAHACHKALA-RADIOCENTR"}, + {"002734489", "MAKHACHKALA DAG/MAHACHKALA-RADIOCENTR"}, + {"002150100", "MALTA RADIO"}, + {"005251529", "MANADO RADIO"}, + {"007100003", "MANAUS-RADIO (VALDIR LEAL)"}, + {"005250023", "MANOKWARI RADIO"}, + {"007354754", "MANTA RADIO"}, + {"003451410", "MANZANILLO, COLIMA RADIO"}, + {"007010003", "MAR DEL PLATA PREFECTURA NAVAL RADIO"}, + {"007010221", "MAR DEL PLATA RADIO"}, + {"002723650", "MARIUPOL RSC"}, + {"002713000", "MARKIZ RADIO"}, + {"005251518", "MAUMERE RADIO"}, + {"006452700", "MAURITIUS RADIO"}, + {"002470128", "MAZARA DEL VALLO RADIO"}, + {"003450810", "MAZATLAN, SINALOA RADIO"}, + {"007250040", "MEJILLONES RADIO"}, + {"005030126", "MELBOURNE (SANDRINGHAM)"}, + {"007250280", "MELINKA RADIO"}, + {"005251518", "MENENG RADIO"}, + {"005250021", "MERAUKE RADIO"}, + {"002470129", "MESSINA RADIO"}, + {"002320017", "MILFORD HAVEN"}, + {"003660003", "MOBILE, ALABAMA RADIO / WLO"}, + {"004310701", "MOJI COAST GUARD RADIO"}, + {"004400304", "MOKPO RADIO"}, + {"004400307", "MOKPO RADIO"}, + {"004400308", "MOKPO RADIO"}, + {"004400309", "MOKPO RADIO"}, + {"004400310", "MOKPO RADIO"}, + {"004403301", "MOKPO RADIO"}, + {"004402301", "MOKPO/SUHYUP"}, + {"004402302", "MOKPO/SUHYUP"}, + {"004402305", "MOKPO/SUHYUP"}, + {"004402308", "MOKPO/SUHYUP"}, + {"004402309", "MOKPO/SUHYUP"}, + {"004402310", "MOKPO/SUHYUP"}, + {"004402311", "MOKPO/SUHYUP"}, + {"004402312", "MOKPO/SUHYUP"}, + {"007600129", "MOLLENDO RADIO"}, + {"005741010", "MONG CAI RADIO"}, + {"002633060", "MONTE FIGO"}, + {"002633030", "MONTE FUNCHAL"}, + {"007703870", "MONTEVIDEO ARMADA RADIO"}, + {"006054118", "MOSTAGANEM RADIO"}, + {"005061411", "MRCC AYEYARWADY"}, + {"004194401", "MRCC CHENNAI"}, + {"002275300", "MRCC CORSEN"}, + {"006631008", "MRCC DAKAR"}, + {"002275000", "MRCC ETEL"}, + {"002275010", "MRCC ETEL"}, + {"002130100", "MRCC GEORGIA"}, + {"002275100", "MRCC GRIS-NEZ"}, + {"004773500", "MRCC HONG KONG"}, + {"002275200", "MRCC JOBOURG"}, + {"002275400", "MRCC LA GARDE"}, + {"002630100", "MRCC LISBOA"}, + {"002633040", "MRCC LISBOA"}, + {"004550191", "MRCC MALE"}, + {"004192203", "MRCC MUMBAI"}, + {"005401000", "MRCC NOUMEA"}, + {"005461000", "MRCC PAPEETE"}, + {"002040100", "MRCC PONTA DELGADA"}, + {"004194409", "MRCC PORT BLAIR"}, + {"006601000", "MRCC REUNION"}, + {"002470010", "MRCC ROMA"}, + {"002301000", "MRCC TURKU"}, + {"002050480", "MRCC-OOSTENDE RADIO"}, + {"002059981", "MRCC-OOSTENDE RADIO"}, + {"002275420", "MRSC AJACCIO"}, + {"002470017", "MRSC ANCONA"}, + {"004192209", "MRSC ANDROTH"}, + {"002470016", "MRSC BARI"}, + {"004192205", "MRSC BEYPORE"}, + {"002470023", "MRSC CAGLIARI"}, + {"004194408", "MRSC CAMPBELL BAY"}, + {"002470021", "MRSC CATANIA"}, + {"004192203", "MRSC DAHANU"}, + {"004192201", "MRSC DAMAN"}, + {"004194407", "MRSC DIGLIPUR"}, + {"004194404", "MRSC FRAZERGANJ"}, + {"002470011", "MRSC GENOVA"}, + {"004192206", "MRSC GOA"}, + {"004194403", "MRSC GOPALPUR"}, + {"004194404", "MRSC HALDIA"}, + {"002302000", "MRSC HELSINKI"}, + {"004194409", "MRSC HUTBAY"}, + {"004192208", "MRSC JAKHAU"}, + {"004194402", "MRSC KAKINADA"}, + {"004194408", "MRSC KAMORTA"}, + {"004194405", "MRSC KARAIKAL"}, + {"004192204", "MRSC KARWAR"}, + {"004192209", "MRSC KAVARATTI"}, + {"004192205", "MRSC KOCHI"}, + {"004194402", "MRSC KRISHNAPATNAM"}, + {"002470012", "MRSC LIVORNO"}, + {"002500100", "MRSC MALIN HEAD RADIO"}, + {"004194406", "MRSC MANDAPAM"}, + {"004194407", "MRSC MAYABUNDAR"}, + {"004192209", "MRSC MINICOY"}, + {"004192207", "MRSC MUNDRA"}, + {"004192203", "MRSC MURUD JANJIRA"}, + {"002470014", "MRSC NAPOLI"}, + {"004192204", "MRSC NEW MANGALORE"}, + {"004194402", "MRSC NIZAMPATNAM"}, + {"004192207", "MRSC OKHA"}, + {"002470022", "MRSC PALERMO"}, + {"004194403", "MRSC PARADIP"}, + {"004192207", "MRSC PIPAVAV"}, + {"004192202", "MRSC PORBANDAR"}, + {"004194401", "MRSC PUDUCHERRY"}, + {"004192203", "MRSC RATNAGIRI"}, + {"002470018", "MRSC RAVENNA"}, + {"002470015", "MRSC REGGIO CALABRIA"}, + {"002470013", "MRSC ROMA"}, + {"002470020", "MRSC TRIESTE"}, + {"004194405", "MRSC TUTICORIN"}, + {"004192210", "MRSC VADINAR"}, + {"002500200", "MRSC VALENTIA RADIO"}, + {"002470019", "MRSC VENEZIA"}, + {"004192207", "MRSC VERAVAL"}, + {"004194402", "MRSC VISHAKHAPATNAM"}, + {"004192205", "MRSC VIZHINJAM"}, + {"005250546", "MUNTOK RADIO"}, + {"002734441", "MURMANSK RADIO 30"}, + {"002734420", "MURMANSK RADIO MRCC"}, + {"005060200", "MYEIK RADIO"}, + {"004310401", "NAGOYA COAST GUARD RADIO"}, + {"002470130", "NAPOLI RADIO"}, + {"002500300", "NATIONAL MARITIME OPERATIONS CENTRE (MRCC DUBLIN)"}, + {"005251505", "NATUNA RADIO"}, + {"006459022", "NCG"}, + {"004224602", "NEKA RADIO"}, + {"005330183", "NENASI"}, + {"002510100", "NESKAUPSTADUR RADIO"}, + {"002442000", "NETHERLANDS COAST GUARD RADIO"}, + {"005742080", "NHA TRANG RADIO"}, + {"004310901", "NIIGATA COAST GUARD RADIO"}, + {"004122400", "NINGBO RADIO"}, + {"003621001", "NORTH POST RADIO STATION"}, + {"002570000", "NORWEGIAN COASTAL RADIO NORTH"}, + {"002570300", "NORWEGIAN COASTAL RADIO, SOUTH"}, + {"002570000", "NORWEGIAN COASTAL RADIO, SOUTH"}, + {"002731223", "NOVAYA ZEMLYA ARKH/NOVAYA ZEMLYA-RADIO"}, + {"002734411", "NOVOROSSIYSK RADIO MRCC/NOVOROSSIYSK-RADIO-SKC"}, + {"004224600", "NOWSHAHR RADIO"}, + {"004225600", "NOWSHAHR RADIO"}, + {"004030000", "OBHUR RADIO"}, + {"002723660", "ODESSA MRCC"}, + {"004311101", "OKINAWA COAST GUARD RADIO"}, + {"002371000", "OLYMPIA RADIO NOC"}, + {"004610013", "OMAN COAST RADIO/A4A20 (MUSCAT)"}, + {"004610014", "OMAN COAST RADIO/A4A21 (SALALAH)"}, + {"004610015", "OMAN COAST RADIO/A4A22 (KHASAB)"}, + {"004610016", "OMAN COAST RADIO/A4A23 (ASHKARAH)"}, + {"006054117", "ORAN RADIO"}, + {"002713000", "OREN RADIO"}, + {"002734426", "ORLAN RADIO"}, + {"007600121", "PAITA RADIO"}, + {"002713000", "PALAMUT RADIO"}, + {"005251507", "PALEMBANG RADIO"}, + {"002470002", "PALERMO RADIO"}, + {"002241024", "PALMA RADIO"}, + {"005250071", "PALOPO RADIO"}, + {"005251508", "PANGKAL BALAM RADIO"}, + {"005250013", "PANJANG RADIO / PKC4"}, + {"005250018", "PANTOLOAN RADIO"}, + {"005251525", "PARE-PARE RADIO / PKF23"}, + {"007250100", "PASCUA ZONAL RADIO"}, + {"002712000", "PAZAR RADIO"}, + {"005330192", "PENGERANG"}, + {"002470131", "PESCARA RADIO"}, + {"002734418", "PETROPAVLOVSK-KAMCHATSKIY"}, + {"002731117", "PEVEK CHAO"}, + {"002733730", "PEVEK CHAO"}, + {"005742100", "PHAN RANG RADIO"}, + {"005743010", "PHAN THIET RADIO"}, + {"005743110", "PHU QUOC RADIO"}, + {"005742070", "PHU YEN RADIO"}, + {"002633040", "PICOTO"}, + {"007600123", "PIMENTEL RADIO"}, + {"002392000", "PIRAEUS RADIO"}, + {"007600130", "PISCO RADIO"}, + {"003160019", "PLACENTIA COAST GUARD RADIO"}, + {"005250084", "PLAJU RADIO"}, + {"002734442", "PLASTUN RADIO"}, + {"004400401", "POHANG RADIO"}, + {"004400402", "POHANG RADIO"}, + {"004403401", "POHANG RADIO"}, + {"004402402", "POHANG/SUHYUP"}, + {"003621001", "POINT FORTIN"}, + {"002618102", "POLISH RESCUE RADIO"}, + {"002633100", "PONTA DO ALTAR"}, + {"005250016", "PONTIANAK RADIO / PKS"}, + {"003160018", "PORT AUX BASQUES COAST GUARD RADIO"}, + {"004702007", "PORT OF FUJAIRAH"}, + {"004702008", "PORT OF FUJAIRAH"}, + {"006221113", "PORT SAID RADIO"}, + {"002470132", "PORTO CERVO RADIO"}, + {"002470097", "PORTO NOGARO"}, + {"002470133", "PORTO TORRES RADIO"}, + {"002470098", "PORTOSCUSO"}, + {"005251527", "POSO RADIO"}, + {"003160029", "PRESCOTT COAST GUARD RADIO"}, + {"003160013", "PRINCE RUPERT COAST GUARD RADIO"}, + {"003450910", "PROGRESO, YUCATAN RADIO"}, + {"007250294", "PUERTO AGUIRRE RADIO"}, + {"007354757", "PUERTO AYORA RADIO"}, + {"007250300", "PUERTO AYSEN RADIO"}, + {"007354756", "PUERTO BOLIVAR RADIO"}, + {"007250298", "PUERTO CHACABUCO RADIO"}, + {"007250330", "PUERTO EDEN RADIO"}, + {"007250230", "PUERTO MONTT ZONAL RADIO"}, + {"007250340", "PUERTO NATALES RADIO"}, + {"003451210", "PUERTO VALLARTA, JALISCO RADIO"}, + {"007250420", "PUERTO WILLIAMS RADIO"}, + {"005330006", "PULAU TIOMAN"}, + {"007600134", "PUNO RADIO"}, + {"004400101", "PUSAN RADIO"}, + {"004400103", "PUSAN RADIO"}, + {"004400104", "PUSAN RADIO"}, + {"004400105", "PUSAN RADIO"}, + {"004400106", "PUSAN RADIO"}, + {"004403102", "PUSAN RADIO"}, + {"004122200", "QINGDAO RADIO"}, + {"004121200", "QINHUANGDAO RADIO"}, + {"003160027", "QUEBEC COAST GUARD RADIO"}, + {"007250270", "QUELLON RADIO"}, + {"004224304", "QUESHM RADIO"}, + {"007250125", "QUINTERO RADIO"}, + {"005742060", "QUY NHON RADIO"}, + {"004030000", "RABIGH RADIO"}, + {"002733728", "RADUZHNYY MAGADAN"}, + {"003669991", "RCC BOSTON"}, + {"004401002", "RCC DONGHAE"}, + {"004401001", "RCC INCHEON"}, + {"004401005", "RCC JEJU"}, + {"003669997", "RCC MIAMI"}, + {"004401004", "RCC NAMHAE"}, + {"003669998", "RCC NEW ORLEANS"}, + {"003669992", "RCC SAN JUAN"}, + {"004401003", "RCC SEOHAE"}, + {"007100002", "RECIFE BONGI"}, + {"002510100", "REYKJAVIK RADIO"}, + {"004122201", "RI ZHAO"}, + {"002750100", "RIGA RESCUE RADIO"}, + {"002380200", "RIJEKA RADIO"}, + {"007100001", "RIO DE JANEIRO (SANTA CRUZ)"}, + {"007010010", "RIO GALLEGOS PREFECTURA NAVAL RADIO"}, + {"006341000", "RMRCC MOMBASA"}, + {"002470001", "ROMA RADIO"}, + {"003621001", "RUNNEMEDE"}, + {"007250140", "S. ANTONIO RADIO"}, + {"002470134", "S. BENEDETTO DEL TRONTO RADIO"}, + {"007600131", "S. JUAN RADIO"}, + {"007250320", "S. PEDRO RADIO"}, + {"002733700", "S. PETERSBURG RADIO MRCC"}, + {"005251501", "SABANG RADIO / PKA4"}, + {"002731177", "SABETTA PT YNAO"}, + {"002731187", "SABETTA PT YNAO"}, + {"002731197", "SABETTA PT YNAO"}, + {"002733733", "SAKHALIN RADIO SPC"}, + {"007600124", "SALAVERRY RADIO"}, + {"007354755", "SALINAS RADIO"}, + {"005251524", "SAMARINDA RADIO / PKN6"}, + {"004402106", "SAMCHEONPO/SUHYUP"}, + {"004402112", "SAMCHEONPO/SUHYUP"}, + {"005251521", "SAMPIT RADIO"}, + {"002712000", "SAMSUN TURK RADIO"}, + {"007010006", "SAN BLAS PREFECTURA NAVAL RADIO"}, + {"003669990", "SAN FRANCISCO"}, + {"005250025", "SANANA RADIO"}, + {"006191000", "SAN-PEDRO RADIO"}, + {"004123700", "SANYA RADIO"}, + {"002711000", "SARKOY RADIO"}, + {"003160030", "SARNIA COAST GUARD RADIO"}, + {"006191000", "SASSANDRA RADIO"}, + {"005251531", "SAUMLAKI RADIO"}, + {"005250029", "SEI KOLAK KIJANG RADIO"}, + {"005250090", "SEI PAKNING RADIO"}, + {"005250008", "SEMARANG RADIO / PKR"}, + {"004400002", "SEOUL RADIO"}, + {"004122100", "SHANGHAI RADIO"}, + {"004123200", "SHANTOU RADIO"}, + {"004123106", "SHENZHEN RADIO"}, + {"002320001", "SHETLAND"}, + {"004310201", "SHIOGAMA COAST GUARD RADIO"}, + {"004030000", "SHUAIBA RADIO"}, + {"004030000", "SHUQAIQ RADIO"}, + {"005250028", "SIBOLGA RADIO / PKB3"}, + {"002510100", "SIGLUFJOERDUR RADIO"}, + {"005630002", "SINGAPORE PORT OPERATIONS CONTROL"}, + {"002734417", "SINYAVINO KLN/KALININGRAD-1"}, + {"005250047", "SIPORA RADIO"}, + {"002731108", "SOCHI AKHUN MTN KRAS"}, + {"004402603", "SOKCHO/SUHYUP"}, + {"002320011", "SOLENT"}, + {"005250011", "SORONG RADIO / PKY4"}, + {"002380100", "SPLIT RADIO"}, + {"003751001", "ST. VINCENT AND THE GRENADINES COAST GUARD"}, + {"005330196", "STESEN PANTAI KUALA MUDA"}, + {"005330188", "STESEN PEMANCAR PERMATANG PAUH, P. PINANG"}, + {"005330184", "STESEN PEMANCAR STAPOK"}, + {"005330193", "STESEN PEMANCAR TUARAN"}, + {"005330199", "STESEN PENERIMAAN RADIO TANJUNG ARU"}, + {"005330200", "STESEN PENERIMAAN SEMANTAN"}, + {"005330198", "STESEN SATELLITE BUMI BESERAH"}, + {"002320024", "STORNOWAY"}, + {"007600127", "SUPE RADIO"}, + {"005250001", "SURABAYA RADIO / PKD"}, + {"002733733", "SVOBODNYY SAKH"}, + {"003160017", "SYDNEY COAST GUARD RADIO"}, + {"006191000", "TABOU RADIO"}, + {"004402201", "TAEAN/SUHYUP"}, + {"004402202", "TAEAN/SUHYUP"}, + {"004402203", "TAEAN/SUHYUP"}, + {"004402204", "TAEAN/SUHYUP"}, + {"002734487", "TAGANROG RADIO"}, + {"002734487", "TAGANROG ROST/TAGANROG-RADIO-1"}, + {"005250024", "TAHUNA RADIO"}, + {"007600122", "TALARA RADIO"}, + {"007250170", "TALCAHUANO ZONAL RADIO"}, + {"002761000", "TALLINN RADIO"}, + {"007250060", "TALTAL RADIO"}, + {"003450110", "TAMPICO, TAMAULIPAS RADIO"}, + {"005330187", "TANJUNG LOBANG"}, + {"005251506", "TANJUNG UBAN RADIO / PKJ"}, + {"005251502", "TAPAK TUAN RADIO"}, + {"005250017", "TARAKAN RADIO / PKO"}, + {"002241026", "TARIFA RADIO"}, + {"004680012", "TARTOUS RADIO"}, + {"005120010", "TAUPO MARITIME RADIO"}, + {"005251513", "TEGAL RADIO / PKR26"}, + {"005251075", "TELUK BAYUR RADIO / PKP20"}, + {"005250075", "TELUK BAYUR RADIO / PKV"}, + {"005250094", "TEMBILAHAN RADIO"}, + {"006052113", "TENES RADIO"}, + {"005250020", "TERNATE RADIO / PKE5"}, + {"002470099", "TERRASINI"}, + {"005330014", "TG TARAS"}, + {"005741060", "THANH HOA RADIO"}, + {"005743100", "THO CHU RADIO"}, + {"004121100", "TIANJIN RADIO"}, + {"002734449", "TIKSI MRSC"}, + {"002731196", "TIKSI-3 YAK"}, + {"002733718", "TIKSI-3 YAK"}, + {"004225309", "TIYAB RADIO"}, + {"007250030", "TOCOPILLA RADIO"}, + {"004310001", "TOKYO COAST GUARD RADIO"}, + {"005251528", "TOLI-TOLI RADIO"}, + {"004402105", "TONGYEONG/SUHYUP"}, + {"004402108", "TONGYEONG/SUHYUP"}, + {"004402109", "TONGYEONG/SUHYUP"}, + {"004402110", "TONGYEONG/SUHYUP"}, + {"002311000", "TORSHAVN RADIO"}, + {"002470135", "TRIESTE RADIO"}, + {"005330194", "TRIG HILL"}, + {"005251530", "TUAL RADIO"}, + {"002734413", "TUAPSE KRAS/TUAPSE-CENTR"}, + {"002300230", "TURKU RADIO"}, + {"002734448", "UGOLNYE KOPI 3-Y CHAO/MARIYA-RADIO"}, + {"002731178", "UGOLNYE KOPI CHAO"}, + {"004402404", "ULLENG/SUHYUP"}, + {"004402405", "ULLENG/SUHYUP"}, + {"004402406", "ULLENG/SUHYUP"}, + {"004400403", "ULREUNG RADIO"}, + {"004400404", "ULREUNG RADIO"}, + {"004400102", "ULSAN RADIO"}, + {"004402102", "ULSAN/SUHYUP"}, + {"004402104", "ULSAN/SUHYUP"}, + {"005330004", "ULU KALI"}, + {"004030000", "UMM LAJJ RADIO"}, + {"007250220", "VALDIVIA RADIO"}, + {"007251860", "VALPARAISO PLAYA ANCHA RADIO"}, + {"002734421", "VANINO RADIO"}, + {"002070810", "VARNA RADIO"}, + {"003450310", "VERACRUZ, VERACRUZ RADIO"}, + {"002770090", "VESSEL TRAFFIC MONITORING"}, + {"002770100", "VESSEL TRAFFIC MONITORING"}, + {"002770110", "VESSEL TRAFFIC MONITORING"}, + {"002770120", "VESSEL TRAFFIC MONITORING"}, + {"002770130", "VESSEL TRAFFIC MONITORING"}, + {"002510100", "VESTMANNAEYJAR RADIO"}, + {"002633070", "VIANA DO CASTELO"}, + {"003160011", "VICTORIA COAST GUARD RADIO"}, + {"002734412", "VLADIVOSTOCK RADIO MRCC"}, + {"005743020", "VUNG TAU RADIO"}, + {"002734451", "VYSOTSK LEN"}, + {"005788020", "WALLIS RADIO"}, + {"004121403", "WEI FANG"}, + {"004121404", "WEIHAI"}, + {"004402403", "WHOPO/SUHYUP"}, + {"004402407", "WHOPO/SUHYUP"}, + {"004403408", "WHOPO/SUHYUP"}, + {"007250430", "WOLLASTON RADIO"}, + {"004122700", "XIAMEN RADIO"}, + {"004030000", "YANBU RADIO"}, + {"005060100", "YANGON RADIO"}, + {"004121400", "YANTAI RADIO"}, + {"004400305", "YEOSU RADIO"}, + {"004400306", "YEOSU RADIO"}, + {"004402303", "YEOSU/SUHYUP"}, + {"004402304", "YEOSU/SUHYUP"}, + {"004402307", "YEOSU/SUHYUP"}, + {"002712000", "YILDIZTEPE RADIO"}, + {"004310301", "YOKOHAMA COAST GUARD RADIO"}, + {"002713000", "YUMRUTEPE RADIO"}, + {"002711000", "YUSA RADIO"}, + {"002050480", "ZEEBRUGGE RADIO"}, + {"004123300", "ZHANJIANG RADIO"}, + {"004125725", "ZHANJIANG RADIO"}, + {"002712000", "ZONGULDAK RADIO"}, + {"007600120", "ZORRITOS RADIO"}, + // Not from ITU database + {"004472188", "KUWAIT"}, + {"002241078", "MADRID RADIO"}, + {"002640570", "CONSTANTA RADIO"}, + {"004280001", "HAIFA RADIO"}, + {"004634060", "MRCC KARACHI"} +}; diff --git a/plugins/channelrx/demoddsc/coaststations.h b/plugins/channelrx/demoddsc/coaststations.h new file mode 100644 index 0000000000..ea3fe2574b --- /dev/null +++ b/plugins/channelrx/demoddsc/coaststations.h @@ -0,0 +1,25 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2024 Jon Beniston, M7RCE // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_COASTSTATIONS_H +#define INCLUDE_COASTSTATIONS_H + +#include + +extern const QMap CoastStations; + +#endif /* INCLUDE_COASTSTATIONS_H */ diff --git a/plugins/channelrx/demoddsc/dscdemodgui.cpp b/plugins/channelrx/demoddsc/dscdemodgui.cpp index be54003789..3fc540624a 100644 --- a/plugins/channelrx/demoddsc/dscdemodgui.cpp +++ b/plugins/channelrx/demoddsc/dscdemodgui.cpp @@ -27,6 +27,7 @@ #include #include "dscdemodgui.h" +#include "coaststations.h" #include "device/deviceuiset.h" #include "device/deviceset.h" @@ -325,6 +326,13 @@ void DSCDemodGUI::messageReceived(const DSCMessage& message, int errors, float r ui->messages->scrollToBottom(); } + if (CoastStations.contains(message.m_address)) { + addressNameItem->setText(CoastStations.value(message.m_address)); + } + if (CoastStations.contains(message.m_selfId)) { + selfIdNameItem->setText(CoastStations.value(message.m_selfId)); + } + // Get latest APRS.fi data to calculate distance if (m_aprsFi && message.m_valid) { diff --git a/plugins/channelrx/remotetcpsink/remotetcpsinksink.cpp b/plugins/channelrx/remotetcpsink/remotetcpsinksink.cpp index 5697422fd4..d69aebc9b9 100644 --- a/plugins/channelrx/remotetcpsink/remotetcpsinksink.cpp +++ b/plugins/channelrx/remotetcpsink/remotetcpsinksink.cpp @@ -881,8 +881,8 @@ RemoteTCPProtocol::Device RemoteTCPSinkSink::getDevice() void RemoteTCPSinkSink::acceptWebConnection() { - QMutexLocker mutexLocker(&m_mutex); - QWebSocket *client = m_webSocketServer->nextPendingConnection(); + QMutexLocker mutexLocker(&m_mutex); + QWebSocket *client = m_webSocketServer->nextPendingConnection(); connect(client, &QWebSocket::binaryMessageReceived, this, &RemoteTCPSinkSink::processCommand); connect(client, &QWebSocket::disconnected, this, &RemoteTCPSinkSink::disconnected); @@ -891,8 +891,11 @@ void RemoteTCPSinkSink::acceptWebConnection() // https://bugreports.qt.io/browse/QTBUG-125874 QTimer::singleShot(200, this, [this, client] () { QMutexLocker mutexLocker(&m_mutex); - m_clients.append(new WebSocket(client)); - acceptConnection(m_clients.last()); + if (client->isValid()) + { + m_clients.append(new WebSocket(client)); + acceptConnection(m_clients.last()); + } }); } @@ -912,8 +915,11 @@ void RemoteTCPSinkSink::acceptTCPConnection() QTimer::singleShot(200, this, [this, client] () { QMutexLocker mutexLocker(&m_mutex); - m_clients.append(new TCPSocket(client)); - acceptConnection(m_clients.last()); + if (client->isValid()) + { + m_clients.append(new TCPSocket(client)); + acceptConnection(m_clients.last()); + } }); } diff --git a/plugins/channeltx/modam/ammodsource.cpp b/plugins/channeltx/modam/ammodsource.cpp index 6028902699..165a2f4263 100644 --- a/plugins/channeltx/modam/ammodsource.cpp +++ b/plugins/channeltx/modam/ammodsource.cpp @@ -128,7 +128,7 @@ void AMModSource::pullOne(Sample& sample) void AMModSource::prefetch(unsigned int nbSamples) { - auto nbSamplesAudio = (nbSamples * (unsigned int) ((Real) m_audioSampleRate / (Real) m_channelSampleRate)); + unsigned int nbSamplesAudio = (unsigned int) (nbSamples * ((Real) m_audioSampleRate / (Real) m_channelSampleRate)); pullAudio(nbSamplesAudio); } diff --git a/plugins/channeltx/modnfm/nfmmodsource.cpp b/plugins/channeltx/modnfm/nfmmodsource.cpp index ff37ccfb77..7d54cb13fb 100644 --- a/plugins/channeltx/modnfm/nfmmodsource.cpp +++ b/plugins/channeltx/modnfm/nfmmodsource.cpp @@ -119,7 +119,7 @@ void NFMModSource::pullOne(Sample& sample) void NFMModSource::prefetch(unsigned int nbSamples) { - unsigned int nbSamplesAudio = (nbSamples * (unsigned int) ((Real) m_audioSampleRate / (Real) m_channelSampleRate)); + unsigned int nbSamplesAudio = (unsigned int) (nbSamples * ((Real) m_audioSampleRate / (Real) m_channelSampleRate)); pullAudio(nbSamplesAudio); } diff --git a/plugins/channeltx/modssb/ssbmod.cpp b/plugins/channeltx/modssb/ssbmod.cpp index 411bf7d71b..54485d6019 100644 --- a/plugins/channeltx/modssb/ssbmod.cpp +++ b/plugins/channeltx/modssb/ssbmod.cpp @@ -68,6 +68,7 @@ SSBMod::SSBMod(DeviceAPI *deviceAPI) : m_basebandSource->setSpectrumSink(&m_spectrumVis); m_basebandSource->setInputFileStream(&m_ifstream); m_basebandSource->setChannel(this); + m_basebandSource->setCWKeyer(&m_cwKeyer); m_basebandSource->moveToThread(m_thread); applySettings(m_settings, true); diff --git a/plugins/channeltx/modssb/ssbmodsource.cpp b/plugins/channeltx/modssb/ssbmodsource.cpp index c2e1f9df22..3d7e2483bf 100644 --- a/plugins/channeltx/modssb/ssbmodsource.cpp +++ b/plugins/channeltx/modssb/ssbmodsource.cpp @@ -131,7 +131,7 @@ void SSBModSource::pullOne(Sample& sample) void SSBModSource::prefetch(unsigned int nbSamples) { - unsigned int nbSamplesAudio = (nbSamples * (unsigned int) ((Real) m_audioSampleRate / (Real) m_channelSampleRate)); + unsigned int nbSamplesAudio = (unsigned int) (nbSamples * ((Real) m_audioSampleRate / (Real) m_channelSampleRate)); pullAudio(nbSamplesAudio); } diff --git a/plugins/channeltx/modwfm/wfmmodsource.cpp b/plugins/channeltx/modwfm/wfmmodsource.cpp index 532ccf594b..2b01569d42 100644 --- a/plugins/channeltx/modwfm/wfmmodsource.cpp +++ b/plugins/channeltx/modwfm/wfmmodsource.cpp @@ -191,7 +191,7 @@ void WFMModSource::modulateAudio() void WFMModSource::prefetch(unsigned int nbSamples) { - unsigned int nbSamplesAudio = nbSamples * ((Real) m_audioSampleRate / (Real) m_channelSampleRate); + unsigned int nbSamplesAudio = (unsigned int) (nbSamples * ((Real) m_audioSampleRate / (Real) m_channelSampleRate)); pullAudio(nbSamplesAudio); } diff --git a/plugins/feature/radiosonde/radiosondegui.cpp b/plugins/feature/radiosonde/radiosondegui.cpp index 066448855e..ecf023eb5e 100644 --- a/plugins/feature/radiosonde/radiosondegui.cpp +++ b/plugins/feature/radiosonde/radiosondegui.cpp @@ -190,6 +190,8 @@ RadiosondeGUI::RadiosondeGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, F // Get updated when position changes connect(&MainCore::instance()->getSettings(), &MainSettings::preferenceChanged, this, &RadiosondeGUI::preferenceChanged); + connect(&m_positionUpdateTimer, &QTimer::timeout, this, &RadiosondeGUI::updatePosition); + m_positionUpdateTimer.setSingleShot(true); ui->radiosondes->setItemDelegateForColumn(RADIOSONDE_COL_LATITUDE, new DecimalDelegate(5, ui->radiosondes)); ui->radiosondes->setItemDelegateForColumn(RADIOSONDE_COL_LONGITUDE, new DecimalDelegate(5, ui->radiosondes)); @@ -979,22 +981,41 @@ QStringList RadiosondeGUI::getRadios() void RadiosondeGUI::updatePosition() { + // Limit number of position updates sent to SondeHub + const int updateTime = m_settings.m_mobile ? m_minMobilePositionUpdateTime : m_minFixedPositionUpdateTime; + if (m_sondeHub && m_settings.m_displayPosition) { - float stationLatitude = MainCore::instance()->getSettings().getLatitude(); - float stationLongitude = MainCore::instance()->getSettings().getLongitude(); - float stationAltitude = MainCore::instance()->getSettings().getAltitude(); - - m_sondeHub->updatePosition( - m_settings.m_callsign, - stationLatitude, - stationLongitude, - stationAltitude, - getRadios().join(" "), - m_settings.m_antenna, - m_settings.m_email, - m_settings.m_mobile - ); + if (!m_lastPositionUpdate.isValid() || (m_lastPositionUpdate.secsTo(QDateTime::currentDateTime()) >= updateTime)) + { + float stationLatitude = MainCore::instance()->getSettings().getLatitude(); + float stationLongitude = MainCore::instance()->getSettings().getLongitude(); + float stationAltitude = MainCore::instance()->getSettings().getAltitude(); + + m_sondeHub->updatePosition( + m_settings.m_callsign, + stationLatitude, + stationLongitude, + stationAltitude, + getRadios().join(" "), + m_settings.m_antenna, + m_settings.m_email, + m_settings.m_mobile + ); + + m_positionUpdateTimer.stop(); + m_lastPositionUpdate = QDateTime::currentDateTime(); + } + else + { + qint64 msecs = (updateTime * 1000) - m_lastPositionUpdate.msecsTo(QDateTime::currentDateTime()); + + if (msecs < 0) { + msecs = 0; + } + m_positionUpdateTimer.setInterval(msecs); + m_positionUpdateTimer.start(); + } } } diff --git a/plugins/feature/radiosonde/radiosondegui.h b/plugins/feature/radiosonde/radiosondegui.h index 124a189ea2..9afb619cd9 100644 --- a/plugins/feature/radiosonde/radiosondegui.h +++ b/plugins/feature/radiosonde/radiosondegui.h @@ -103,6 +103,10 @@ class RadiosondeGUI : public FeatureGUI { QMenu *radiosondesMenu; // Column select context menu SondeHub *m_sondeHub; + QDateTime m_lastPositionUpdate; + QTimer m_positionUpdateTimer; + static const int m_minMobilePositionUpdateTime = 30; // In seconds + static const int m_minFixedPositionUpdateTime = 5 * 60; explicit RadiosondeGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr); virtual ~RadiosondeGUI(); diff --git a/plugins/feature/sid/sidgui.cpp b/plugins/feature/sid/sidgui.cpp index 69c7bd3c8f..2ccd5546eb 100644 --- a/plugins/feature/sid/sidgui.cpp +++ b/plugins/feature/sid/sidgui.cpp @@ -2396,8 +2396,11 @@ void SIDGUI::readCSV(const QString& filename, bool autoload) if (CSV::readRow(in, &colNames)) { QList measurements; - for (int i = 0; i < colNames.size() - 1; i++) { + QList measurementIdx; + for (int i = 0; i < colNames.size() - 1; i++) + { measurements.append(nullptr); + measurementIdx.append(-1); } for (int i = 1; i < colNames.size(); i++) { @@ -2439,7 +2442,8 @@ void SIDGUI::readCSV(const QString& filename, bool autoload) } else { id = name; } - measurements[i-1] = &addMeasurements(id); + addMeasurements(id); + measurementIdx[i-1] = m_channelMeasurements.size() - 1; // Create settings, if we don't have them SIDSettings::ChannelSettings *channelSettings = m_settings.getChannelSettings(id); @@ -2482,7 +2486,11 @@ void SIDGUI::readCSV(const QString& filename, bool autoload) if (!valueStr.isEmpty()) { double value = valueStr.toDouble(); - measurements[i]->append(dateTime, value, false); + if (measurements[i]) { + measurements[i]->append(dateTime, value, false); + } else { + m_channelMeasurements[measurementIdx[i]].append(dateTime, value, false); + } } } } diff --git a/plugins/samplesink/usrpoutput/readme.md b/plugins/samplesink/usrpoutput/readme.md index 812ddcf1ba..2fc29d9603 100644 --- a/plugins/samplesink/usrpoutput/readme.md +++ b/plugins/samplesink/usrpoutput/readme.md @@ -123,3 +123,10 @@ This label turns green when data has been transmitted to the device. - **D**: turns red if stream experiences packet drop outs The stream warning indicators are reset when the acquisition is started. + +

GPIOs

+ +The USRP device settings supports 8-bit `gpioDir` and `gpioPins` settings. These can be set via the Web API or Simple PTT feature. +`gpioDir` can be set to 0 for default ATR (automatic transmit/receive) functionality or 1 for GPIO output. +On the b210, the GPIOs are on J504 header. Bit 0 corresponds to pin 1. +On other USRP devices, that may have multiple GPIO banks, these settings correspond to bank `FP0` (Front panel). diff --git a/plugins/samplesink/usrpoutput/usrpoutput.cpp b/plugins/samplesink/usrpoutput/usrpoutput.cpp index 8f9444e8ac..9fe77db39a 100644 --- a/plugins/samplesink/usrpoutput/usrpoutput.cpp +++ b/plugins/samplesink/usrpoutput/usrpoutput.cpp @@ -813,6 +813,25 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, const QListgetDevice()) + { + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "CTRL", ~settings.m_gpioDir, 0xff); // 0 for GPIO, 1 for ATR + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "DDR", settings.m_gpioDir, 0xff); // 0 for input, 1 for output + qDebug() << "USRPOutput::applySettings: set GPIO dir to " << settings.m_gpioDir; + } + } + + if (settingsKeys.contains("gpioPins") || force) + { + if (m_deviceShared.m_deviceParams->getDevice()) + { + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "OUT", settings.m_gpioPins, 0xff); + qDebug() << "USRPOutput::applySettings: set GPIO pins to " << settings.m_gpioPins; + } + } + if (settingsKeys.contains("useReverseAPI")) { bool fullUpdate = (settingsKeys.contains("useReverseAPI") && settings.m_useReverseAPI) || @@ -1036,6 +1055,12 @@ void USRPOutput::webapiUpdateDeviceSettings( if (deviceSettingsKeys.contains("transverterMode")) { settings.m_transverterMode = response.getUsrpOutputSettings()->getTransverterMode() != 0; } + if (deviceSettingsKeys.contains("gpioDir")) { + settings.m_gpioDir = response.getUsrpOutputSettings()->getGpioDir(); + } + if (deviceSettingsKeys.contains("gpioPins")) { + settings.m_gpioPins = response.getUsrpOutputSettings()->getGpioPins(); + } if (deviceSettingsKeys.contains("useReverseAPI")) { settings.m_useReverseAPI = response.getUsrpOutputSettings()->getUseReverseApi() != 0; } @@ -1072,6 +1097,8 @@ void USRPOutput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& resp response.getUsrpOutputSettings()->setLpfBw(settings.m_lpfBW); response.getUsrpOutputSettings()->setTransverterDeltaFrequency(settings.m_transverterDeltaFrequency); response.getUsrpOutputSettings()->setTransverterMode(settings.m_transverterMode ? 1 : 0); + response.getUsrpOutputSettings()->setGpioDir(settings.m_gpioDir); + response.getUsrpOutputSettings()->setGpioPins(settings.m_gpioPins); response.getUsrpOutputSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); if (response.getUsrpOutputSettings()->getReverseApiAddress()) { @@ -1172,6 +1199,12 @@ void USRPOutput::webapiReverseSendSettings(const QList& deviceSettingsK if (deviceSettingsKeys.contains("transverterMode") || force) { swgUsrpOutputSettings->setTransverterMode(settings.m_transverterMode ? 1 : 0); } + if (deviceSettingsKeys.contains("gpioDir") || force) { + swgUsrpOutputSettings->setGpioDir(settings.m_gpioDir); + } + if (deviceSettingsKeys.contains("gpioPins") || force) { + swgUsrpOutputSettings->setGpioPins(settings.m_gpioPins); + } QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings") .arg(settings.m_reverseAPIAddress) diff --git a/plugins/samplesink/usrpoutput/usrpoutputsettings.cpp b/plugins/samplesink/usrpoutput/usrpoutputsettings.cpp index c762072670..a726884fae 100644 --- a/plugins/samplesink/usrpoutput/usrpoutputsettings.cpp +++ b/plugins/samplesink/usrpoutput/usrpoutputsettings.cpp @@ -40,6 +40,8 @@ void USRPOutputSettings::resetToDefaults() m_clockSource = "internal"; m_transverterMode = false; m_transverterDeltaFrequency = 0; + m_gpioDir = 0; + m_gpioPins = 0; m_useReverseAPI = false; m_reverseAPIAddress = "127.0.0.1"; m_reverseAPIPort = 8888; @@ -63,6 +65,8 @@ QByteArray USRPOutputSettings::serialize() const s.writeU32(11, m_reverseAPIPort); s.writeU32(12, m_reverseAPIDeviceIndex); s.writeS32(13, m_loOffset); + s.writeU32(14, m_gpioDir); + s.writeU32(15, m_gpioPins); return s.final(); } @@ -102,6 +106,10 @@ bool USRPOutputSettings::deserialize(const QByteArray& data) d.readU32(12, &uintval, 0); m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval; d.readS32(13, &m_loOffset, 0); + d.readU32(14, &uintval, 0); + m_gpioDir = uintval & 0xFF; + d.readU32(15, &uintval, 0); + m_gpioPins = uintval & 0xFF; return true; } @@ -148,6 +156,12 @@ void USRPOutputSettings::applySettings(const QStringList& settingsKeys, const US if (settingsKeys.contains("transverterDeltaFrequency")) { m_transverterDeltaFrequency = settings.m_transverterDeltaFrequency; } + if (settingsKeys.contains("gpioDir")) { + m_gpioDir = settings.m_gpioDir; + } + if (settingsKeys.contains("gpioPins")) { + m_gpioPins = settings.m_gpioPins; + } if (settingsKeys.contains("useReverseAPI")) { m_useReverseAPI = settings.m_useReverseAPI; } @@ -199,6 +213,12 @@ QString USRPOutputSettings::getDebugString(const QStringList& settingsKeys, bool if (settingsKeys.contains("transverterDeltaFrequency") || force) { ostr << " m_transverterDeltaFrequency: " << m_transverterDeltaFrequency; } + if (settingsKeys.contains("gpioDir") || force) { + ostr << " m_gpioDir: " << (int) m_gpioDir; + } + if (settingsKeys.contains("gpioPins") || force) { + ostr << " m_gpioPins: " << (int) m_gpioPins; + } if (settingsKeys.contains("useReverseAPI") || force) { ostr << " m_useReverseAPI: " << m_useReverseAPI; } diff --git a/plugins/samplesink/usrpoutput/usrpoutputsettings.h b/plugins/samplesink/usrpoutput/usrpoutputsettings.h index ec07c179e5..3b11fcafff 100644 --- a/plugins/samplesink/usrpoutput/usrpoutputsettings.h +++ b/plugins/samplesink/usrpoutput/usrpoutputsettings.h @@ -45,6 +45,8 @@ struct USRPOutputSettings QString m_clockSource; bool m_transverterMode; qint64 m_transverterDeltaFrequency; + uint8_t m_gpioDir; //!< GPIO pin direction; 0 ATR (automatic transmit/receive), 1 output + uint8_t m_gpioPins; //!< GPIO pins levels for outputs bool m_useReverseAPI; QString m_reverseAPIAddress; uint16_t m_reverseAPIPort; diff --git a/plugins/samplesource/usrpinput/readme.md b/plugins/samplesource/usrpinput/readme.md index 572268f50e..39feeb1d6d 100644 --- a/plugins/samplesource/usrpinput/readme.md +++ b/plugins/samplesource/usrpinput/readme.md @@ -143,3 +143,10 @@ On Ubuntu 20, the libuhd-dev package should be installed. The FPGA images then n ```shell sudo /usr/lib/uhd/utils/uhd_images_downloader.py ``` + +

GPIOs

+ +The USRP device settings supports 8-bit `gpioDir` and `gpioPins` settings. These can be set via the Web API or Simple PTT feature. +`gpioDir` can be set to 0 for default ATR (automatic transmit/receive) functionality or 1 for GPIO output. +On the b210, the GPIOs are on J504 header. Bit 0 corresponds to pin 1. +On other USRP devices, that may have multiple GPIO banks, these settings correspond to bank `FP0` (Front panel). diff --git a/plugins/samplesource/usrpinput/usrpinput.cpp b/plugins/samplesource/usrpinput/usrpinput.cpp index b6d8eb1c7c..acc408d82d 100644 --- a/plugins/samplesource/usrpinput/usrpinput.cpp +++ b/plugins/samplesource/usrpinput/usrpinput.cpp @@ -895,6 +895,25 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, const QListgetDevice()) + { + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "CTRL", ~settings.m_gpioDir, 0xff); // 0 for GPIO, 1 for ATR + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "DDR", settings.m_gpioDir, 0xff); // 0 for input, 1 for output + qDebug() << "USRPInput::applySettings: set GPIO dir to " << settings.m_gpioDir; + } + } + + if (settingsKeys.contains("gpioPins") || force) + { + if (m_deviceShared.m_deviceParams->getDevice()) + { + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "OUT", settings.m_gpioPins, 0xff); + qDebug() << "USRPInput::applySettings: set GPIO pins to " << settings.m_gpioPins; + } + } + if (settingsKeys.contains("useReverseAPI")) { bool fullUpdate = (settingsKeys.contains("useReverseAPI") && settings.m_useReverseAPI) || @@ -1162,6 +1181,12 @@ void USRPInput::webapiUpdateDeviceSettings( if (deviceSettingsKeys.contains("transverterMode")) { settings.m_transverterMode = response.getUsrpInputSettings()->getTransverterMode() != 0; } + if (deviceSettingsKeys.contains("gpioDir")) { + settings.m_gpioDir = response.getUsrpInputSettings()->getGpioDir(); + } + if (deviceSettingsKeys.contains("gpioPins")) { + settings.m_gpioPins = response.getUsrpInputSettings()->getGpioPins(); + } if (deviceSettingsKeys.contains("useReverseAPI")) { settings.m_useReverseAPI = response.getUsrpInputSettings()->getUseReverseApi() != 0; } @@ -1191,6 +1216,8 @@ void USRPInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& respo response.getUsrpInputSettings()->setLpfBw(settings.m_lpfBW); response.getUsrpInputSettings()->setTransverterDeltaFrequency(settings.m_transverterDeltaFrequency); response.getUsrpInputSettings()->setTransverterMode(settings.m_transverterMode ? 1 : 0); + response.getUsrpInputSettings()->setGpioDir(settings.m_gpioDir); + response.getUsrpInputSettings()->setGpioPins(settings.m_gpioPins); response.getUsrpInputSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); if (response.getUsrpInputSettings()->getReverseApiAddress()) { @@ -1311,6 +1338,12 @@ void USRPInput::webapiReverseSendSettings(const QList& deviceSettingsKe if (deviceSettingsKeys.contains("transverterMode") || force) { swgUsrpInputSettings->setTransverterMode(settings.m_transverterMode ? 1 : 0); } + if (deviceSettingsKeys.contains("gpioDir") || force) { + swgUsrpInputSettings->setGpioDir(settings.m_gpioDir); + } + if (deviceSettingsKeys.contains("gpioPins") || force) { + swgUsrpInputSettings->setGpioPins(settings.m_gpioPins); + } QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings") .arg(settings.m_reverseAPIAddress) diff --git a/plugins/samplesource/usrpinput/usrpinputsettings.cpp b/plugins/samplesource/usrpinput/usrpinputsettings.cpp index e1b1381a26..82fec7e17e 100644 --- a/plugins/samplesource/usrpinput/usrpinputsettings.cpp +++ b/plugins/samplesource/usrpinput/usrpinputsettings.cpp @@ -46,6 +46,8 @@ void USRPInputSettings::resetToDefaults() m_replayLength = 20.0f; m_replayStep = 5.0f; m_replayLoop = false; + m_gpioDir = 0; + m_gpioPins = 0; m_useReverseAPI = false; m_reverseAPIAddress = "127.0.0.1"; m_reverseAPIPort = 8888; @@ -76,6 +78,8 @@ QByteArray USRPInputSettings::serialize() const s.writeFloat(18, m_replayLength); s.writeFloat(19, m_replayStep); s.writeBool(20, m_replayLoop); + s.writeU32(21, m_gpioDir); + s.writeU32(22, m_gpioPins); return s.final(); } @@ -124,6 +128,10 @@ bool USRPInputSettings::deserialize(const QByteArray& data) d.readFloat(18, &m_replayLength, 20.0f); d.readFloat(19, &m_replayStep, 5.0f); d.readBool(20, &m_replayLoop, false); + d.readU32(21, &uintval, 0); + m_gpioDir = uintval & 0xFF; + d.readU32(22, &uintval, 0); + m_gpioPins = uintval & 0xFF; return true; } @@ -191,6 +199,12 @@ void USRPInputSettings::applySettings(const QStringList& settingsKeys, const USR if (settingsKeys.contains("replayLoop")) { m_replayLoop = settings.m_replayLoop; } + if (settingsKeys.contains("gpioDir")) { + m_gpioDir = settings.m_gpioDir; + } + if (settingsKeys.contains("gpioPins")) { + m_gpioPins = settings.m_gpioPins; + } if (settingsKeys.contains("useReverseAPI")) { m_useReverseAPI = settings.m_useReverseAPI; } @@ -263,6 +277,12 @@ QString USRPInputSettings::getDebugString(const QStringList& settingsKeys, bool if (settingsKeys.contains("replayLoop") || force) { ostr << " m_replayLoop: " << m_replayLoop; } + if (settingsKeys.contains("gpioDir") || force) { + ostr << " m_gpioDir: " << (int) m_gpioDir; + } + if (settingsKeys.contains("gpioPins") || force) { + ostr << " m_gpioPins: " << (int) m_gpioPins; + } if (settingsKeys.contains("useReverseAPI") || force) { ostr << " m_useReverseAPI: " << m_useReverseAPI; } diff --git a/plugins/samplesource/usrpinput/usrpinputsettings.h b/plugins/samplesource/usrpinput/usrpinputsettings.h index ae2f6e15df..774e62bde6 100644 --- a/plugins/samplesource/usrpinput/usrpinputsettings.h +++ b/plugins/samplesource/usrpinput/usrpinputsettings.h @@ -52,10 +52,12 @@ struct USRPInputSettings QString m_clockSource; bool m_transverterMode; qint64 m_transverterDeltaFrequency; - float m_replayOffset; //!< Replay offset in seconds + float m_replayOffset; //!< Replay offset in seconds float m_replayLength; //!< Replay buffer size in seconds float m_replayStep; //!< Replay forward/back step size in seconds bool m_replayLoop; //!< Replay buffer repeatedly without recording new data + uint8_t m_gpioDir; //!< GPIO pin direction; 0 ATR (automatic transmit/receive), 1 output + uint8_t m_gpioPins; //!< GPIO pins levels for outputs bool m_useReverseAPI; QString m_reverseAPIAddress; uint16_t m_reverseAPIPort; diff --git a/sdrbase/channel/channelwebapiutils.cpp b/sdrbase/channel/channelwebapiutils.cpp index 6a26b90188..e5e09ee0a5 100644 --- a/sdrbase/channel/channelwebapiutils.cpp +++ b/sdrbase/channel/channelwebapiutils.cpp @@ -1319,9 +1319,15 @@ bool ChannelWebAPIUtils::patchDeviceSetting(unsigned int deviceIndex, const QStr SWGSDRangel::SWGErrorResponse errorResponse2; delete jsonObj; - DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource(); - - httpRC = source->webapiSettingsPutPatch(false, deviceSettingsKeys, deviceSettingsResponse, *errorResponse2.getMessage()); + if (DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource()) { + httpRC = source->webapiSettingsPutPatch(false, deviceSettingsKeys, deviceSettingsResponse, *errorResponse2.getMessage()); + } else if (DeviceSampleSink *sink = deviceSet->m_deviceAPI->getSampleSink()) { + httpRC = sink->webapiSettingsPutPatch(false, deviceSettingsKeys, deviceSettingsResponse, *errorResponse2.getMessage()); + } else if (DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO()) { + httpRC = mimo->webapiSettingsPutPatch(false, deviceSettingsKeys, deviceSettingsResponse, *errorResponse2.getMessage()); + } else { + httpRC = 404; + } if (httpRC/100 == 2) { diff --git a/sdrbase/feature/featurewebapiutils.cpp b/sdrbase/feature/featurewebapiutils.cpp index 45832bb96a..84303acda5 100644 --- a/sdrbase/feature/featurewebapiutils.cpp +++ b/sdrbase/feature/featurewebapiutils.cpp @@ -20,12 +20,42 @@ #include "SWGFeatureActions.h" #include "SWGMapActions.h" #include "SWGPERTesterActions.h" +#include "SWGDeviceState.h" #include "maincore.h" #include "feature/featureset.h" #include "feature/feature.h" #include "featurewebapiutils.h" +// Start feature +bool FeatureWebAPIUtils::run(int featureSetIndex, int featureIndex) +{ + Feature *feature = FeatureWebAPIUtils::getFeature(featureSetIndex, featureIndex, ""); + if (feature != nullptr) + { + SWGSDRangel::SWGDeviceState runResponse; + QString errorResponse; + int httpRC; + + runResponse.setState(new QString()); + httpRC = feature->webapiRun(true, runResponse, errorResponse); + + if (httpRC/100 != 2) + { + qWarning("FeatureWebAPIUtils::run: run error %d: %s", + httpRC, qPrintable(errorResponse)); + return false; + } + + return true; + } + else + { + qWarning("FeatureWebAPIUtils::run: no feature F%d:%d", featureSetIndex, featureIndex); + return false; + } +} + // Find the specified target on the map bool FeatureWebAPIUtils::mapFind(const QString& target, int featureSetIndex, int featureIndex) { diff --git a/sdrbase/feature/featurewebapiutils.h b/sdrbase/feature/featurewebapiutils.h index d0448892cf..ddad1ae821 100644 --- a/sdrbase/feature/featurewebapiutils.h +++ b/sdrbase/feature/featurewebapiutils.h @@ -47,6 +47,7 @@ private slots: class SDRBASE_API FeatureWebAPIUtils { public: + static bool run(int featureSetIndex, int featureIndex); static bool mapFind(const QString& target, int featureSetIndex=-1, int featureIndex=-1); static bool mapSetDateTime(const QDateTime& dateTime, int featureSetIndex=-1, int featureIndex=-1); static bool skyMapFind(const QString& target, int featureSetIndex=-1, int featureIndex=-1); diff --git a/sdrbase/mainparser.cpp b/sdrbase/mainparser.cpp index 3735a5103d..1456b8f259 100644 --- a/sdrbase/mainparser.cpp +++ b/sdrbase/mainparser.cpp @@ -42,7 +42,8 @@ MainParser::MainParser() : m_remoteTCPSinkPortOption("remote-tcp-port", "Remote TCP Sink port (Default 1234).", "port", "1234"), m_remoteTCPSinkHWTypeOption("remote-tcp-hwtype", "Remote TCP Sink device hardware type (Optional. E.g. RTLSDR/SDRplayV3/AirspyHF).", "hwtype"), m_remoteTCPSinkSerialOption("remote-tcp-serial", "Remote TCP Sink device serial (Optional).", "serial"), - m_listDevicesOption("list-devices", "List available physical devices.") + m_listDevicesOption("list-devices", "List available physical devices."), + m_startOption("start", "Start all devices and features") { m_serverAddress = ""; // Bind to any address @@ -56,6 +57,7 @@ MainParser::MainParser() : m_remoteTCPSinkHWType = ""; m_remoteTCPSinkSerial = ""; m_listDevices = false; + m_start = false; m_parser.setApplicationDescription("Software Defined Radio application"); m_parser.addHelpOption(); @@ -72,6 +74,7 @@ MainParser::MainParser() : m_parser.addOption(m_remoteTCPSinkHWTypeOption); m_parser.addOption(m_remoteTCPSinkSerialOption); m_parser.addOption(m_listDevicesOption); + m_parser.addOption(m_startOption); } MainParser::~MainParser() @@ -154,4 +157,8 @@ void MainParser::parse(const QCoreApplication& app) qCritical() << "You must specify a device with either --remote-tcp-hwtype or --remote-tcp-serial"; exit (EXIT_FAILURE); } + + // Start devices and features + m_start = m_parser.isSet(m_startOption); + } diff --git a/sdrbase/mainparser.h b/sdrbase/mainparser.h index d38be74ba7..220db95bb7 100644 --- a/sdrbase/mainparser.h +++ b/sdrbase/mainparser.h @@ -45,6 +45,7 @@ class SDRBASE_API MainParser const QString& getRemoteTCPSinkHWType() const { return m_remoteTCPSinkHWType; } const QString& getRemoteTCPSinkSerial() const { return m_remoteTCPSinkSerial; } bool getListDevices() const { return m_listDevices; } + bool getStart() const { return m_start; } private: QString m_serverAddress; @@ -58,6 +59,7 @@ class SDRBASE_API MainParser QString m_remoteTCPSinkHWType; QString m_remoteTCPSinkSerial; bool m_listDevices; + bool m_start; QCommandLineParser m_parser; QCommandLineOption m_serverAddressOption; @@ -71,6 +73,7 @@ class SDRBASE_API MainParser QCommandLineOption m_remoteTCPSinkHWTypeOption; QCommandLineOption m_remoteTCPSinkSerialOption; QCommandLineOption m_listDevicesOption; + QCommandLineOption m_startOption; }; diff --git a/sdrbase/resources/webapi/doc/html2/index.html b/sdrbase/resources/webapi/doc/html2/index.html index cb1da788d6..ff653dee97 100644 --- a/sdrbase/resources/webapi/doc/html2/index.html +++ b/sdrbase/resources/webapi/doc/html2/index.html @@ -13451,6 +13451,18 @@ "properties" : { "sampleRate" : { "type" : "integer" + }, + "latitude" : { + "type" : "number", + "format" : "float" + }, + "longitude" : { + "type" : "number", + "format" : "float" + }, + "altitude" : { + "type" : "number", + "format" : "float" } }, "description" : "RemoteTCPInput" @@ -16824,6 +16836,14 @@ "type" : "integer", "format" : "int64" }, + "gpioDir" : { + "type" : "integer", + "format" : "int8" + }, + "gpioPins" : { + "type" : "integer", + "format" : "int8" + }, "useReverseAPI" : { "type" : "integer", "description" : "Synchronize with reverse API (1 for yes, 0 for no)" @@ -16893,6 +16913,14 @@ "type" : "integer", "format" : "int64" }, + "gpioDir" : { + "type" : "integer", + "format" : "int8" + }, + "gpioPins" : { + "type" : "integer", + "format" : "int8" + }, "useReverseAPI" : { "type" : "integer", "description" : "Synchronize with reverse API (1 for yes, 0 for no)" @@ -59441,7 +59469,7 @@

Status: 501 - Function not implemented

- Generated 2024-07-16T23:20:27.082+02:00 + Generated 2024-12-24T11:56:24.260+01:00
diff --git a/sdrbase/resources/webapi/doc/swagger/include/RemoteTCPInput.yaml b/sdrbase/resources/webapi/doc/swagger/include/RemoteTCPInput.yaml index 09cc073e60..c27b4e712e 100644 --- a/sdrbase/resources/webapi/doc/swagger/include/RemoteTCPInput.yaml +++ b/sdrbase/resources/webapi/doc/swagger/include/RemoteTCPInput.yaml @@ -61,3 +61,12 @@ RemoteTCPInputReport: properties: sampleRate: type: integer + latitude: + type: number + format: float + longitude: + type: number + format: float + altitude: + type: number + format: float diff --git a/sdrbase/resources/webapi/doc/swagger/include/USRP.yaml b/sdrbase/resources/webapi/doc/swagger/include/USRP.yaml index e388f288fc..169094c7b5 100644 --- a/sdrbase/resources/webapi/doc/swagger/include/USRP.yaml +++ b/sdrbase/resources/webapi/doc/swagger/include/USRP.yaml @@ -30,6 +30,12 @@ USRPInputSettings: transverterDeltaFrequency: type: integer format: int64 + gpioDir: + type: integer + format: int8 + gpioPins: + type: integer + format: int8 useReverseAPI: description: Synchronize with reverse API (1 for yes, 0 for no) type: integer @@ -65,6 +71,12 @@ USRPOutputSettings: transverterDeltaFrequency: type: integer format: int64 + gpioDir: + type: integer + format: int8 + gpioPins: + type: integer + format: int8 useReverseAPI: description: Synchronize with reverse API (1 for yes, 0 for no) type: integer diff --git a/sdrbase/util/colormap.cpp b/sdrbase/util/colormap.cpp index e2678c648a..4f7065415e 100644 --- a/sdrbase/util/colormap.cpp +++ b/sdrbase/util/colormap.cpp @@ -72,6 +72,7 @@ QHash ColorMap::m_colorMaps{ {"Cubehlx2", &m_cubehlx2[0]}, {"Icy", &m_icy[0]}, {"Mint", &m_mint[0]}, + {"A.C.A.B.", &m_acab[0]}, }; const float ColorMap::m_angel[m_size] = @@ -7102,3 +7103,263 @@ const float ColorMap::m_mint[m_size] = 0.999, 0.997, 0.995, 1.000, 1.000, 1.000, }; + +const float ColorMap::m_acab[m_size] = +{ + 0.00000, 0.00000, 0.00000, + 0.01042, 0.01042, 0.01042, + 0.02083, 0.02083, 0.02083, + 0.03125, 0.03125, 0.03125, + 0.04167, 0.04167, 0.04167, + 0.05208, 0.05208, 0.05208, + 0.06250, 0.06250, 0.06250, + 0.07292, 0.07292, 0.07292, + 0.08333, 0.08333, 0.08333, + 0.09375, 0.09375, 0.09375, + 0.10417, 0.10417, 0.10417, + 0.11458, 0.11458, 0.11458, + 0.12500, 0.12500, 0.12500, + 0.13542, 0.13542, 0.13542, + 0.14583, 0.14583, 0.14583, + 0.15625, 0.15625, 0.15625, + 0.16667, 0.16667, 0.16667, + 0.17708, 0.17708, 0.17708, + 0.18750, 0.18750, 0.18750, + 0.19792, 0.19792, 0.19792, + 0.20833, 0.20833, 0.20833, + 0.21875, 0.21875, 0.21875, + 0.22917, 0.22917, 0.22917, + 0.23958, 0.23958, 0.23958, + 0.25000, 0.25000, 0.25000, + 0.26042, 0.26042, 0.26042, + 0.27083, 0.27083, 0.27083, + 0.28125, 0.28125, 0.28125, + 0.29167, 0.29167, 0.29167, + 0.30208, 0.30208, 0.30208, + 0.31250, 0.31250, 0.31250, + 0.32292, 0.32292, 0.32292, + 0.33333, 0.33333, 0.33333, + 0.32292, 0.32292, 0.35417, + 0.31250, 0.31250, 0.37500, + 0.30208, 0.30208, 0.39583, + 0.29167, 0.29167, 0.41667, + 0.28125, 0.28125, 0.43750, + 0.27083, 0.27083, 0.45833, + 0.26042, 0.26042, 0.47917, + 0.25000, 0.25000, 0.50000, + 0.23958, 0.23958, 0.52083, + 0.22917, 0.22917, 0.54167, + 0.21875, 0.21875, 0.56250, + 0.20833, 0.20833, 0.58333, + 0.19792, 0.19792, 0.60417, + 0.18750, 0.18750, 0.62500, + 0.17708, 0.17708, 0.64583, + 0.16667, 0.16667, 0.66667, + 0.15625, 0.15625, 0.68750, + 0.14583, 0.14583, 0.70833, + 0.13542, 0.13542, 0.72917, + 0.12500, 0.12500, 0.75000, + 0.11458, 0.11458, 0.77083, + 0.10417, 0.10417, 0.79167, + 0.09375, 0.09375, 0.81250, + 0.08333, 0.08333, 0.83333, + 0.07292, 0.07292, 0.85417, + 0.06250, 0.06250, 0.87500, + 0.05208, 0.05208, 0.89583, + 0.04167, 0.04167, 0.91667, + 0.03125, 0.03125, 0.93750, + 0.02083, 0.02083, 0.95833, + 0.01042, 0.01042, 0.97917, + 0.00000, 0.00000, 1.00000, + 0.00000, 0.03125, 1.00000, + 0.00000, 0.06250, 1.00000, + 0.00000, 0.09375, 1.00000, + 0.00000, 0.12500, 1.00000, + 0.00000, 0.15625, 1.00000, + 0.00000, 0.18750, 1.00000, + 0.00000, 0.21875, 1.00000, + 0.00000, 0.25000, 1.00000, + 0.00000, 0.28125, 1.00000, + 0.00000, 0.31250, 1.00000, + 0.00000, 0.34375, 1.00000, + 0.00000, 0.37500, 1.00000, + 0.00000, 0.40625, 1.00000, + 0.00000, 0.43750, 1.00000, + 0.00000, 0.46875, 1.00000, + 0.00000, 0.50000, 1.00000, + 0.00000, 0.53125, 1.00000, + 0.00000, 0.56250, 1.00000, + 0.00000, 0.59375, 1.00000, + 0.00000, 0.62500, 1.00000, + 0.00000, 0.65625, 1.00000, + 0.00000, 0.68750, 1.00000, + 0.00000, 0.71875, 1.00000, + 0.00000, 0.75000, 1.00000, + 0.00000, 0.78125, 1.00000, + 0.00000, 0.81250, 1.00000, + 0.00000, 0.84375, 1.00000, + 0.00000, 0.87500, 1.00000, + 0.00000, 0.90625, 1.00000, + 0.00000, 0.93750, 1.00000, + 0.00000, 0.96875, 1.00000, + 0.00000, 1.00000, 1.00000, + 0.00000, 1.00000, 0.96875, + 0.00000, 1.00000, 0.93750, + 0.00000, 1.00000, 0.90625, + 0.00000, 1.00000, 0.87500, + 0.00000, 1.00000, 0.84375, + 0.00000, 1.00000, 0.81250, + 0.00000, 1.00000, 0.78125, + 0.00000, 1.00000, 0.75000, + 0.00000, 1.00000, 0.71875, + 0.00000, 1.00000, 0.68750, + 0.00000, 1.00000, 0.65625, + 0.00000, 1.00000, 0.62500, + 0.00000, 1.00000, 0.59375, + 0.00000, 1.00000, 0.56250, + 0.00000, 1.00000, 0.53125, + 0.00000, 1.00000, 0.50000, + 0.00000, 1.00000, 0.46875, + 0.00000, 1.00000, 0.43750, + 0.00000, 1.00000, 0.40625, + 0.00000, 1.00000, 0.37500, + 0.00000, 1.00000, 0.34375, + 0.00000, 1.00000, 0.31250, + 0.00000, 1.00000, 0.28125, + 0.00000, 1.00000, 0.25000, + 0.00000, 1.00000, 0.21875, + 0.00000, 1.00000, 0.18750, + 0.00000, 1.00000, 0.15625, + 0.00000, 1.00000, 0.12500, + 0.00000, 1.00000, 0.09375, + 0.00000, 1.00000, 0.06250, + 0.00000, 1.00000, 0.03125, + 0.00000, 1.00000, 0.00000, + 0.03125, 1.00000, 0.00000, + 0.06250, 1.00000, 0.00000, + 0.09375, 1.00000, 0.00000, + 0.12500, 1.00000, 0.00000, + 0.15625, 1.00000, 0.00000, + 0.18750, 1.00000, 0.00000, + 0.21875, 1.00000, 0.00000, + 0.25000, 1.00000, 0.00000, + 0.28125, 1.00000, 0.00000, + 0.31250, 1.00000, 0.00000, + 0.34375, 1.00000, 0.00000, + 0.37500, 1.00000, 0.00000, + 0.40625, 1.00000, 0.00000, + 0.43750, 1.00000, 0.00000, + 0.46875, 1.00000, 0.00000, + 0.50000, 1.00000, 0.00000, + 0.53125, 1.00000, 0.00000, + 0.56250, 1.00000, 0.00000, + 0.59375, 1.00000, 0.00000, + 0.62500, 1.00000, 0.00000, + 0.65625, 1.00000, 0.00000, + 0.68750, 1.00000, 0.00000, + 0.71875, 1.00000, 0.00000, + 0.75000, 1.00000, 0.00000, + 0.78125, 1.00000, 0.00000, + 0.81250, 1.00000, 0.00000, + 0.84375, 1.00000, 0.00000, + 0.87500, 1.00000, 0.00000, + 0.90625, 1.00000, 0.00000, + 0.93750, 1.00000, 0.00000, + 0.96875, 1.00000, 0.00000, + 1.00000, 1.00000, 0.00000, + 1.00000, 0.96875, 0.00000, + 1.00000, 0.93750, 0.00000, + 1.00000, 0.90625, 0.00000, + 1.00000, 0.87500, 0.00000, + 1.00000, 0.84375, 0.00000, + 1.00000, 0.81250, 0.00000, + 1.00000, 0.78125, 0.00000, + 1.00000, 0.75000, 0.00000, + 1.00000, 0.71875, 0.00000, + 1.00000, 0.68750, 0.00000, + 1.00000, 0.65625, 0.00000, + 1.00000, 0.62500, 0.00000, + 1.00000, 0.59375, 0.00000, + 1.00000, 0.56250, 0.00000, + 1.00000, 0.53125, 0.00000, + 1.00000, 0.50000, 0.00000, + 1.00000, 0.46875, 0.00000, + 1.00000, 0.43750, 0.00000, + 1.00000, 0.40625, 0.00000, + 1.00000, 0.37500, 0.00000, + 1.00000, 0.34375, 0.00000, + 1.00000, 0.31250, 0.00000, + 1.00000, 0.28125, 0.00000, + 1.00000, 0.25000, 0.00000, + 1.00000, 0.21875, 0.00000, + 1.00000, 0.18750, 0.00000, + 1.00000, 0.15625, 0.00000, + 1.00000, 0.12500, 0.00000, + 1.00000, 0.09375, 0.00000, + 1.00000, 0.06250, 0.00000, + 1.00000, 0.03125, 0.00000, + 1.00000, 0.00000, 0.00000, + 1.00000, 0.00000, 0.03125, + 1.00000, 0.00000, 0.06250, + 1.00000, 0.00000, 0.09375, + 1.00000, 0.00000, 0.12500, + 1.00000, 0.00000, 0.15625, + 1.00000, 0.00000, 0.18750, + 1.00000, 0.00000, 0.21875, + 1.00000, 0.00000, 0.25000, + 1.00000, 0.00000, 0.28125, + 1.00000, 0.00000, 0.31250, + 1.00000, 0.00000, 0.34375, + 1.00000, 0.00000, 0.37500, + 1.00000, 0.00000, 0.40625, + 1.00000, 0.00000, 0.43750, + 1.00000, 0.00000, 0.46875, + 1.00000, 0.00000, 0.50000, + 1.00000, 0.00000, 0.53125, + 1.00000, 0.00000, 0.56250, + 1.00000, 0.00000, 0.59375, + 1.00000, 0.00000, 0.62500, + 1.00000, 0.00000, 0.65625, + 1.00000, 0.00000, 0.68750, + 1.00000, 0.00000, 0.71875, + 1.00000, 0.00000, 0.75000, + 1.00000, 0.00000, 0.78125, + 1.00000, 0.00000, 0.81250, + 1.00000, 0.00000, 0.84375, + 1.00000, 0.00000, 0.87500, + 1.00000, 0.00000, 0.90625, + 1.00000, 0.00000, 0.93750, + 1.00000, 0.00000, 0.96875, + 1.00000, 0.00000, 1.00000, + 1.00000, 0.03125, 1.00000, + 1.00000, 0.06250, 1.00000, + 1.00000, 0.09375, 1.00000, + 1.00000, 0.12500, 1.00000, + 1.00000, 0.15625, 1.00000, + 1.00000, 0.18750, 1.00000, + 1.00000, 0.21875, 1.00000, + 1.00000, 0.25000, 1.00000, + 1.00000, 0.28125, 1.00000, + 1.00000, 0.31250, 1.00000, + 1.00000, 0.34375, 1.00000, + 1.00000, 0.37500, 1.00000, + 1.00000, 0.40625, 1.00000, + 1.00000, 0.43750, 1.00000, + 1.00000, 0.46875, 1.00000, + 1.00000, 0.50000, 1.00000, + 1.00000, 0.53125, 1.00000, + 1.00000, 0.56250, 1.00000, + 1.00000, 0.59375, 1.00000, + 1.00000, 0.62500, 1.00000, + 1.00000, 0.65625, 1.00000, + 1.00000, 0.68750, 1.00000, + 1.00000, 0.71875, 1.00000, + 1.00000, 0.75000, 1.00000, + 1.00000, 0.78125, 1.00000, + 1.00000, 0.81250, 1.00000, + 1.00000, 0.84375, 1.00000, + 1.00000, 0.87500, 1.00000, + 1.00000, 0.90625, 1.00000, + 1.00000, 0.93750, 1.00000, + 1.00000, 0.96875, 1.00000, +}; diff --git a/sdrbase/util/colormap.h b/sdrbase/util/colormap.h index 110b1a04f1..ae7399b27a 100644 --- a/sdrbase/util/colormap.h +++ b/sdrbase/util/colormap.h @@ -69,6 +69,7 @@ class SDRBASE_API ColorMap static const float m_cubehlx2[m_size]; static const float m_icy[m_size]; static const float m_mint[m_size]; + static const float m_acab[m_size]; }; #endif diff --git a/sdrbase/util/sondehub.cpp b/sdrbase/util/sondehub.cpp index 75c00c76fe..9cb76158c0 100644 --- a/sdrbase/util/sondehub.cpp +++ b/sdrbase/util/sondehub.cpp @@ -126,6 +126,7 @@ void SondeHub::upload( obj.insert("subtype", subframe->getType()); } + //obj.insert("dev", true); //qDebug() << obj; QJsonArray payloads { obj @@ -189,7 +190,43 @@ void SondeHub::handleReply(QNetworkReply* reply) if (!reply->error()) { QByteArray bytes = reply->readAll(); - //qDebug() << bytes; + QJsonDocument document = QJsonDocument::fromJson(bytes); + if (document.isObject()) + { + QJsonObject obj = document.object(); + if (obj.contains(QStringLiteral("message"))) + { + QString message = obj.value(QStringLiteral("message")).toString(); + qWarning() << "SondeHub message:" << message; + } + if (obj.contains(QStringLiteral("errors"))) + { + QJsonArray errors = obj.value(QStringLiteral("errors")).toArray(); + for (auto errorObjRef : errors) + { + QJsonObject errorObj = errorObjRef.toObject(); + if (errorObj.contains(QStringLiteral("error_message"))) + { + QString errorMessage = errorObj.value(QStringLiteral("error_message")).toString(); + qWarning() << "SondeHub error:" << errorMessage; + if (errorObj.contains(QStringLiteral("payload"))) + { + QJsonObject payload = errorObj.value(QStringLiteral("payload")).toObject(); + qWarning() << "SondeHub error:" << QJsonDocument(payload); + } + } + else + { + qWarning() << "SondeHub error:" << QJsonDocument(errorObj); + } + } + } + //qDebug() << "SondeHub::handleReply: obj" << QJsonDocument(obj); + } + else + { + qDebug() << "SondeHub::handleReply:" << bytes; + } } else { diff --git a/sdrgui/gui/crightclickenabler.cpp b/sdrgui/gui/crightclickenabler.cpp index d7624c3832..3dc3c1415b 100644 --- a/sdrgui/gui/crightclickenabler.cpp +++ b/sdrgui/gui/crightclickenabler.cpp @@ -81,6 +81,17 @@ bool CRightClickEnabler::eventFilter(QObject *obj, QEvent *event) } } } + else if (event->type() == QEvent::KeyPress) + { + auto keyEvent = (QKeyEvent*) event; + + if ((keyEvent->key() == Qt::Key_Menu && keyEvent->modifiers() == 0) || (keyEvent->modifiers() & Qt::ShiftModifier && keyEvent->key() == Qt::Key_F10)) + { + emit rightClick(QCursor::pos()); + keyEvent->setAccepted(true); + return true; + } + } else if (event->type() == QEvent::ContextMenu) { // Filter ContextMenu events, so we don't get popup menus as well diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp index a3c5e9fe9e..0fad8ba788 100644 --- a/sdrgui/mainwindow.cpp +++ b/sdrgui/mainwindow.cpp @@ -61,6 +61,7 @@ #include "feature/featureset.h" #include "feature/feature.h" #include "feature/featuregui.h" +#include "feature/featurewebapiutils.h" #include "mainspectrum/mainspectrumgui.h" #include "commands/commandkeyreceiver.h" #include "gui/presetitem.h" @@ -275,6 +276,9 @@ MainWindow::MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parse InitFSM *fsm = new InitFSM(this, splash, !parser.getScratch()); connect(fsm, &InitFSM::finished, fsm, &InitFSM::deleteLater); connect(fsm, &InitFSM::finished, splash, &SDRangelSplash::deleteLater); + if (parser.getStart()) { + connect(fsm, &InitFSM::finished, this, &MainWindow::startAllAfterDelay); + } fsm->start(); qDebug() << "MainWindow::MainWindow: end"; @@ -3382,6 +3386,30 @@ void MainWindow::showAllChannels(int deviceSetIndex) } } +void MainWindow::startAllAfterDelay() +{ + // Wait a little bit before starting all devices and features, + // as some devices, such as FileSinks, can fail to start if run before initialised + // Is there a better way than this arbitrary time? + QTimer::singleShot(1000, this, &MainWindow::startAll); +} + +// Start all devices and features in all workspaces +void MainWindow::startAll() +{ + // Start all devices + for (const auto& workspace : m_workspaces) { + startAllDevices(workspace); + } + // Start all features + for (int featureSetIndex = 0; featureSetIndex < m_featureUIs.size(); featureSetIndex++) + { + for (int featureIndex = 0; featureIndex < m_featureUIs[featureSetIndex]->getNumberOfFeatures(); featureIndex++) { + FeatureWebAPIUtils::run(featureSetIndex, featureIndex); + } + } +} + // Start all devices in the workspace void MainWindow::startAllDevices(const Workspace *workspace) const { diff --git a/sdrgui/mainwindow.h b/sdrgui/mainwindow.h index 6b7baf77bf..d14228fad7 100644 --- a/sdrgui/mainwindow.h +++ b/sdrgui/mainwindow.h @@ -458,6 +458,8 @@ private slots: void featureMove(FeatureGUI *gui, int wsIndexDestnation); void deviceStateChanged(DeviceAPI *deviceAPI); void openFeaturePresetsDialog(QPoint p, Workspace *workspace); + void startAllAfterDelay(); + void startAll(); void startAllDevices(const Workspace *workspace) const; void stopAllDevices(const Workspace *workspace) const; void deviceMove(DeviceGUI *gui, int wsIndexDestnation); diff --git a/swagger/sdrangel/api/swagger/include/USRP.yaml b/swagger/sdrangel/api/swagger/include/USRP.yaml index e388f288fc..169094c7b5 100644 --- a/swagger/sdrangel/api/swagger/include/USRP.yaml +++ b/swagger/sdrangel/api/swagger/include/USRP.yaml @@ -30,6 +30,12 @@ USRPInputSettings: transverterDeltaFrequency: type: integer format: int64 + gpioDir: + type: integer + format: int8 + gpioPins: + type: integer + format: int8 useReverseAPI: description: Synchronize with reverse API (1 for yes, 0 for no) type: integer @@ -65,6 +71,12 @@ USRPOutputSettings: transverterDeltaFrequency: type: integer format: int64 + gpioDir: + type: integer + format: int8 + gpioPins: + type: integer + format: int8 useReverseAPI: description: Synchronize with reverse API (1 for yes, 0 for no) type: integer diff --git a/swagger/sdrangel/code/html2/index.html b/swagger/sdrangel/code/html2/index.html index cb1da788d6..ff653dee97 100644 --- a/swagger/sdrangel/code/html2/index.html +++ b/swagger/sdrangel/code/html2/index.html @@ -13451,6 +13451,18 @@ "properties" : { "sampleRate" : { "type" : "integer" + }, + "latitude" : { + "type" : "number", + "format" : "float" + }, + "longitude" : { + "type" : "number", + "format" : "float" + }, + "altitude" : { + "type" : "number", + "format" : "float" } }, "description" : "RemoteTCPInput" @@ -16824,6 +16836,14 @@ "type" : "integer", "format" : "int64" }, + "gpioDir" : { + "type" : "integer", + "format" : "int8" + }, + "gpioPins" : { + "type" : "integer", + "format" : "int8" + }, "useReverseAPI" : { "type" : "integer", "description" : "Synchronize with reverse API (1 for yes, 0 for no)" @@ -16893,6 +16913,14 @@ "type" : "integer", "format" : "int64" }, + "gpioDir" : { + "type" : "integer", + "format" : "int8" + }, + "gpioPins" : { + "type" : "integer", + "format" : "int8" + }, "useReverseAPI" : { "type" : "integer", "description" : "Synchronize with reverse API (1 for yes, 0 for no)" @@ -59441,7 +59469,7 @@

Status: 501 - Function not implemented

- Generated 2024-07-16T23:20:27.082+02:00 + Generated 2024-12-24T11:56:24.260+01:00
diff --git a/swagger/sdrangel/code/qt5/client/SWGRemoteTCPInputReport.cpp b/swagger/sdrangel/code/qt5/client/SWGRemoteTCPInputReport.cpp index eb50dd12a4..5fa22b16ac 100644 --- a/swagger/sdrangel/code/qt5/client/SWGRemoteTCPInputReport.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGRemoteTCPInputReport.cpp @@ -1,6 +1,6 @@ /** * SDRangel - * This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time --- + * This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time --- * * OpenAPI spec version: 7.0.0 * Contact: f4exb06@gmail.com @@ -30,6 +30,12 @@ SWGRemoteTCPInputReport::SWGRemoteTCPInputReport(QString* json) { SWGRemoteTCPInputReport::SWGRemoteTCPInputReport() { sample_rate = 0; m_sample_rate_isSet = false; + latitude = 0.0f; + m_latitude_isSet = false; + longitude = 0.0f; + m_longitude_isSet = false; + altitude = 0.0f; + m_altitude_isSet = false; } SWGRemoteTCPInputReport::~SWGRemoteTCPInputReport() { @@ -40,11 +46,20 @@ void SWGRemoteTCPInputReport::init() { sample_rate = 0; m_sample_rate_isSet = false; + latitude = 0.0f; + m_latitude_isSet = false; + longitude = 0.0f; + m_longitude_isSet = false; + altitude = 0.0f; + m_altitude_isSet = false; } void SWGRemoteTCPInputReport::cleanup() { + + + } SWGRemoteTCPInputReport* @@ -59,7 +74,13 @@ SWGRemoteTCPInputReport::fromJson(QString &json) { void SWGRemoteTCPInputReport::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&sample_rate, pJson["sampleRate"], "qint32", ""); - + + ::SWGSDRangel::setValue(&latitude, pJson["latitude"], "float", ""); + + ::SWGSDRangel::setValue(&longitude, pJson["longitude"], "float", ""); + + ::SWGSDRangel::setValue(&altitude, pJson["altitude"], "float", ""); + } QString @@ -79,9 +100,15 @@ SWGRemoteTCPInputReport::asJsonObject() { if(m_sample_rate_isSet){ obj->insert("sampleRate", QJsonValue(sample_rate)); } - obj->insert("latitude", QJsonValue(latitude)); - obj->insert("longitude", QJsonValue(longitude)); - obj->insert("altitude", QJsonValue(altitude)); + if(m_latitude_isSet){ + obj->insert("latitude", QJsonValue(latitude)); + } + if(m_longitude_isSet){ + obj->insert("longitude", QJsonValue(longitude)); + } + if(m_altitude_isSet){ + obj->insert("altitude", QJsonValue(altitude)); + } return obj; } @@ -96,6 +123,36 @@ SWGRemoteTCPInputReport::setSampleRate(qint32 sample_rate) { this->m_sample_rate_isSet = true; } +float +SWGRemoteTCPInputReport::getLatitude() { + return latitude; +} +void +SWGRemoteTCPInputReport::setLatitude(float latitude) { + this->latitude = latitude; + this->m_latitude_isSet = true; +} + +float +SWGRemoteTCPInputReport::getLongitude() { + return longitude; +} +void +SWGRemoteTCPInputReport::setLongitude(float longitude) { + this->longitude = longitude; + this->m_longitude_isSet = true; +} + +float +SWGRemoteTCPInputReport::getAltitude() { + return altitude; +} +void +SWGRemoteTCPInputReport::setAltitude(float altitude) { + this->altitude = altitude; + this->m_altitude_isSet = true; +} + bool SWGRemoteTCPInputReport::isSet(){ @@ -104,6 +161,15 @@ SWGRemoteTCPInputReport::isSet(){ if(m_sample_rate_isSet){ isObjectUpdated = true; break; } + if(m_latitude_isSet){ + isObjectUpdated = true; break; + } + if(m_longitude_isSet){ + isObjectUpdated = true; break; + } + if(m_altitude_isSet){ + isObjectUpdated = true; break; + } }while(false); return isObjectUpdated; } diff --git a/swagger/sdrangel/code/qt5/client/SWGRemoteTCPInputReport.h b/swagger/sdrangel/code/qt5/client/SWGRemoteTCPInputReport.h index 92ea400e01..661be25556 100644 --- a/swagger/sdrangel/code/qt5/client/SWGRemoteTCPInputReport.h +++ b/swagger/sdrangel/code/qt5/client/SWGRemoteTCPInputReport.h @@ -1,6 +1,6 @@ /** * SDRangel - * This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time --- + * This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time --- * * OpenAPI spec version: 7.0.0 * Contact: f4exb06@gmail.com @@ -43,21 +43,31 @@ class SWG_API SWGRemoteTCPInputReport: public SWGObject { qint32 getSampleRate(); void setSampleRate(qint32 sample_rate); - float getLatitude() { return latitude; } - float getLongitude() { return longitude; } - float getAltitude() { return altitude; } - void setLatitude(float latitude) { this->latitude = latitude; } - void setLongitude(float longitude) { this->longitude = longitude; } - void setAltitude(float altitude) { this->altitude = altitude; } + + float getLatitude(); + void setLatitude(float latitude); + + float getLongitude(); + void setLongitude(float longitude); + + float getAltitude(); + void setAltitude(float altitude); + virtual bool isSet() override; private: qint32 sample_rate; bool m_sample_rate_isSet; + float latitude; + bool m_latitude_isSet; + float longitude; + bool m_longitude_isSet; + float altitude; + bool m_altitude_isSet; }; diff --git a/swagger/sdrangel/code/qt5/client/SWGUSRPInputSettings.cpp b/swagger/sdrangel/code/qt5/client/SWGUSRPInputSettings.cpp index 80400dd762..9ed57c6362 100644 --- a/swagger/sdrangel/code/qt5/client/SWGUSRPInputSettings.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGUSRPInputSettings.cpp @@ -54,6 +54,10 @@ SWGUSRPInputSettings::SWGUSRPInputSettings() { m_transverter_mode_isSet = false; transverter_delta_frequency = 0L; m_transverter_delta_frequency_isSet = false; + gpio_dir = 0; + m_gpio_dir_isSet = false; + gpio_pins = 0; + m_gpio_pins_isSet = false; use_reverse_api = 0; m_use_reverse_api_isSet = false; reverse_api_address = nullptr; @@ -96,6 +100,10 @@ SWGUSRPInputSettings::init() { m_transverter_mode_isSet = false; transverter_delta_frequency = 0L; m_transverter_delta_frequency_isSet = false; + gpio_dir = 0; + m_gpio_dir_isSet = false; + gpio_pins = 0; + m_gpio_pins_isSet = false; use_reverse_api = 0; m_use_reverse_api_isSet = false; reverse_api_address = new QString(""); @@ -126,6 +134,8 @@ SWGUSRPInputSettings::cleanup() { + + if(reverse_api_address != nullptr) { delete reverse_api_address; } @@ -170,6 +180,10 @@ SWGUSRPInputSettings::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&transverter_delta_frequency, pJson["transverterDeltaFrequency"], "qint64", ""); + ::SWGSDRangel::setValue(&gpio_dir, pJson["gpioDir"], "qint32", ""); + + ::SWGSDRangel::setValue(&gpio_pins, pJson["gpioPins"], "qint32", ""); + ::SWGSDRangel::setValue(&use_reverse_api, pJson["useReverseAPI"], "qint32", ""); ::SWGSDRangel::setValue(&reverse_api_address, pJson["reverseAPIAddress"], "QString", "QString"); @@ -233,6 +247,12 @@ SWGUSRPInputSettings::asJsonObject() { if(m_transverter_delta_frequency_isSet){ obj->insert("transverterDeltaFrequency", QJsonValue(transverter_delta_frequency)); } + if(m_gpio_dir_isSet){ + obj->insert("gpioDir", QJsonValue(gpio_dir)); + } + if(m_gpio_pins_isSet){ + obj->insert("gpioPins", QJsonValue(gpio_pins)); + } if(m_use_reverse_api_isSet){ obj->insert("useReverseAPI", QJsonValue(use_reverse_api)); } @@ -379,6 +399,26 @@ SWGUSRPInputSettings::setTransverterDeltaFrequency(qint64 transverter_delta_freq this->m_transverter_delta_frequency_isSet = true; } +qint32 +SWGUSRPInputSettings::getGpioDir() { + return gpio_dir; +} +void +SWGUSRPInputSettings::setGpioDir(qint32 gpio_dir) { + this->gpio_dir = gpio_dir; + this->m_gpio_dir_isSet = true; +} + +qint32 +SWGUSRPInputSettings::getGpioPins() { + return gpio_pins; +} +void +SWGUSRPInputSettings::setGpioPins(qint32 gpio_pins) { + this->gpio_pins = gpio_pins; + this->m_gpio_pins_isSet = true; +} + qint32 SWGUSRPInputSettings::getUseReverseApi() { return use_reverse_api; @@ -463,6 +503,12 @@ SWGUSRPInputSettings::isSet(){ if(m_transverter_delta_frequency_isSet){ isObjectUpdated = true; break; } + if(m_gpio_dir_isSet){ + isObjectUpdated = true; break; + } + if(m_gpio_pins_isSet){ + isObjectUpdated = true; break; + } if(m_use_reverse_api_isSet){ isObjectUpdated = true; break; } diff --git a/swagger/sdrangel/code/qt5/client/SWGUSRPInputSettings.h b/swagger/sdrangel/code/qt5/client/SWGUSRPInputSettings.h index 7d6697cf11..3ddfc02eae 100644 --- a/swagger/sdrangel/code/qt5/client/SWGUSRPInputSettings.h +++ b/swagger/sdrangel/code/qt5/client/SWGUSRPInputSettings.h @@ -81,6 +81,12 @@ class SWG_API SWGUSRPInputSettings: public SWGObject { qint64 getTransverterDeltaFrequency(); void setTransverterDeltaFrequency(qint64 transverter_delta_frequency); + qint32 getGpioDir(); + void setGpioDir(qint32 gpio_dir); + + qint32 getGpioPins(); + void setGpioPins(qint32 gpio_pins); + qint32 getUseReverseApi(); void setUseReverseApi(qint32 use_reverse_api); @@ -136,6 +142,12 @@ class SWG_API SWGUSRPInputSettings: public SWGObject { qint64 transverter_delta_frequency; bool m_transverter_delta_frequency_isSet; + qint32 gpio_dir; + bool m_gpio_dir_isSet; + + qint32 gpio_pins; + bool m_gpio_pins_isSet; + qint32 use_reverse_api; bool m_use_reverse_api_isSet; diff --git a/swagger/sdrangel/code/qt5/client/SWGUSRPOutputSettings.cpp b/swagger/sdrangel/code/qt5/client/SWGUSRPOutputSettings.cpp index 57c00be9e6..dcbde1bb5f 100644 --- a/swagger/sdrangel/code/qt5/client/SWGUSRPOutputSettings.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGUSRPOutputSettings.cpp @@ -48,6 +48,10 @@ SWGUSRPOutputSettings::SWGUSRPOutputSettings() { m_transverter_mode_isSet = false; transverter_delta_frequency = 0L; m_transverter_delta_frequency_isSet = false; + gpio_dir = 0; + m_gpio_dir_isSet = false; + gpio_pins = 0; + m_gpio_pins_isSet = false; use_reverse_api = 0; m_use_reverse_api_isSet = false; reverse_api_address = nullptr; @@ -84,6 +88,10 @@ SWGUSRPOutputSettings::init() { m_transverter_mode_isSet = false; transverter_delta_frequency = 0L; m_transverter_delta_frequency_isSet = false; + gpio_dir = 0; + m_gpio_dir_isSet = false; + gpio_pins = 0; + m_gpio_pins_isSet = false; use_reverse_api = 0; m_use_reverse_api_isSet = false; reverse_api_address = new QString(""); @@ -111,6 +119,8 @@ SWGUSRPOutputSettings::cleanup() { + + if(reverse_api_address != nullptr) { delete reverse_api_address; } @@ -149,6 +159,10 @@ SWGUSRPOutputSettings::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&transverter_delta_frequency, pJson["transverterDeltaFrequency"], "qint64", ""); + ::SWGSDRangel::setValue(&gpio_dir, pJson["gpioDir"], "qint32", ""); + + ::SWGSDRangel::setValue(&gpio_pins, pJson["gpioPins"], "qint32", ""); + ::SWGSDRangel::setValue(&use_reverse_api, pJson["useReverseAPI"], "qint32", ""); ::SWGSDRangel::setValue(&reverse_api_address, pJson["reverseAPIAddress"], "QString", "QString"); @@ -203,6 +217,12 @@ SWGUSRPOutputSettings::asJsonObject() { if(m_transverter_delta_frequency_isSet){ obj->insert("transverterDeltaFrequency", QJsonValue(transverter_delta_frequency)); } + if(m_gpio_dir_isSet){ + obj->insert("gpioDir", QJsonValue(gpio_dir)); + } + if(m_gpio_pins_isSet){ + obj->insert("gpioPins", QJsonValue(gpio_pins)); + } if(m_use_reverse_api_isSet){ obj->insert("useReverseAPI", QJsonValue(use_reverse_api)); } @@ -319,6 +339,26 @@ SWGUSRPOutputSettings::setTransverterDeltaFrequency(qint64 transverter_delta_fre this->m_transverter_delta_frequency_isSet = true; } +qint32 +SWGUSRPOutputSettings::getGpioDir() { + return gpio_dir; +} +void +SWGUSRPOutputSettings::setGpioDir(qint32 gpio_dir) { + this->gpio_dir = gpio_dir; + this->m_gpio_dir_isSet = true; +} + +qint32 +SWGUSRPOutputSettings::getGpioPins() { + return gpio_pins; +} +void +SWGUSRPOutputSettings::setGpioPins(qint32 gpio_pins) { + this->gpio_pins = gpio_pins; + this->m_gpio_pins_isSet = true; +} + qint32 SWGUSRPOutputSettings::getUseReverseApi() { return use_reverse_api; @@ -394,6 +434,12 @@ SWGUSRPOutputSettings::isSet(){ if(m_transverter_delta_frequency_isSet){ isObjectUpdated = true; break; } + if(m_gpio_dir_isSet){ + isObjectUpdated = true; break; + } + if(m_gpio_pins_isSet){ + isObjectUpdated = true; break; + } if(m_use_reverse_api_isSet){ isObjectUpdated = true; break; } diff --git a/swagger/sdrangel/code/qt5/client/SWGUSRPOutputSettings.h b/swagger/sdrangel/code/qt5/client/SWGUSRPOutputSettings.h index ea59c25ebb..13157d962e 100644 --- a/swagger/sdrangel/code/qt5/client/SWGUSRPOutputSettings.h +++ b/swagger/sdrangel/code/qt5/client/SWGUSRPOutputSettings.h @@ -72,6 +72,12 @@ class SWG_API SWGUSRPOutputSettings: public SWGObject { qint64 getTransverterDeltaFrequency(); void setTransverterDeltaFrequency(qint64 transverter_delta_frequency); + qint32 getGpioDir(); + void setGpioDir(qint32 gpio_dir); + + qint32 getGpioPins(); + void setGpioPins(qint32 gpio_pins); + qint32 getUseReverseApi(); void setUseReverseApi(qint32 use_reverse_api); @@ -118,6 +124,12 @@ class SWG_API SWGUSRPOutputSettings: public SWGObject { qint64 transverter_delta_frequency; bool m_transverter_delta_frequency_isSet; + qint32 gpio_dir; + bool m_gpio_dir_isSet; + + qint32 gpio_pins; + bool m_gpio_pins_isSet; + qint32 use_reverse_api; bool m_use_reverse_api_isSet;