Adding simple FSK Rx Processor. Can be used with New Apps. (#2716)

* Work to allow for unique beacon parsing functions.

* Fixing pull.

* Changes.

* Formatting.

* Fix Copyright

* Update firmware/application/apps/ble_rx_app.cpp

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update firmware/baseband/proc_btlerx.cpp

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* PR suggestions.

* Fix String.

* FSK Rx Improvements. Works for my custom protocol.

* Fix buffer size.

* Refactor

* Formatting.

* Formatting.

* Fixing compiling, and BLE Rx UI/Performance.

* More improvements.

* Fixing stuck state.

* More stuck parsing fix.

* Combining PR changes.

* Improvements from previous PR.

* Fix dbM calculation relative to device RSSI.

* Formatting.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: TJ <tj.baginski@cognosos.com>
This commit is contained in:
Netro 2025-06-28 19:02:12 -04:00 committed by GitHub
parent 4e276cdc71
commit f90d3fabce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 521 additions and 448 deletions

View file

@ -57,95 +57,6 @@ std::string pad_string_with_spaces(int snakes) {
return paddedStr;
}
struct GainEntry {
uint8_t lna;
uint8_t vga;
uint8_t gain;
};
// Only LNA with VGA 0-4 is tested to be accurate. Max zeroized gain tested to be 16dBm.
// Beyond that it is hard to tell distance to transmitting device.
// Test was conducted within a few inches of the device.
// Device was transmitting at 0dBm.
constexpr GainEntry gain_table[] =
{
{40, 0, 19},
{32, 0, 18},
{24, 0, 15},
{16, 0, 8},
{8, 0, 2},
{0, 0, 0},
{40, 2, 20},
{32, 2, 22},
{24, 2, 14},
{16, 2, 8},
{8, 2, 2},
{0, 2, 0},
{40, 4, 21},
{32, 4, 22},
{24, 4, 15},
{16, 4, 10},
{8, 4, 3},
{0, 4, 0},
{40, 6, 26},
{32, 6, 22},
{24, 6, 15},
{16, 6, 10},
{8, 6, 4},
{0, 6, 0},
{40, 8, 26},
{32, 8, 26},
{24, 8, 18},
{16, 8, 12},
{8, 8, 6},
{0, 8, 1},
{40, 10, 26},
{32, 10, 26},
{24, 10, 20},
{16, 10, 15},
{8, 10, 8},
{0, 10, 3},
{40, 12, 26},
{32, 12, 26},
{24, 12, 23},
{16, 12, 17},
{8, 12, 10},
{0, 12, 4},
{40, 14, 26},
{32, 14, 26},
{24, 14, 25},
{16, 14, 19},
{8, 14, 12},
{0, 14, 6},
{40, 16, 26},
{32, 16, 26},
{24, 16, 26},
{16, 16, 20},
{8, 16, 13},
{0, 16, 7},
{40, 18, 26},
{32, 18, 26},
{24, 18, 26},
{16, 18, 21},
{8, 18, 14},
{0, 18, 8},
{40, 20, 26},
{32, 20, 26},
{24, 20, 26},
{16, 20, 23},
{8, 20, 16},
{0, 20, 10},
};
uint8_t get_total_gain(uint8_t lna, uint8_t vga) {
for (const auto& entry : gain_table) {
if (entry.lna == lna && entry.vga == vga)
return entry.gain;
}
return 0;
}
uint64_t copy_mac_address_to_uint64(const uint8_t* macAddress) {
uint64_t result = 0;
@ -275,10 +186,10 @@ void RecentEntriesTable<BleRecentEntries>::draw(
if (!entry.nameString.empty() && entry.include_name) {
line = entry.nameString;
if (line.length() < 10) {
line += pad_string_with_spaces(10 - line.length());
if (line.length() < 17) {
line += pad_string_with_spaces(17 - line.length());
} else {
line = truncate(line, 10);
line = truncate(line, 17);
}
} else {
line = to_string_mac_address(entry.packetData.macAddress, 6, false);
@ -289,12 +200,12 @@ void RecentEntriesTable<BleRecentEntries>::draw(
if (!entry.informationString.empty()) {
hitsStr = entry.informationString;
} else {
hitsStr = "Hits: " + to_string_dec_int(entry.numHits);
hitsStr = to_string_dec_int(entry.numHits);
}
// Pushing single digit values down right justified.
int hitsDigits = hitsStr.length();
uint8_t hits_spacing = 14 - hitsDigits;
uint8_t hits_spacing = 8 - hitsDigits;
// Pushing single digit values down right justified.
std::string dbStr = to_string_dec_int(entry.dbValue);
@ -879,17 +790,29 @@ void BLERxView::on_data(BlePacketData* packet) {
// Start of Packet stuffing.
// Masking off the top 2 bytes to avoid invalid keys.
BleRecentEntry tempEntry;
uint64_t key = macAddressEncoded & 0xFFFFFFFFFFFF;
bool packetExists = false;
if (updateEntry(packet, tempEntry, (ADV_PDU_TYPE)packet->type)) {
auto& entry = ::on_packet(recent, macAddressEncoded & 0xFFFFFFFFFFFF);
// If found store into tempEntry to modify.
auto it = find(recent, key);
if (it != recent.end()) {
recent.push_front(*it);
recent.erase(it);
updateEntry(packet, recent.front(), (ADV_PDU_TYPE)packet->type);
packetExists = true;
} else {
recent.emplace_front(key);
truncate_entries(recent);
// Preserve exisisting data from entry.
tempEntry.macAddress = macAddressEncoded;
tempEntry.numHits = ++entry.numHits;
packetExists = updateEntry(packet, recent.front(), (ADV_PDU_TYPE)packet->type);
entry = tempEntry;
// If parsing failed, remove entry.
if (!packetExists) {
recent.erase(recent.begin());
}
}
if (packetExists) {
handle_filter_options(options_filter.selected_index());
handle_entries_sort(options_sort.selected_index());
@ -899,7 +822,7 @@ void BLERxView::on_data(BlePacketData* packet) {
while (it != searchList.end()) {
std::string searchStr = (std::string)*it;
if (entry.dataString.find(searchStr) != std::string::npos) {
if (recent.front().dataString.find(searchStr) != std::string::npos) {
searchList.erase(it);
found_count++;
break;
@ -1000,13 +923,10 @@ void BLERxView::on_timer() {
timer_count = 0;
if (auto_channel) {
int min = 37;
int max = 39;
field_frequency.set_value(get_freq_by_channel_number(channel_number));
baseband::set_btlerx(channel_number);
int randomChannel = min + std::rand() % (max - min + 1);
field_frequency.set_value(get_freq_by_channel_number(randomChannel));
baseband::set_btlerx(randomChannel);
channel_number = (channel_number < 39) ? channel_number + 1 : 37;
}
}
if (ble_rx_error != BLE_RX_NO_ERROR) {
@ -1093,7 +1013,7 @@ bool BLERxView::updateEntry(const BlePacketData* packet, BleRecentEntry& entry,
data_string += to_string_hex(packet->data[i], 2);
}
entry.dbValue = 2 * (packet->max_dB - get_total_gain(receiver_model.lna(), receiver_model.vga()));
entry.dbValue = packet->max_dB - (receiver_model.lna() + receiver_model.vga() + (receiver_model.rf_amp() ? 14 : 0));
entry.timestamp = to_string_timestamp(rtc_time::now());
entry.dataString = data_string;
@ -1111,6 +1031,7 @@ bool BLERxView::updateEntry(const BlePacketData* packet, BleRecentEntry& entry,
entry.pduType = pdu_type;
entry.channelNumber = channel_number;
entry.numHits++;
if (entry.vendor_status == MAC_VENDOR_UNKNOWN) {
std::string vendor_name;
@ -1125,8 +1046,7 @@ bool BLERxView::updateEntry(const BlePacketData* packet, BleRecentEntry& entry,
entry.include_name = check_name.value();
// Only parse name for advertisment packets and empty name entries
if (pdu_type == ADV_IND || pdu_type == ADV_NONCONN_IND) // || pdu_type == SCAN_RSP || pdu_type == ADV_SCAN_IND)
{
if (pdu_type == ADV_IND || pdu_type == ADV_NONCONN_IND || pdu_type == SCAN_RSP || pdu_type == ADV_SCAN_IND) {
if (uniqueParsing) {
// Add your unique beacon parsing function here.
}
@ -1145,6 +1065,7 @@ bool BLERxView::updateEntry(const BlePacketData* packet, BleRecentEntry& entry,
bool BLERxView::parse_beacon_data(const uint8_t* data, uint8_t length, std::string& nameString, std::string& informationString) {
uint8_t currentByte, currentLength, currentType = 0;
std::string tempName = "";
for (currentByte = 0; currentByte < length;) {
currentLength = data[currentByte++];
@ -1154,18 +1075,25 @@ bool BLERxView::parse_beacon_data(const uint8_t* data, uint8_t length, std::stri
for (int i = 0; ((i < currentLength - 1) && (currentByte < length)); i++) {
// parse the name of bluetooth device: 0x08->Shortened Local Name; 0x09->Complete Local Name
if (currentType == 0x08 || currentType == 0x09) {
nameString += (char)data[currentByte];
tempName += (char)data[currentByte];
}
currentByte++;
}
}
if (nameString.empty()) {
nameString = "None";
if (!tempName.empty()) {
nameString = tempName;
break;
}
}
informationString = "";
if (!informationString.empty()) {
// Option to change title of Hits Column.
// Setting to default for now.
columns.set(1, "Hits", 7);
}
return true;
}