Loading fastboot/device/commands.cpp +60 −20 Original line number Diff line number Diff line Loading @@ -42,26 +42,66 @@ using ::android::hardware::boot::V1_0::CommandResult; using ::android::hardware::boot::V1_0::Slot; using namespace android::fs_mgr; struct VariableHandlers { // Callback to retrieve the value of a single variable. std::function<bool(FastbootDevice*, const std::vector<std::string>&, std::string*)> get; // Callback to retrieve all possible argument combinations, for getvar all. std::function<std::vector<std::vector<std::string>>(FastbootDevice*)> get_all_args; }; static void GetAllVars(FastbootDevice* device, const std::string& name, const VariableHandlers& handlers) { if (!handlers.get_all_args) { std::string message; if (!handlers.get(device, std::vector<std::string>(), &message)) { return; } device->WriteInfo(android::base::StringPrintf("%s:%s", name.c_str(), message.c_str())); return; } auto all_args = handlers.get_all_args(device); for (const auto& args : all_args) { std::string message; if (!handlers.get(device, args, &message)) { continue; } std::string arg_string = android::base::Join(args, ":"); device->WriteInfo(android::base::StringPrintf("%s:%s:%s", name.c_str(), arg_string.c_str(), message.c_str())); } } bool GetVarHandler(FastbootDevice* device, const std::vector<std::string>& args) { using VariableHandler = std::function<bool(FastbootDevice*, const std::vector<std::string>&, std::string*)>; const std::unordered_map<std::string, VariableHandler> kVariableMap = { {FB_VAR_VERSION, GetVersion}, {FB_VAR_VERSION_BOOTLOADER, GetBootloaderVersion}, {FB_VAR_VERSION_BASEBAND, GetBasebandVersion}, {FB_VAR_PRODUCT, GetProduct}, {FB_VAR_SERIALNO, GetSerial}, {FB_VAR_SECURE, GetSecure}, {FB_VAR_UNLOCKED, GetUnlocked}, {FB_VAR_MAX_DOWNLOAD_SIZE, GetMaxDownloadSize}, {FB_VAR_CURRENT_SLOT, ::GetCurrentSlot}, {FB_VAR_SLOT_COUNT, GetSlotCount}, {FB_VAR_HAS_SLOT, GetHasSlot}, {FB_VAR_SLOT_SUCCESSFUL, GetSlotSuccessful}, {FB_VAR_SLOT_UNBOOTABLE, GetSlotUnbootable}, {FB_VAR_PARTITION_SIZE, GetPartitionSize}, {FB_VAR_IS_LOGICAL, GetPartitionIsLogical}, {FB_VAR_IS_USERSPACE, GetIsUserspace}}; const std::unordered_map<std::string, VariableHandlers> kVariableMap = { {FB_VAR_VERSION, {GetVersion, nullptr}}, {FB_VAR_VERSION_BOOTLOADER, {GetBootloaderVersion, nullptr}}, {FB_VAR_VERSION_BASEBAND, {GetBasebandVersion, nullptr}}, {FB_VAR_PRODUCT, {GetProduct, nullptr}}, {FB_VAR_SERIALNO, {GetSerial, nullptr}}, {FB_VAR_SECURE, {GetSecure, nullptr}}, {FB_VAR_UNLOCKED, {GetUnlocked, nullptr}}, {FB_VAR_MAX_DOWNLOAD_SIZE, {GetMaxDownloadSize, nullptr}}, {FB_VAR_CURRENT_SLOT, {::GetCurrentSlot, nullptr}}, {FB_VAR_SLOT_COUNT, {GetSlotCount, nullptr}}, {FB_VAR_HAS_SLOT, {GetHasSlot, GetAllPartitionArgsNoSlot}}, {FB_VAR_SLOT_SUCCESSFUL, {GetSlotSuccessful, nullptr}}, {FB_VAR_SLOT_UNBOOTABLE, {GetSlotUnbootable, nullptr}}, {FB_VAR_PARTITION_SIZE, {GetPartitionSize, GetAllPartitionArgsWithSlot}}, {FB_VAR_IS_LOGICAL, {GetPartitionIsLogical, GetAllPartitionArgsWithSlot}}, {FB_VAR_IS_USERSPACE, {GetIsUserspace, nullptr}}}; if (args.size() < 2) { return device->WriteFail("Missing argument"); } // Special case: return all variables that we can. if (args[1] == "all") { for (const auto& [name, handlers] : kVariableMap) { GetAllVars(device, name, handlers); } return device->WriteOkay(""); } // args[0] is command name, args[1] is variable. auto found_variable = kVariableMap.find(args[1]); Loading @@ -71,7 +111,7 @@ bool GetVarHandler(FastbootDevice* device, const std::vector<std::string>& args) std::string message; std::vector<std::string> getvar_args(args.begin() + 2, args.end()); if (!found_variable->second(device, getvar_args, &message)) { if (!found_variable->second.get(device, getvar_args, &message)) { return device->WriteFail(message); } return device->WriteOkay(message); Loading fastboot/device/fastboot_device.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -137,3 +137,7 @@ bool FastbootDevice::WriteOkay(const std::string& message) { bool FastbootDevice::WriteFail(const std::string& message) { return WriteStatus(FastbootResult::FAIL, message); } bool FastbootDevice::WriteInfo(const std::string& message) { return WriteStatus(FastbootResult::INFO, message); } fastboot/device/fastboot_device.h +2 −1 Original line number Diff line number Diff line Loading @@ -39,9 +39,10 @@ class FastbootDevice { bool HandleData(bool read, std::vector<char>* data); std::string GetCurrentSlot(); // Shortcuts for writing OKAY and FAIL status results. // Shortcuts for writing status results. bool WriteOkay(const std::string& message); bool WriteFail(const std::string& message); bool WriteInfo(const std::string& message); std::vector<char>& download_data() { return download_data_; } Transport* get_transport() { return transport_.get(); } Loading fastboot/device/utility.cpp +35 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,11 @@ #include "utility.h" #include <dirent.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <android-base/logging.h> #include <fs_mgr_dm_linear.h> #include <liblp/liblp.h> Loading Loading @@ -123,3 +128,33 @@ bool GetSlotNumber(const std::string& slot, Slot* number) { *number = slot[0] - 'a'; return true; } std::vector<std::string> ListPartitions(FastbootDevice* device) { std::vector<std::string> partitions; // First get physical partitions. struct dirent* de; std::unique_ptr<DIR, decltype(&closedir)> by_name(opendir("/dev/block/by-name"), closedir); while ((de = readdir(by_name.get())) != nullptr) { if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) { continue; } struct stat s; std::string path = "/dev/block/by-name/" + std::string(de->d_name); if (!stat(path.c_str(), &s) && S_ISBLK(s.st_mode)) { partitions.emplace_back(de->d_name); } } // Next get logical partitions. if (auto path = FindPhysicalPartition(LP_METADATA_PARTITION_NAME)) { uint32_t slot_number = SlotNumberForSlotSuffix(device->GetCurrentSlot()); if (auto metadata = ReadMetadata(path->c_str(), slot_number)) { for (const auto& partition : metadata->partitions) { std::string partition_name = GetPartitionName(partition); partitions.emplace_back(partition_name); } } } return partitions; } fastboot/device/utility.h +1 −1 Original line number Diff line number Diff line Loading @@ -56,5 +56,5 @@ std::optional<std::string> FindPhysicalPartition(const std::string& name); bool LogicalPartitionExists(const std::string& name, const std::string& slot_suffix, bool* is_zero_length = nullptr); bool OpenPartition(FastbootDevice* device, const std::string& name, PartitionHandle* handle); bool GetSlotNumber(const std::string& slot, android::hardware::boot::V1_0::Slot* number); std::vector<std::string> ListPartitions(FastbootDevice* device); Loading
fastboot/device/commands.cpp +60 −20 Original line number Diff line number Diff line Loading @@ -42,26 +42,66 @@ using ::android::hardware::boot::V1_0::CommandResult; using ::android::hardware::boot::V1_0::Slot; using namespace android::fs_mgr; struct VariableHandlers { // Callback to retrieve the value of a single variable. std::function<bool(FastbootDevice*, const std::vector<std::string>&, std::string*)> get; // Callback to retrieve all possible argument combinations, for getvar all. std::function<std::vector<std::vector<std::string>>(FastbootDevice*)> get_all_args; }; static void GetAllVars(FastbootDevice* device, const std::string& name, const VariableHandlers& handlers) { if (!handlers.get_all_args) { std::string message; if (!handlers.get(device, std::vector<std::string>(), &message)) { return; } device->WriteInfo(android::base::StringPrintf("%s:%s", name.c_str(), message.c_str())); return; } auto all_args = handlers.get_all_args(device); for (const auto& args : all_args) { std::string message; if (!handlers.get(device, args, &message)) { continue; } std::string arg_string = android::base::Join(args, ":"); device->WriteInfo(android::base::StringPrintf("%s:%s:%s", name.c_str(), arg_string.c_str(), message.c_str())); } } bool GetVarHandler(FastbootDevice* device, const std::vector<std::string>& args) { using VariableHandler = std::function<bool(FastbootDevice*, const std::vector<std::string>&, std::string*)>; const std::unordered_map<std::string, VariableHandler> kVariableMap = { {FB_VAR_VERSION, GetVersion}, {FB_VAR_VERSION_BOOTLOADER, GetBootloaderVersion}, {FB_VAR_VERSION_BASEBAND, GetBasebandVersion}, {FB_VAR_PRODUCT, GetProduct}, {FB_VAR_SERIALNO, GetSerial}, {FB_VAR_SECURE, GetSecure}, {FB_VAR_UNLOCKED, GetUnlocked}, {FB_VAR_MAX_DOWNLOAD_SIZE, GetMaxDownloadSize}, {FB_VAR_CURRENT_SLOT, ::GetCurrentSlot}, {FB_VAR_SLOT_COUNT, GetSlotCount}, {FB_VAR_HAS_SLOT, GetHasSlot}, {FB_VAR_SLOT_SUCCESSFUL, GetSlotSuccessful}, {FB_VAR_SLOT_UNBOOTABLE, GetSlotUnbootable}, {FB_VAR_PARTITION_SIZE, GetPartitionSize}, {FB_VAR_IS_LOGICAL, GetPartitionIsLogical}, {FB_VAR_IS_USERSPACE, GetIsUserspace}}; const std::unordered_map<std::string, VariableHandlers> kVariableMap = { {FB_VAR_VERSION, {GetVersion, nullptr}}, {FB_VAR_VERSION_BOOTLOADER, {GetBootloaderVersion, nullptr}}, {FB_VAR_VERSION_BASEBAND, {GetBasebandVersion, nullptr}}, {FB_VAR_PRODUCT, {GetProduct, nullptr}}, {FB_VAR_SERIALNO, {GetSerial, nullptr}}, {FB_VAR_SECURE, {GetSecure, nullptr}}, {FB_VAR_UNLOCKED, {GetUnlocked, nullptr}}, {FB_VAR_MAX_DOWNLOAD_SIZE, {GetMaxDownloadSize, nullptr}}, {FB_VAR_CURRENT_SLOT, {::GetCurrentSlot, nullptr}}, {FB_VAR_SLOT_COUNT, {GetSlotCount, nullptr}}, {FB_VAR_HAS_SLOT, {GetHasSlot, GetAllPartitionArgsNoSlot}}, {FB_VAR_SLOT_SUCCESSFUL, {GetSlotSuccessful, nullptr}}, {FB_VAR_SLOT_UNBOOTABLE, {GetSlotUnbootable, nullptr}}, {FB_VAR_PARTITION_SIZE, {GetPartitionSize, GetAllPartitionArgsWithSlot}}, {FB_VAR_IS_LOGICAL, {GetPartitionIsLogical, GetAllPartitionArgsWithSlot}}, {FB_VAR_IS_USERSPACE, {GetIsUserspace, nullptr}}}; if (args.size() < 2) { return device->WriteFail("Missing argument"); } // Special case: return all variables that we can. if (args[1] == "all") { for (const auto& [name, handlers] : kVariableMap) { GetAllVars(device, name, handlers); } return device->WriteOkay(""); } // args[0] is command name, args[1] is variable. auto found_variable = kVariableMap.find(args[1]); Loading @@ -71,7 +111,7 @@ bool GetVarHandler(FastbootDevice* device, const std::vector<std::string>& args) std::string message; std::vector<std::string> getvar_args(args.begin() + 2, args.end()); if (!found_variable->second(device, getvar_args, &message)) { if (!found_variable->second.get(device, getvar_args, &message)) { return device->WriteFail(message); } return device->WriteOkay(message); Loading
fastboot/device/fastboot_device.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -137,3 +137,7 @@ bool FastbootDevice::WriteOkay(const std::string& message) { bool FastbootDevice::WriteFail(const std::string& message) { return WriteStatus(FastbootResult::FAIL, message); } bool FastbootDevice::WriteInfo(const std::string& message) { return WriteStatus(FastbootResult::INFO, message); }
fastboot/device/fastboot_device.h +2 −1 Original line number Diff line number Diff line Loading @@ -39,9 +39,10 @@ class FastbootDevice { bool HandleData(bool read, std::vector<char>* data); std::string GetCurrentSlot(); // Shortcuts for writing OKAY and FAIL status results. // Shortcuts for writing status results. bool WriteOkay(const std::string& message); bool WriteFail(const std::string& message); bool WriteInfo(const std::string& message); std::vector<char>& download_data() { return download_data_; } Transport* get_transport() { return transport_.get(); } Loading
fastboot/device/utility.cpp +35 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,11 @@ #include "utility.h" #include <dirent.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <android-base/logging.h> #include <fs_mgr_dm_linear.h> #include <liblp/liblp.h> Loading Loading @@ -123,3 +128,33 @@ bool GetSlotNumber(const std::string& slot, Slot* number) { *number = slot[0] - 'a'; return true; } std::vector<std::string> ListPartitions(FastbootDevice* device) { std::vector<std::string> partitions; // First get physical partitions. struct dirent* de; std::unique_ptr<DIR, decltype(&closedir)> by_name(opendir("/dev/block/by-name"), closedir); while ((de = readdir(by_name.get())) != nullptr) { if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) { continue; } struct stat s; std::string path = "/dev/block/by-name/" + std::string(de->d_name); if (!stat(path.c_str(), &s) && S_ISBLK(s.st_mode)) { partitions.emplace_back(de->d_name); } } // Next get logical partitions. if (auto path = FindPhysicalPartition(LP_METADATA_PARTITION_NAME)) { uint32_t slot_number = SlotNumberForSlotSuffix(device->GetCurrentSlot()); if (auto metadata = ReadMetadata(path->c_str(), slot_number)) { for (const auto& partition : metadata->partitions) { std::string partition_name = GetPartitionName(partition); partitions.emplace_back(partition_name); } } } return partitions; }
fastboot/device/utility.h +1 −1 Original line number Diff line number Diff line Loading @@ -56,5 +56,5 @@ std::optional<std::string> FindPhysicalPartition(const std::string& name); bool LogicalPartitionExists(const std::string& name, const std::string& slot_suffix, bool* is_zero_length = nullptr); bool OpenPartition(FastbootDevice* device, const std::string& name, PartitionHandle* handle); bool GetSlotNumber(const std::string& slot, android::hardware::boot::V1_0::Slot* number); std::vector<std::string> ListPartitions(FastbootDevice* device);