Release fw 0.8.4: doc sync, System UI, BT/FM polish.
Align README, manual, and backlog to 0.8.4; add Web UI System tab for OTA/DSP uploads, serial in health header, FM seek down, and BT1035 paired list plus auto-reconnect API. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -12,6 +12,8 @@
|
||||
*/
|
||||
|
||||
#include "core/Bt1035At.hpp"
|
||||
#include "core/Bt1035PairedDevice.hpp"
|
||||
#include "core/BluetoothJson.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
@@ -74,6 +76,50 @@ namespace {
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
[[nodiscard]] int runNameAutoConnPairedParseTest()
|
||||
{
|
||||
const auto name =
|
||||
core::parseBt1035NameResponse("+NAME=DigiRadio-A1B2\r\nOK\r\n");
|
||||
if (!name || *name != "DigiRadio-A1B2") {
|
||||
std::cerr << "NAME parse failed\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
const auto autoconn =
|
||||
core::parseBt1035AutoConnResponse("+AUTOCONN=3\r\nOK\r\n");
|
||||
if (!autoconn || *autoconn != 3U) {
|
||||
std::cerr << "AUTOCONN parse failed\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
const auto plist = core::parseBt1035PairedListResponse(
|
||||
"+PLIST=1,001122334455,Phone\r\n"
|
||||
"+PLIST=2,FFEEDDCCBBAA,\r\n"
|
||||
"OK\r\n");
|
||||
if (!plist || plist->size() != 2U || (*plist)[0U].index != 1U
|
||||
|| (*plist)[0U].mac != "001122334455"
|
||||
|| (*plist)[0U].name != "Phone") {
|
||||
std::cerr << "PLIST parse failed\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
const std::string pairedJson =
|
||||
core::serializeBluetoothPairedJson(*plist);
|
||||
if (pairedJson.find("\"index\":1") == std::string::npos
|
||||
|| pairedJson.find("\"mac\":\"001122334455\"") == std::string::npos) {
|
||||
std::cerr << "paired JSON serialise failed: " << pairedJson << '\n';
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
const auto times =
|
||||
core::parseBluetoothAutoReconnectJson(R"({"times":5})");
|
||||
if (!times || *times != 5U) {
|
||||
std::cerr << "auto-reconnect JSON parse failed\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (core::buildBt1035SetAutoConnLine(5) != "AT+AUTOCONN=5\r\n") {
|
||||
std::cerr << "AUTOCONN command line mismatch\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
@@ -84,5 +130,8 @@ int main()
|
||||
if (runParseTest() != EXIT_SUCCESS) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (runNameAutoConnPairedParseTest() != EXIT_SUCCESS) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -178,6 +178,34 @@ namespace {
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
[[nodiscard]] int runTunerSeekParseTest()
|
||||
{
|
||||
const auto empty = core::parseTunerSeekJson("");
|
||||
if (!empty || *empty != core::SeekDirection::Up) {
|
||||
std::cerr << "empty seek body should default to up\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
const auto up =
|
||||
core::parseTunerSeekJson(R"({"direction":"up"})");
|
||||
if (!up || *up != core::SeekDirection::Up) {
|
||||
std::cerr << "seek up parse failed\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
const auto down =
|
||||
core::parseTunerSeekJson(R"({"direction":"down"})");
|
||||
if (!down || *down != core::SeekDirection::Down) {
|
||||
std::cerr << "seek down parse failed\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
const auto bad =
|
||||
core::parseTunerSeekJson(R"({"direction":"sideways"})");
|
||||
if (bad) {
|
||||
std::cerr << "expected invalid seek direction rejection\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
@@ -209,5 +237,8 @@ int main()
|
||||
if (runTunerErrorSerialiseTest() != EXIT_SUCCESS) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (runTunerSeekParseTest() != EXIT_SUCCESS) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user