diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2018-08-07 00:08:18 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2018-08-07 00:08:18 +0000 |
commit | c30a75a00717cefa35de93e0aa50bb48d5f7a5c3 (patch) | |
tree | 32d4c912d52119f02e2e8c8ca62e3b249879078f /fastboot/device/commands.cpp | |
parent | 0e947189c5a9493e9f2038446d880038024d184b (diff) | |
parent | dea91b4b5354af2f9470845cb05cca1207142c98 (diff) |
Merge "Add fastbootd."
Diffstat (limited to 'fastboot/device/commands.cpp')
-rw-r--r-- | fastboot/device/commands.cpp | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp new file mode 100644 index 000000000..a3cbf9692 --- /dev/null +++ b/fastboot/device/commands.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "commands.h" + +#include <sys/socket.h> +#include <sys/un.h> + +#include <android-base/logging.h> +#include <android-base/parseint.h> +#include <android-base/properties.h> +#include <android-base/stringprintf.h> +#include <android-base/strings.h> +#include <android-base/unique_fd.h> +#include <cutils/android_reboot.h> + +#include "fastboot_device.h" + +bool DownloadHandler(FastbootDevice* device, const std::vector<std::string>& args) { + if (args.size() < 2) { + return device->WriteStatus(FastbootResult::FAIL, "size argument unspecified"); + } + // arg[0] is the command name, arg[1] contains size of data to be downloaded + unsigned int size; + if (!android::base::ParseUint("0x" + args[1], &size, UINT_MAX)) { + return device->WriteStatus(FastbootResult::FAIL, "Invalid size"); + } + device->get_download_data().resize(size); + if (!device->WriteStatus(FastbootResult::DATA, android::base::StringPrintf("%08x", size))) { + return false; + } + + if (device->HandleData(true, &device->get_download_data())) { + return device->WriteStatus(FastbootResult::OKAY, ""); + } + + PLOG(ERROR) << "Couldn't download data"; + return device->WriteStatus(FastbootResult::FAIL, "Couldn't download data"); +} + +bool SetActiveHandler(FastbootDevice* device, const std::vector<std::string>& /* args */) { + return device->WriteStatus(FastbootResult::OKAY, ""); +} + +bool ShutDownHandler(FastbootDevice* device, const std::vector<std::string>& /* args */) { + auto result = device->WriteStatus(FastbootResult::OKAY, "Shutting down"); + android::base::SetProperty(ANDROID_RB_PROPERTY, "shutdown,fastboot"); + device->CloseDevice(); + TEMP_FAILURE_RETRY(pause()); + return result; +} + +bool RebootHandler(FastbootDevice* device, const std::vector<std::string>& /* args */) { + auto result = device->WriteStatus(FastbootResult::OKAY, "Rebooting"); + android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot,from_fastboot"); + device->CloseDevice(); + TEMP_FAILURE_RETRY(pause()); + return result; +} + +bool RebootBootloaderHandler(FastbootDevice* device, const std::vector<std::string>& /* args */) { + auto result = device->WriteStatus(FastbootResult::OKAY, "Rebooting bootloader"); + android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot,bootloader"); + device->CloseDevice(); + TEMP_FAILURE_RETRY(pause()); + return result; +} + +bool RebootFastbootHandler(FastbootDevice* device, const std::vector<std::string>& /* args */) { + auto result = device->WriteStatus(FastbootResult::OKAY, "Rebooting fastboot"); + android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot,fastboot"); + device->CloseDevice(); + TEMP_FAILURE_RETRY(pause()); + return result; +} + +static bool EnterRecovery() { + const char msg_switch_to_recovery = 'r'; + + android::base::unique_fd sock(socket(AF_UNIX, SOCK_STREAM, 0)); + if (sock < 0) { + PLOG(ERROR) << "Couldn't create sock"; + return false; + } + + struct sockaddr_un addr = {.sun_family = AF_UNIX}; + strncpy(addr.sun_path, "/dev/socket/recovery", sizeof(addr.sun_path) - 1); + if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) { + PLOG(ERROR) << "Couldn't connect to recovery"; + return false; + } + // Switch to recovery will not update the boot reason since it does not + // require a reboot. + auto ret = write(sock, &msg_switch_to_recovery, sizeof(msg_switch_to_recovery)); + if (ret != sizeof(msg_switch_to_recovery)) { + PLOG(ERROR) << "Couldn't write message to switch to recovery"; + return false; + } + + return true; +} + +bool RebootRecoveryHandler(FastbootDevice* device, const std::vector<std::string>& /* args */) { + auto status = true; + if (EnterRecovery()) { + status = device->WriteStatus(FastbootResult::OKAY, "Rebooting to recovery"); + } else { + status = device->WriteStatus(FastbootResult::FAIL, "Unable to reboot to recovery"); + } + device->CloseDevice(); + TEMP_FAILURE_RETRY(pause()); + return status; +} |