Added support for extracting firmware from TAR file (with apps) (#1704)

* Added support for extracting firmware from TAR file (with apps)
* Added tar to usb cdc firmware command.
* Serial flash tar
* Show error on bad tar
* Check tar for valid filenames
This commit is contained in:
Totoo 2024-01-03 14:05:24 +01:00 committed by GitHub
parent d122a8fc3b
commit fbe7954f2e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 251 additions and 4 deletions

View file

@ -50,6 +50,17 @@ FlashUtilityView::FlashUtilityView(NavigationView& nav)
this->firmware_selected(path);
}});
}
for (const auto& entry : std::filesystem::directory_iterator(firmware_folder, u"*.ppfw.tar")) {
auto filename = entry.path().filename();
auto path = entry.path().native();
menu_view.add_item({filename.string().substr(0, max_filename_length),
ui::Color::purple(),
&bitmap_icon_temperature,
[this, path](KeyEvent) {
this->firmware_selected(path);
}});
}
}
void FlashUtilityView::firmware_selected(std::filesystem::path::string_type path) {
@ -65,7 +76,43 @@ void FlashUtilityView::firmware_selected(std::filesystem::path::string_type path
});
}
bool FlashUtilityView::endsWith(const std::u16string& str, const std::u16string& suffix) {
if (str.length() >= suffix.length()) {
std::u16string endOfString = str.substr(str.length() - suffix.length());
return endOfString == suffix;
} else {
return false;
}
}
std::filesystem::path FlashUtilityView::extract_tar(std::filesystem::path::string_type path) {
//
ui::Painter painter;
painter.fill_rectangle(
{0, 0, portapack::display.width(), portapack::display.height()},
ui::Color::black());
painter.draw_string({12, 24}, this->nav_.style(), "Unpacking TAR file...");
auto res = UnTar::untar(path, [this](const std::string fileName) {
ui::Painter painter;
painter.fill_rectangle({0, 50, portapack::display.width(), 90}, ui::Color::black());
painter.draw_string({0, 60}, this->nav_.style(), fileName);
});
if (res.string().empty()) {
ui::Painter painter;
painter.fill_rectangle({0, 50, portapack::display.width(), 90}, ui::Color::black());
painter.draw_string({0, 60}, this->nav_.style(), "BAD TAR FILE");
chThdSleepMilliseconds(5000);
}
return res;
}
void FlashUtilityView::flash_firmware(std::filesystem::path::string_type path) {
if (endsWith(path, u".ppfw.tar")) {
// extract, then update
path = extract_tar(u'/' + path).native();
if (path.empty()) return;
}
ui::Painter painter;
painter.fill_rectangle(
{0, 0, portapack::display.width(), portapack::display.height()},