Skip to content

Commit

Permalink
Workaround buggy encoders that show 1 extra character in RT+ fields
Browse files Browse the repository at this point in the history
  • Loading branch information
windytan committed Sep 26, 2024
1 parent 9050c40 commit 23b063d
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 36 deletions.
3 changes: 2 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* New features:
* Decode 'broadcaster use' data in Slow labeling codes (variant 6)
* Decode 'decoder identification' bits in Group 15B
* Workaround buggy encoders that show 1 extra character in RT+ fields
* Bug fixes:
* Fix the CSVReader (used in the TMC decoder) ignoring the last line of any file
* Remove extra trailing space in transparent data channels hexdump
Expand All @@ -13,7 +14,7 @@
* macOS: ask Homebrew about liquid-dsp location instead of hardcoding it
* Set default installation prefix to /usr/local (all platforms)

## 1.0.1
## 1.0.1 (2024-07-19)

* Fixes:
* Fix a crash (uncaught json exception) when attempting to serialize a string that's
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ Try running this in the terminal:

## Contributing

We welcome bug reports and documentation contributions. See
We welcome bug reports and documentation contributions. Or take a peek at our
[open issues](https://github.com/windytan/redsea/issues) to see where we could use a hand. See
[CONTRIBUTING](CONTRIBUTING.md) for more information.

Also, if a station in your area is transmitting an interesting RDS feature
Expand Down
6 changes: 3 additions & 3 deletions src/groups.cc
Original file line number Diff line number Diff line change
Expand Up @@ -322,11 +322,11 @@ void Station::updateAndPrint(const Group& group, std::ostream& stream) {
// incomplete JSON objects could get printed.
std::stringstream output_proxy_stream;
output_proxy_stream << json_;
stream << output_proxy_stream.str() << std::endl << std::flush;
stream << output_proxy_stream.str() << std::endl;
} catch (const std::exception& e) {
nlohmann::ordered_json json_from_exception;
json_from_exception["debug"] = std::string(e.what());
stream << json_from_exception << std::endl << std::flush;
stream << json_from_exception << std::endl;
}
}

