summaryrefslogtreecommitdiff
path: root/fastboot/Fastboot.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fastboot/Fastboot.cpp')
-rw-r--r--fastboot/Fastboot.cpp72
1 files changed, 67 insertions, 5 deletions
diff --git a/fastboot/Fastboot.cpp b/fastboot/Fastboot.cpp
index 93435d6..922334b 100644
--- a/fastboot/Fastboot.cpp
+++ b/fastboot/Fastboot.cpp
@@ -19,11 +19,19 @@
#include <string>
#include <unordered_map>
#include <vector>
+#include <map>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
+
+// FS headers
+#include <ext4_utils/wipe.h>
+#include <fs_mgr.h>
+#include <fs_mgr/roots.h>
+
+// Nugget headers
#include <app_nugget.h>
#include <nos/NuggetClient.h>
#include <nos/debug.h>
@@ -122,7 +130,50 @@ Return<void> Fastboot::doOemCommand(const ::android::hardware::hidl_string& oemC
return Void();
}
+static android::fs_mgr::Fstab fstab;
+enum WipeVolumeStatus {
+ WIPE_OK = 0,
+ VOL_FSTAB,
+ VOL_UNKNOWN,
+ VOL_MOUNTED,
+ VOL_BLK_DEV_OPEN,
+ WIPE_ERROR_MAX = 0xffffffff,
+};
+std::map<enum WipeVolumeStatus, std::string> wipe_vol_ret_msg{
+ {WIPE_OK, ""},
+ {VOL_FSTAB, "Unknown FS table"},
+ {VOL_UNKNOWN, "Unknown volume"},
+ {VOL_MOUNTED, "Fail to unmount volume"},
+ {VOL_BLK_DEV_OPEN, "Fail to open block device"},
+ {WIPE_ERROR_MAX, "Unknown wipe error"}};
+
+enum WipeVolumeStatus wipe_volume(const std::string &volume) {
+ if (!android::fs_mgr::ReadDefaultFstab(&fstab)) {
+ return VOL_FSTAB;
+ }
+ const fs_mgr::FstabEntry *v = android::fs_mgr::GetEntryForPath(&fstab, volume);
+ if (v == nullptr) {
+ return VOL_UNKNOWN;
+ }
+ if (android::fs_mgr::EnsurePathUnmounted(&fstab, volume) != true) {
+ return VOL_MOUNTED;
+ }
+
+ int fd = open(v->blk_device.c_str(), O_WRONLY | O_CREAT, 0644);
+ if (fd == -1) {
+ return VOL_BLK_DEV_OPEN;
+ }
+ wipe_block_device(fd, get_block_device_size(fd));
+ close(fd);
+
+ return WIPE_OK;
+}
+
Return<void> Fastboot::doOemSpecificErase(V1_1::IFastboot::doOemSpecificErase_cb _hidl_cb) {
+ // Erase metadata partition along with userdata partition.
+ // Keep erasing Titan M even if failing on this case.
+ auto wipe_status = wipe_volume("/metadata");
+
// Connect to Titan M
::nos::NuggetClient client;
client.Open();
@@ -136,16 +187,27 @@ Return<void> Fastboot::doOemSpecificErase(V1_1::IFastboot::doOemSpecificErase_cb
std::vector<uint8_t> magic(sizeof(magicValue));
memcpy(magic.data(), &magicValue, sizeof(magicValue));
const uint8_t retry_count = 5;
+ uint32_t nugget_status;
for(uint8_t i = 0; i < retry_count; i++) {
- const uint32_t status
- = client.CallApp(APP_ID_NUGGET, NUGGET_PARAM_NUKE_FROM_ORBIT, magic, nullptr);
- if (status == APP_SUCCESS) {
- _hidl_cb({ Status::SUCCESS, "" });
+ nugget_status = client.CallApp(APP_ID_NUGGET, NUGGET_PARAM_NUKE_FROM_ORBIT, magic, nullptr);
+ if (nugget_status == APP_SUCCESS && wipe_status == WIPE_OK) {
+ _hidl_cb({Status::SUCCESS, wipe_vol_ret_msg[wipe_status]});
return Void();
}
}
- _hidl_cb({ Status::FAILURE_UNKNOWN, "Titan M user data wipe failed" });
+ // Return exactly what happened
+ if (nugget_status != APP_SUCCESS && wipe_status != WIPE_OK) {
+ _hidl_cb({Status::FAILURE_UNKNOWN, "Fail on wiping metadata and Titan M user data"});
+ } else if (nugget_status != APP_SUCCESS) {
+ _hidl_cb({Status::FAILURE_UNKNOWN, "Titan M user data wipe failed"});
+ } else {
+ if (wipe_vol_ret_msg.find(wipe_status) != wipe_vol_ret_msg.end())
+ _hidl_cb({Status::FAILURE_UNKNOWN, wipe_vol_ret_msg[wipe_status]});
+ else // Should not reach here, but handle it anyway
+ _hidl_cb({Status::FAILURE_UNKNOWN, "Unknown failure"});
+ }
+
return Void();
}