Skip to content

Commit b40a73a

Browse files
committed
Added satellites support.
1 parent 4d12149 commit b40a73a

14 files changed

+184
-10
lines changed

config.example.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
{
2+
"api_key": "",
23
"devices": [],
34
"ignored_frequencies": [],
45
"output": {
56
"color_log_enabled": true,
67
"console_log_level": "info",
78
"file_log_level": "debug"
89
},
10+
"position": {
11+
"altitude": 0,
12+
"latitude": "0.000000",
13+
"longitude": "0.000000"
14+
},
915
"recording": {
1016
"max_noise_time_ms": 2000,
1117
"min_sample_rate": 32000,
1218
"min_time_ms": 2000,
1319
"step": 2500
1420
},
15-
"version": 1,
21+
"version": 2,
1622
"workers": 0
1723
}

sources/config.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#include <radio/sdr_device_reader.h>
66
#include <utils/utils.h>
77

8+
#include <regex>
9+
810
constexpr auto LABEL = "config";
911

1012
spdlog::level::level_enum parseLogLevel(const std::string& level) {
@@ -68,7 +70,11 @@ Config::Config(const nlohmann::json& json, const ArgConfig& argConfig)
6870
m_recordingMinTime(std::chrono::milliseconds(readKey<int>(json, {"recording", "min_time_ms"}))),
6971
m_recordingTimeout(std::chrono::milliseconds(readKey<int>(json, {"recording", "max_noise_time_ms"}))),
7072
m_recordingTuningStep(readKey<Frequency>(json, {"recording", "step"})),
71-
m_workers(readKey<int>(json, {"workers"})) {}
73+
m_workers(readKey<int>(json, {"workers"})),
74+
m_apiKey(readKey<std::string>(json, {"api_key"})),
75+
m_latitude(readKey<std::string>(json, {"position", "latitude"})),
76+
m_longitude(readKey<std::string>(json, {"position", "longitude"})),
77+
m_altitude(readKey<int>(json, {"position", "altitude"})) {}
7278

7379
Config Config::loadFromFile(const std::string& path, const ArgConfig& argConfig) {
7480
constexpr auto BUFFER_SIZE = 1024 * 1024;
@@ -107,6 +113,21 @@ void Config::saveToFile(const std::string& path, const nlohmann::json& json) {
107113
}
108114
}
109115

116+
nlohmann::json Config::hideSensitiveData(const nlohmann::json& json) {
117+
nlohmann::json config(json);
118+
try {
119+
if (!config["api_key"].empty()) {
120+
config["api_key"] = "******";
121+
}
122+
std::regex regex(R"(^(\d+)\.\d+)");
123+
config["position"]["latitude"] = std::regex_replace(config["position"]["latitude"].get<std::string>(), regex, "$1.********");
124+
config["position"]["longitude"] = std::regex_replace(config["position"]["longitude"].get<std::string>(), regex, "$1.********");
125+
} catch (const std::exception& exception) {
126+
Logger::warn(LABEL, "hide sensitive data exception: {}", colored(RED, "{}", exception.what()));
127+
}
128+
return config;
129+
}
130+
110131
nlohmann::json Config::json() const { return m_json; }
111132
std::string Config::mqtt() const { return fmt::format("{}@{}", m_argConfig.mqttUser, m_argConfig.mqttUrl); };
112133

@@ -131,3 +152,8 @@ Frequency Config::recordingTuningStep() const { return m_recordingTuningStep; }
131152
std::string Config::mqttUrl() const { return m_argConfig.mqttUrl; }
132153
std::string Config::mqttUsername() const { return m_argConfig.mqttUser; }
133154
std::string Config::mqttPassword() const { return m_argConfig.mqttPassword; }
155+
156+
std::string Config::apiKey() const { return m_apiKey; }
157+
std::string Config::latitude() const { return m_latitude; }
158+
std::string Config::longitude() const { return m_longitude; }
159+
int Config::altitude() const { return m_altitude; }

sources/config.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class Config {
4949
public:
5050
static Config loadFromFile(const std::string& path, const ArgConfig& argConfig);
5151
static void saveToFile(const std::string& path, const nlohmann::json& json);
52+
static nlohmann::json hideSensitiveData(const nlohmann::json& json);
5253
nlohmann::json json() const;
5354
std::string mqtt() const;
5455

@@ -70,6 +71,11 @@ class Config {
7071
std::string mqttUsername() const;
7172
std::string mqttPassword() const;
7273

74+
std::string apiKey() const;
75+
std::string latitude() const;
76+
std::string longitude() const;
77+
int altitude() const;
78+
7379
private:
7480
Config(const nlohmann::json& json, const ArgConfig& argConfig);
7581

@@ -89,4 +95,9 @@ class Config {
8995
const std::chrono::milliseconds m_recordingTimeout;
9096
const Frequency m_recordingTuningStep;
9197
const int m_workers;
98+
99+
const std::string m_apiKey;
100+
const std::string m_latitude;
101+
const std::string m_longitude;
102+
const int m_altitude;
92103
};

sources/config_migrator.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,14 @@ void ConfigMigrator::applyVersion(nlohmann::json& config, const int version) {
3636
config["version"] = version;
3737
}
3838

39-
void ConfigMigrator::applyVersion2(nlohmann::json& config) { std::ignore = config; }
39+
void ConfigMigrator::applyVersion2(nlohmann::json& config) {
40+
applyVersion(config, 2);
41+
config["api_key"] = "";
42+
config["position"]["latitude"] = "0.000000";
43+
config["position"]["longitude"] = "0.000000";
44+
config["position"]["altitude"] = 0;
45+
46+
for (auto& device : config.at("devices")) {
47+
device["satellites"] = nlohmann::json::array();
48+
}
49+
}

sources/main.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ int main(int argc, char** argv) {
4747
bool reload = false;
4848
const Config config = Config::loadFromFile(argConfig.configFile, argConfig);
4949
Logger::configure(config.consoleLogLevel(), config.fileLogLevel(), argConfig.logFileName, argConfig.logFileSize, argConfig.logFileCount, config.isColorLogEnabled());
50-
Logger::info(LABEL, "config: {}", colored(GREEN, "{}", config.json().dump()));
50+
Logger::info(LABEL, "config: {}", colored(GREEN, "{}", Config::hideSensitiveData(config.json()).dump()));
5151
Logger::info(LABEL, "mqtt: {}", colored(GREEN, "{}", config.mqtt()));
5252

5353
Mqtt mqtt(config);
5454
RemoteController remoteController(config, mqtt);
5555
remoteController.reloadConfigCallback([&reload, &argConfig, &remoteController](const nlohmann::json& json) {
56-
Logger::info(LABEL, "reload config: {}", colored(GREEN, "{}", json.dump()));
56+
Logger::info(LABEL, "reload config: {}", colored(GREEN, "{}", Config::hideSensitiveData(json).dump()));
5757
Config::saveToFile(argConfig.configFile, json);
5858
remoteController.reloadConfigStatus(true);
5959
reload = true;
@@ -63,10 +63,8 @@ int main(int argc, char** argv) {
6363
try {
6464
if (!device.m_enabled) {
6565
Logger::info(LABEL, "device disabled, skipping: {}", colored(GREEN, "{}", device.getName()));
66-
} else if (device.m_ranges.empty()) {
67-
Logger::info(LABEL, "empty ranges to scan, skipping: {}", colored(GREEN, "{}", device.getName()));
6866
} else {
69-
scanners.push_back(std::make_unique<Scanner>(config, device, mqtt, config.recordersCount()));
67+
scanners.push_back(std::make_unique<Scanner>(config, device, mqtt, remoteController, config.recordersCount()));
7068
}
7169
} catch (const std::exception& exception) {
7270
Logger::error(LABEL, "can not open device: {}, exception: {}", colored(RED, "{}", device.getName()), exception.what());

sources/network/remote_controller.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
constexpr auto LIST = "list";
88
constexpr auto STATUS = "status";
99
constexpr auto CONFIG = "config";
10+
constexpr auto SATELLITES = "satellites";
1011
constexpr auto SUCCESS = "success";
1112
constexpr auto FAILED = "failed";
1213
constexpr auto LABEL = "remote";
@@ -22,6 +23,12 @@ void RemoteController::reloadConfigCallback(const Mqtt::JsonCallback& callback)
2223

2324
void RemoteController::reloadConfigStatus(const bool& success) { m_mqtt.publish(fmt::format("sdr/{}/{}/{}", CONFIG, m_config.getId(), success ? SUCCESS : FAILED), "", 2); }
2425

26+
void RemoteController::satellitesQuery(const std::string& device, const std::string& query) { m_mqtt.publish(fmt::format("sdr/{}/{}/{}/get", SATELLITES, m_config.getId(), device), query, 2); }
27+
28+
void RemoteController::satellitesCallback(const std::string& device, const Mqtt::JsonCallback& callback) {
29+
m_mqtt.setJsonMessageCallback(fmt::format("sdr/{}/{}/{}/set", SATELLITES, m_config.getId(), device), callback);
30+
}
31+
2532
void RemoteController::listCallback(const std::string&) {
2633
Logger::info(LABEL, "received list");
2734
m_mqtt.publish(fmt::format("sdr/{}/{}", STATUS, m_config.getId()), m_config.json().dump(), 2);

sources/network/remote_controller.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ class RemoteController {
1313
void reloadConfigCallback(const Mqtt::JsonCallback& callback);
1414
void reloadConfigStatus(const bool& success);
1515

16+
void satellitesQuery(const std::string& device, const std::string& query);
17+
void satellitesCallback(const std::string& device, const Mqtt::JsonCallback& callback);
18+
1619
private:
1720
void listCallback(const std::string& data);
1821

sources/radio/help_structures.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include "help_structures.h"
2+
3+
Satellite::Satellite(const int& id, const std::string& name, const Frequency& frequency, const Frequency& bandwidth, const std::string& modulation)
4+
: m_id(id), m_name(name), m_frequency(frequency), m_bandwidth(bandwidth), m_modulation(modulation) {}
5+
6+
nlohmann::json Satellite::toJson() const {
7+
nlohmann::json json;
8+
json["id"] = m_id;
9+
json["name"] = m_name;
10+
json["frequency"] = m_frequency;
11+
json["bandwidth"] = m_bandwidth;
12+
json["modulation"] = m_modulation;
13+
return json;
14+
}

sources/radio/help_structures.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <complex>
77
#include <cstdint>
88
#include <map>
9+
#include <nlohmann/json.hpp>
910
#include <string>
1011
#include <utility>
1112
#include <vector>
@@ -16,6 +17,17 @@ using FrequencyFlush = std::pair<Frequency, bool>;
1617
using TransmissionNotification = Notification<std::vector<FrequencyFlush>>;
1718
using SimpleComplex = std::complex<int8_t>;
1819

20+
struct Satellite {
21+
Satellite(const int& id, const std::string& name, const Frequency& frequency, const Frequency& bandwidth, const std::string& modulation);
22+
nlohmann::json toJson() const;
23+
24+
const int m_id;
25+
const std::string m_name;
26+
const Frequency m_frequency;
27+
const Frequency m_bandwidth;
28+
const std::string m_modulation;
29+
};
30+
1931
struct Device {
2032
bool m_enabled{};
2133
std::vector<std::pair<std::string, float>> m_gains{};
@@ -25,6 +37,7 @@ struct Device {
2537
std::vector<FrequencyRange> m_ranges{};
2638
float m_startLevel{};
2739
float m_stopLevel{};
40+
std::vector<Satellite> m_satellites{};
2841

2942
std::string getName() const { return m_driver + "_" + m_serial; }
3043
};

sources/radio/scheduler.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include "scheduler.h"
2+
3+
#include <radio/help_structures.h>
4+
5+
#include <chrono>
6+
#include <functional>
7+
8+
constexpr auto LABEL = "scheduler";
9+
constexpr auto LOOP_TIMEOUT = std::chrono::milliseconds(100);
10+
constexpr auto UPDATE_INTERVAL = std::chrono::minutes(60);
11+
12+
using namespace std::placeholders;
13+
14+
Scheduler::Scheduler(const Config& config, const Device& device, RemoteController& remoteController)
15+
: m_config(config), m_device(device), m_remoteController(remoteController), m_lastUpdateTime(0), m_isRunning(true), m_thread([this]() { worker(); }) {}
16+
17+
Scheduler::~Scheduler() {
18+
m_isRunning = false;
19+
m_thread.join();
20+
}
21+
22+
void Scheduler::worker() {
23+
m_remoteController.satellitesCallback(m_device.getName(), std::bind(&Scheduler::satellitesCallback, this, _1));
24+
while (m_isRunning) {
25+
const auto now = getTime();
26+
if (m_lastUpdateTime + UPDATE_INTERVAL <= now) {
27+
satellitesQuery();
28+
m_lastUpdateTime = now;
29+
}
30+
std::this_thread::sleep_for(LOOP_TIMEOUT);
31+
}
32+
}
33+
34+
void Scheduler::satellitesQuery() {
35+
Logger::info(LABEL, "send satellites query");
36+
nlohmann::json satellites = nlohmann::json::array();
37+
for (const auto& satellite : m_device.m_satellites) {
38+
satellites.push_back(satellite.toJson());
39+
}
40+
41+
nlohmann::json json;
42+
json["satellites"] = satellites;
43+
json["latitude"] = m_config.latitude();
44+
json["longitude"] = m_config.longitude();
45+
json["altitude"] = m_config.altitude();
46+
json["api_key"] = m_config.apiKey();
47+
m_remoteController.satellitesQuery(m_device.getName(), json.dump());
48+
}
49+
50+
void Scheduler::satellitesCallback(const nlohmann::json& json) { Logger::info(LABEL, "received satellites: {}", colored(GREEN, "{}", json.dump())); }

0 commit comments

Comments
 (0)