Expand Down Expand Up @@ -1022,7 +1022,7 @@ void parseRadioTextPlus(const Group& group, RadioText& rt, nlohmann::ordered_jso
if (text.length() > 0 && tag.content_type != 0) {
nlohmann::ordered_json tag_json;
tag_json["content-type"] = getRTPlusContentTypeString(tag.content_type);
tag_json["data"] = text;
tag_json["data"] = rtrim(text);
json_el["tags"].push_back(tag_json);
}
}
Expand Down
86 changes: 55 additions & 31 deletions test/unit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -327,26 +327,59 @@ TEST_CASE("Enhanced RadioText") {
TEST_CASE("RadioText Plus") {
redsea::Options options;

SECTION("Containing non-ascii characters") {
// Some encoders forget that RT+ length field means _additional_ length, so we need to rtrim
SECTION("Off-by-one encoder bug workaround") {
// clang-format off
const auto json_lines{hex2json({
// RT+ ODA identifier
0x53C5'3558'0000'4BD7,
// RT+
0x53C5'C548'8020'0A6A,
// RT message
0x53C5'2550'4649'4F52,
0x53C5'2551'454C'4C41,
0x53C5'2552'204D'414E,
0x53C5'2553'4E4F'4941,
0x53C5'2554'202D'2047,
0x53C5'2555'4C49'2041,
0x53C5'2556'4D41'4E54,
0x53C5'2557'4920'2020,
0x53C5'2558'2020'2020, 0x53C5'2559'2020'2020, 0x53C5'255A'2020'2020,
0x53C5'255B'2020'2020, 0x53C5'255C'2020'2020, 0x53C5'255D'2020'2020,
0x53C5'255E'2020'2020, 0x53C5'255F'2020'2020,
// RT+ (second one)
0x53C5'C548'8020'0A6A,
}, options, 0x53C5)};
// clang-format on

REQUIRE(json_lines.back()["radiotext_plus"]["tags"].size() == 2);
CHECK(json_lines.back()["radiotext_plus"]["tags"][0]["content-type"] == "item.artist");
CHECK(json_lines.back()["radiotext_plus"]["tags"][0]["data"] == "FIORELLA MANNOIA");
CHECK(json_lines.back()["radiotext_plus"]["tags"][1]["content-type"] == "item.title");
CHECK(json_lines.back()["radiotext_plus"]["tags"][1]["data"] == "GLI AMANTI");
}

// Should count the number of letters and not UTF8-converted bytes
SECTION("Containing non-ASCII characters") {
// Antenne 2016-09-17
// clang-format off
const auto json_lines{hex2json({
// RT+ ODA identifier
0xD318'3558'0000'4BD7,
// RT+ (we need two of these to confirm)
0xD318'C558'8D20'0DCF,
// RT message
0xD318'2540'6A65'747A, 0xD318'2541'7420'6175,
0xD318'2542'6620'414E, 0xD318'2543'5445'4E4E,
0xD318'2544'4520'4241, 0xD318'2545'5945'524E,
0xD318'2546'3A20'4368, 0xD318'2547'7269'7374,
0xD318'2548'696E'6120, 0xD318'2549'5374'9972,
0xD318'254A'6D65'7220, 0xD318'254B'2D20'4569,
0xD318'254C'6E20'5465, 0xD318'254D'696C'2076,
0xD318'254E'6F6E'206D, 0xD318'254F'6972'2020,
// RT+ (second one)
0xD318'C558'8D20'0DCF
}, options, 0xD318)};
const auto json_lines{hex2json({
// RT+ ODA identifier
0xD318'3558'0000'4BD7,
// RT+ (we need two of these to confirm)
0xD318'C558'8D20'0DCF,
// RT message
0xD318'2540'6A65'747A, 0xD318'2541'7420'6175,
0xD318'2542'6620'414E, 0xD318'2543'5445'4E4E,
0xD318'2544'4520'4241, 0xD318'2545'5945'524E,
0xD318'2546'3A20'4368, 0xD318'2547'7269'7374,
0xD318'2548'696E'6120, 0xD318'2549'5374'9972,
0xD318'254A'6D65'7220, 0xD318'254B'2D20'4569,
0xD318'254C'6E20'5465, 0xD318'254D'696C'2076,
0xD318'254E'6F6E'206D, 0xD318'254F'6972'2020,
// RT+ (second one)
0xD318'C558'8D20'0DCF
}, options, 0xD318)};
// clang-format on

REQUIRE(json_lines.back()["radiotext_plus"]["tags"].size() == 2);
Expand Down Expand Up @@ -418,18 +451,9 @@ TEST_CASE("Alternative frequencies") {
// YLE Helsinki (fi) 2016-09-15
// clang-format off
const auto json_lines{hex2json({
0x6403'0447'F741'4920,
0x6403'0440'415F'594C,
0x6403'0441'4441'4520,
0x6403'0442'5541'484B,
0x6403'0447'1C41'4920,
0x6403'0440'6841'594C,
0x6403'0441'5E41'4520,
0x6403'0442'414B'484B,
0x6403'0447'4156'4920,
0x6403'0440'CB41'594C,
0x6403'0441'B741'4520,
0x6403'0442'4174'484B
0x6403'0447'F741'4920, 0x6403'0440'415F'594C, 0x6403'0441'4441'4520, 0x6403'0442'5541'484B,
0x6403'0447'1C41'4920, 0x6403'0440'6841'594C, 0x6403'0441'5E41'4520, 0x6403'0442'414B'484B,
0x6403'0447'4156'4920, 0x6403'0440'CB41'594C, 0x6403'0441'B741'4520, 0x6403'0442'4174'484B
}, options, 0x6403)};
// clang-format on

Expand Down Expand Up @@ -520,7 +544,7 @@ TEST_CASE("Clock-time and date") {
}
}

// TDS is a rarely seen feature. The TRDS4001 encoder is known to fill the fields
// TDC is a rarely seen feature. The TRDS4001 encoder is known to fill the fields
// with its version string and some unknown binary data. We can at least test that this
// version string is found somewhere in the data.
TEST_CASE("Transparent data channels") {
Expand Down

0 comments on commit 23b063d

Please sign in to comment.