Initial commit

This commit is contained in:
2026-01-20 01:39:06 +01:00
commit 6f308ad590
34 changed files with 2068 additions and 0 deletions

103
src/time_manager.cpp Normal file
View File

@@ -0,0 +1,103 @@
#include "time_manager.h"
#include "compressor.h"
#include "config.h"
#include <time.h>
static bool g_time_synced = false;
static bool g_tz_set = false;
void time_receiver_init(const char *ntp_server_1, const char *ntp_server_2) {
const char *server1 = (ntp_server_1 && ntp_server_1[0] != '\0') ? ntp_server_1 : "pool.ntp.org";
const char *server2 = (ntp_server_2 && ntp_server_2[0] != '\0') ? ntp_server_2 : "time.nist.gov";
configTime(0, 0, server1, server2);
if (!g_tz_set) {
setenv("TZ", "CET-1CEST,M3.5.0/2,M10.5.0/3", 1);
tzset();
g_tz_set = true;
}
}
uint32_t time_get_utc() {
time_t now = time(nullptr);
if (now < 1672531200) {
return 0;
}
return static_cast<uint32_t>(now);
}
bool time_is_synced() {
return g_time_synced || time_get_utc() > 0;
}
void time_set_utc(uint32_t epoch) {
if (!g_tz_set) {
setenv("TZ", "CET-1CEST,M3.5.0/2,M10.5.0/3", 1);
tzset();
g_tz_set = true;
}
struct timeval tv;
tv.tv_sec = epoch;
tv.tv_usec = 0;
settimeofday(&tv, nullptr);
g_time_synced = true;
}
void time_send_timesync(uint16_t device_id_short) {
uint32_t epoch = time_get_utc();
if (epoch == 0) {
return;
}
char payload_str[32];
snprintf(payload_str, sizeof(payload_str), "T:%lu", static_cast<unsigned long>(epoch));
uint8_t compressed[LORA_MAX_PAYLOAD];
size_t compressed_len = 0;
if (!compressBuffer(reinterpret_cast<const uint8_t *>(payload_str), strlen(payload_str), compressed, sizeof(compressed), compressed_len)) {
return;
}
LoraPacket pkt = {};
pkt.protocol_version = PROTOCOL_VERSION;
pkt.role = DeviceRole::Receiver;
pkt.device_id_short = device_id_short;
pkt.payload_type = PayloadType::TimeSync;
pkt.payload_len = compressed_len;
memcpy(pkt.payload, compressed, compressed_len);
lora_send(pkt);
}
bool time_handle_timesync_payload(const uint8_t *payload, size_t len) {
uint8_t decompressed[64];
size_t decompressed_len = 0;
if (!decompressBuffer(payload, len, decompressed, sizeof(decompressed), decompressed_len)) {
return false;
}
if (decompressed_len >= sizeof(decompressed)) {
return false;
}
decompressed[decompressed_len] = '\0';
if (decompressed_len < 3 || decompressed[0] != 'T' || decompressed[1] != ':') {
return false;
}
uint32_t epoch = static_cast<uint32_t>(strtoul(reinterpret_cast<const char *>(decompressed + 2), nullptr, 10));
if (epoch == 0) {
return false;
}
time_set_utc(epoch);
return true;
}
void time_get_local_hhmm(char *out, size_t out_len) {
if (!time_is_synced()) {
snprintf(out, out_len, "--:--");
return;
}
time_t now = time(nullptr);
struct tm timeinfo;
localtime_r(&now, &timeinfo);
snprintf(out, out_len, "%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min);
}