Support RSSI_MAX method

This commit is contained in:
Sassa NF
2025-01-01 23:03:34 +00:00
parent 5af6a829f3
commit 500599ec7a
6 changed files with 160 additions and 24 deletions

View File

@@ -262,6 +262,7 @@ bool ReadlineComms::send(Message &m)
Serial.println(name + ": the message is: " + p);
break;
case MessageType::SCAN_RESULT:
case MessageType::SCAN_MAX_RESULT:
p = _scan_result_str(m.payload.dump);
break;
case MessageType::CONFIG_TASK:
@@ -420,7 +421,7 @@ String _wrap_str(String v)
Message::~Message()
{
if (type == SCAN_RESULT)
if (type == SCAN_RESULT || type == SCAN_MAX_RESULT)
{
if (payload.dump.sz > 0)
{

View File

@@ -13,11 +13,18 @@
#define SERIAL0 Serial0
#endif
#ifndef SCAN_MAX_RESULT_KHZ_SCALE
// kHz scale: round frequency, so it fits into 2 bytes
// 2500000 / 40 = 62500, scale 40 fits 2.5GHz into two bytes
#define SCAN_MAX_RESULT_KHZ_SCALE 40
#endif
enum MessageType
{
WRAP = 0,
SCAN,
SCAN_RESULT,
SCAN_MAX_RESULT,
CONFIG_TASK,
_MAX_MESSAGE_TYPE = CONFIG_TASK
};

View File

@@ -62,9 +62,9 @@ uint8_t *_serialize_scan_result(Message &m, size_t &p, uint8_t *msg)
// first cut: dump the RSSI as-is
// optimize the message size later
p = _write(msg, max_msg, p, (uint8_t *)&dump_sz, 2);
p = _write(msg, max_msg, p, (uint8_t *)&m.payload.dump.freqs_khz[0], 4);
p = _write(msg, max_msg, p, (uint8_t *)&m.payload.dump.freqs_khz[dump_sz - 1], 4);
p = _write(msg, max_msg, p, (uint8_t *)&dump_sz, 2);
size_t rem = max_msg - p;
if (rem > dump_sz)
@@ -104,6 +104,44 @@ uint8_t *_serialize_scan_result(Message &m, size_t &p, uint8_t *msg)
return msg;
}
uint8_t *_serialize_scan_max_result(Message &m, size_t &p, uint8_t *msg)
{
if (m.type != SCAN_MAX_RESULT)
{
return NULL;
}
size_t dump_sz = m.payload.dump.sz;
size_t max_msg = p;
p = _write(msg, max_msg, 0, (uint8_t)m.type);
p = _write(msg, max_msg, p, (uint8_t *)&dump_sz, 2);
int16_t b = SCAN_MAX_RESULT_KHZ_SCALE; // scale to fit khz into 2 bytes
p = _write(msg, max_msg, p, (uint8_t)b);
for (int i = 0; i < dump_sz; i++)
{
b = m.payload.dump.freqs_khz[i] / SCAN_MAX_RESULT_KHZ_SCALE;
p = _write(msg, max_msg, p, (uint8_t *)&b, 2);
b = m.payload.dump.rssis[i];
if (b >= 0)
{
b = 255;
}
else
{
b += 255;
if (b < 0)
{
b = 0;
}
}
p = _write(msg, max_msg, p, (uint8_t)b);
}
return msg;
}
uint8_t *_serialize_config_task(Message &m, size_t &p, uint8_t *msg)
{
if (m.type != CONFIG_TASK)
@@ -152,6 +190,10 @@ int16_t RadioComms::send(Message &m)
{
msg = _serialize_scan_result(m, p, msg_buf);
}
else if (m.type == MessageType::SCAN_MAX_RESULT)
{
msg = _serialize_scan_max_result(m, p, msg_buf);
}
else if (m.type == MessageType::CONFIG_TASK)
{
msg = _serialize_config_task(m, p, msg_buf);
@@ -195,9 +237,9 @@ Message *_deserialize_scan_result(size_t len, size_t &p, uint8_t *packet)
uint32_t s, e;
size_t dump_sz = 0;
p = _read(packet, len, p, (uint8_t *)&dump_sz, 2);
p = _read(packet, len, p, (uint8_t *)&s, 4);
p = _read(packet, len, p, (uint8_t *)&e, 4);
p = _read(packet, len, p, (uint8_t *)&dump_sz, 2);
size_t rem = len - p;
message->payload.dump.sz = dump_sz;
@@ -231,6 +273,36 @@ Message *_deserialize_scan_result(size_t len, size_t &p, uint8_t *packet)
return message;
}
Message *_deserialize_scan_max_result(size_t len, size_t &p, uint8_t *packet)
{
Message *message = new Message();
message->type = SCAN_MAX_RESULT;
uint32_t b = 0;
size_t dump_sz = 0;
p = _read(packet, len, p, (uint8_t *)&dump_sz, 2);
uint32_t *freqs = new uint32_t[dump_sz];
int16_t *rssis = new int16_t[dump_sz];
message->payload.dump.sz = dump_sz;
message->payload.dump.freqs_khz = freqs;
message->payload.dump.rssis = rssis;
uint32_t scale = 0;
p = _read(packet, len, p, (uint8_t *)&scale);
for (int i = 0; i < dump_sz; i++)
{
p = _read(packet, len, p, (uint8_t *)&b, 2);
freqs[i] = scale * b;
b = 0;
p = _read(packet, len, p, (uint8_t *)&b);
rssis[i] = ((int16_t)b) - 255;
}
return message;
}
Message *_deserialize_config_task(size_t len, size_t &p, uint8_t *packet)
{
Message *message = new Message();
@@ -346,6 +418,10 @@ Message *RadioComms::receive(uint16_t timeout_ms)
{
message = _deserialize_scan_result(len, p, packet);
}
else if (b == SCAN_MAX_RESULT)
{
message = _deserialize_scan_max_result(len, p, packet);
}
else if (b == CONFIG_TASK)
{
message = _deserialize_config_task(len, p, packet);

View File

@@ -20,6 +20,22 @@ struct ScanRange
uint64_t step_khz;
};
struct ScanPage
{
uint64_t start_mhz;
uint64_t end_mhz;
size_t page_sz;
ScanRange *scan_ranges;
~ScanPage()
{
if (page_sz > 0)
{
delete[] scan_ranges;
}
}
};
struct LoRaConfig
{
float freq;

View File

@@ -34,22 +34,6 @@ constexpr float LO_RSSI_THRESHOLD = HI_RSSI_THRESHOLD - 66;
#define SAMPLES_RSSI 20
#endif
struct ScanPage
{
uint64_t start_mhz;
uint64_t end_mhz;
size_t page_sz;
ScanRange *scan_ranges;
~ScanPage()
{
if (page_sz > 0)
{
delete[] scan_ranges;
}
}
};
struct Scan
{
uint64_t epoch;

View File

@@ -909,7 +909,7 @@ void configureDetection()
CONF_FREQ_BEGIN = config.scan_ranges[0].start_khz / 1000;
CONF_FREQ_END = config.scan_ranges[0].end_khz / 1000;
for (int i = 0; i < config.scan_ranges_sz; i++)
for (int i = 1; i < config.scan_ranges_sz; i++)
{
CONF_FREQ_BEGIN = min(CONF_FREQ_BEGIN, config.scan_ranges[i].start_khz / 1000);
CONF_FREQ_END = max(CONF_FREQ_END, config.scan_ranges[i].end_khz / 1000);
@@ -1419,6 +1419,7 @@ void routeMessage(RoutedMessage &m)
}
if (m.message->type == MessageType::SCAN_RESULT ||
m.message->type == MessageType::SCAN_MAX_RESULT ||
m.message->type == MessageType::CONFIG_TASK &&
(m.message->payload.config.task_type == ConfigTaskType::GETSET_SUCCESS ||
m.message->payload.config.task_type == ConfigTaskType::SET_FAIL))
@@ -1477,6 +1478,12 @@ void sendMessage(RoutedMessage &m)
success = config.updateConfig(*msg->payload.config.key,
*msg->payload.config.value);
delete msg->payload.config.value;
if (success &&
msg->payload.config.key->equalsIgnoreCase("detection_strategy"))
{
configureDetection(); // redo the pages and scan ranges
}
}
if (success)
@@ -1771,7 +1778,8 @@ void doScan()
float (*g)(void *);
samples = CONF_SAMPLES;
if (config.detection_strategy.equalsIgnoreCase("RSSI"))
if (config.detection_strategy.equalsIgnoreCase("RSSI") ||
config.detection_strategy.equalsIgnoreCase("RSSI_MAX"))
g = &getRSSI;
else if (config.detection_strategy.equalsIgnoreCase("CAD"))
{
@@ -2117,8 +2125,52 @@ void reportScan()
Message m;
m.type = SCAN_RESULT;
m.payload.dump = frequency_scan_result.dump;
loraSendMessage(m);
m.payload.dump.sz = 0;
m.payload.dump.sz = 0; // dump is shared, so should not delete underlying arrays
if (config.detection_strategy.equalsIgnoreCase("RSSI"))
{
size_t sz = frequency_scan_result.dump.sz;
m.payload.dump.sz = sz;
m.payload.dump.freqs_khz = new uint32_t[sz];
m.payload.dump.rssis = new int16_t[sz];
memcpy(m.payload.dump.freqs_khz, frequency_scan_result.dump.freqs_khz,
sizeof(uint32_t) * sz);
memcpy(m.payload.dump.rssis, frequency_scan_result.dump.rssis,
sizeof(int16_t) * sz);
}
else if (config.detection_strategy.equalsIgnoreCase("RSSI_MAX"))
{
m.type = SCAN_MAX_RESULT;
size_t sz = config.scan_ranges_sz;
m.payload.dump.sz = sz;
m.payload.dump.freqs_khz = new uint32_t[sz];
m.payload.dump.rssis = new int16_t[sz];
for (int i = 0; i < sz; i++)
{
int16_t rssi = -999;
for (int j = 0; j < frequency_scan_result.dump.sz; j++)
{
uint32_t f = frequency_scan_result.dump.freqs_khz[j];
if (config.scan_ranges[i].start_khz > f ||
config.scan_ranges[i].end_khz < f)
continue;
rssi = max(rssi, frequency_scan_result.dump.rssis[j]);
}
m.payload.dump.freqs_khz[i] =
(config.scan_ranges[i].start_khz + config.scan_ranges[i].end_khz) / 2;
m.payload.dump.rssis[i] = rssi;
}
}
else
{
return;
}
loraSendMessage(m);
}