blob: a43e7a6bbacd55f38c3457695b84d0c47b0b9728 [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
Anatol Pomazau5ae3f932012-02-28 07:21:08 -080012 * the documentation and/or other materials provided with the
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080013 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
Anatol Pomazau5ae3f932012-02-28 07:21:08 -080022 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080023 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
Aaron Wisnerdb511202018-06-26 15:38:35 -050028#include "engine.h"
Anatol Pomazauc8ba5362011-12-15 17:50:18 -080029
Colin Cross81c632e2013-01-23 19:13:43 -080030#include <errno.h>
Elliott Hughes3ab8b852015-08-25 19:34:13 -070031#include <stdarg.h>
Mark Salyzyn5957c1f2014-04-30 14:05:28 -070032#include <stdio.h>
33#include <stdlib.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080034#include <string.h>
Anatol Pomazauc8ba5362011-12-15 17:50:18 -080035#include <sys/stat.h>
Anatol Pomazauc8ba5362011-12-15 17:50:18 -080036#include <sys/types.h>
37#include <unistd.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080038
Elliott Hughes5620d222018-03-28 08:20:00 -070039#include <memory>
40#include <vector>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080041
Elliott Hughes5620d222018-03-28 08:20:00 -070042#include <android-base/stringprintf.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080043
Jerry Zhang769a9c12018-05-15 17:02:50 -070044#include "constants.h"
Elliott Hughes11ff3452018-04-09 13:58:41 -070045#include "transport.h"
46
Tom Cherry11f12092018-08-29 21:36:28 -070047using android::base::StringPrintf;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080048
Aaron Wisnerdb511202018-06-26 15:38:35 -050049static fastboot::FastBootDriver* fb = nullptr;
Anatol Pomazauc8ba5362011-12-15 17:50:18 -080050
Aaron Wisnerdb511202018-06-26 15:38:35 -050051void fb_init(fastboot::FastBootDriver& fbi) {
52 fb = &fbi;
53 auto cb = [](std::string& info) { fprintf(stderr, "(bootloader) %s\n", info.c_str()); };
54 fb->SetInfoCallback(cb);
55}
Colin Cross80f2d032012-05-24 18:24:53 -070056
David Anderson1d887432018-08-27 16:47:32 -070057void fb_reinit(Transport* transport) {
David Anderson03de6452018-09-04 14:32:54 -070058 if (Transport* old_transport = fb->set_transport(transport)) {
59 delete old_transport;
60 }
David Anderson1d887432018-08-27 16:47:32 -070061}
62
Aaron Wisnerdb511202018-06-26 15:38:35 -050063const std::string fb_get_error() {
64 return fb->Error();
65}
66
67bool fb_getvar(const std::string& key, std::string* value) {
68 return !fb->GetVar(key, value);
Colin Cross80f2d032012-05-24 18:24:53 -070069}
70
Tom Cherry11f12092018-08-29 21:36:28 -070071static void HandleResult(double start, int status) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080072 if (status) {
Tom Cherry11f12092018-08-29 21:36:28 -070073 fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str());
74 die("Command failed");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080075 } else {
Daniel Sandlercb6e22b2010-02-25 14:05:33 -050076 double split = now();
Tom Cherry11f12092018-08-29 21:36:28 -070077 fprintf(stderr, "OKAY [%7.3fs]\n", (split - start));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080078 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080079}
80
Tom Cherry11f12092018-08-29 21:36:28 -070081#define RUN_COMMAND(command) \
82 { \
83 double start = now(); \
84 auto status = (command); \
85 HandleResult(start, status); \
86 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080087
Elliott Hughes5620d222018-03-28 08:20:00 -070088void fb_set_active(const std::string& slot) {
Tom Cherry11f12092018-08-29 21:36:28 -070089 Status("Setting current slot to '" + slot + "'");
90 RUN_COMMAND(fb->SetActive(slot));
Daniel Rosenbergb7bd4ae2015-09-14 21:05:41 -070091}
92
Tom Cherry11f12092018-08-29 21:36:28 -070093void fb_erase(const std::string& partition) {
94 Status("Erasing '" + partition + "'");
95 RUN_COMMAND(fb->Erase(partition));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080096}
97
Tom Cherry11f12092018-08-29 21:36:28 -070098void fb_flash_fd(const std::string& partition, int fd, uint32_t sz) {
99 Status(StringPrintf("Sending '%s' (%u KB)", partition.c_str(), sz / 1024));
100 RUN_COMMAND(fb->Download(fd, sz));
Chris Fries0ea946c2017-04-12 10:25:57 -0500101
Tom Cherry11f12092018-08-29 21:36:28 -0700102 Status("Writing '" + partition + "'");
103 RUN_COMMAND(fb->Flash(partition));
Chris Fries0ea946c2017-04-12 10:25:57 -0500104}
105
Tom Cherrydfd85df2018-09-20 14:45:05 -0700106void fb_flash(const std::string& partition, const std::vector<char>& data) {
107 Status(StringPrintf("Sending '%s' (%zu KB)", partition.c_str(), data.size() / 1024));
108 RUN_COMMAND(fb->Download(data));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800109
Tom Cherry11f12092018-08-29 21:36:28 -0700110 Status("Writing '" + partition + "'");
111 RUN_COMMAND(fb->Flash(partition));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800112}
113
Tom Cherry11f12092018-08-29 21:36:28 -0700114void fb_flash_sparse(const std::string& partition, struct sparse_file* s, uint32_t sz,
115 size_t current, size_t total) {
116 Status(StringPrintf("Sending sparse '%s' %zu/%zu (%u KB)", partition.c_str(), current, total,
117 sz / 1024));
118 RUN_COMMAND(fb->Download(s));
Colin Crossf8387882012-05-24 17:18:41 -0700119
Tom Cherry11f12092018-08-29 21:36:28 -0700120 Status(StringPrintf("Writing sparse '%s' %zu/%zu", partition.c_str(), current, total));
121 RUN_COMMAND(fb->Flash(partition));
Colin Crossf8387882012-05-24 17:18:41 -0700122}
123
Tom Cherry11f12092018-08-29 21:36:28 -0700124void fb_create_partition(const std::string& partition, const std::string& size) {
125 Status("Creating '" + partition + "'");
126 RUN_COMMAND(fb->RawCommand(FB_CMD_CREATE_PARTITION ":" + partition + ":" + size));
David Anderson0d4277d2018-07-31 13:27:37 -0700127}
128
Tom Cherry11f12092018-08-29 21:36:28 -0700129void fb_delete_partition(const std::string& partition) {
130 Status("Deleting '" + partition + "'");
131 RUN_COMMAND(fb->RawCommand(FB_CMD_DELETE_PARTITION ":" + partition));
David Anderson0d4277d2018-07-31 13:27:37 -0700132}
133
Tom Cherry11f12092018-08-29 21:36:28 -0700134void fb_resize_partition(const std::string& partition, const std::string& size) {
135 Status("Resizing '" + partition + "'");
136 RUN_COMMAND(fb->RawCommand(FB_CMD_RESIZE_PARTITION ":" + partition + ":" + size));
David Anderson0d4277d2018-07-31 13:27:37 -0700137}
138
Tom Cherry11f12092018-08-29 21:36:28 -0700139void fb_display(const std::string& label, const std::string& var) {
140 std::string value;
141 auto status = fb->GetVar(var, &value);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800142
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800143 if (status) {
Tom Cherry11f12092018-08-29 21:36:28 -0700144 fprintf(stderr, "getvar:%s FAILED (%s)\n", var.c_str(), fb->Error().c_str());
145 return;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800146 }
Tom Cherry11f12092018-08-29 21:36:28 -0700147 fprintf(stderr, "%s: %s\n", label.c_str(), value.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800148}
149
Tom Cherry11f12092018-08-29 21:36:28 -0700150void fb_reboot() {
151 fprintf(stderr, "Rebooting");
152 fb->Reboot();
Elliott Hughes5620d222018-03-28 08:20:00 -0700153 fprintf(stderr, "\n");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800154}
155
Tom Cherry11f12092018-08-29 21:36:28 -0700156void fb_command(const std::string& cmd, const std::string& msg) {
157 Status(msg);
158 RUN_COMMAND(fb->RawCommand(cmd));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800159}
160
Tom Cherrydfd85df2018-09-20 14:45:05 -0700161void fb_download(const std::string& name, const std::vector<char>& data) {
Tom Cherry11f12092018-08-29 21:36:28 -0700162 Status("Downloading '" + name + "'");
Tom Cherrydfd85df2018-09-20 14:45:05 -0700163 RUN_COMMAND(fb->Download(data));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800164}
165
Tom Cherry11f12092018-08-29 21:36:28 -0700166void fb_download_fd(const std::string& name, int fd, uint32_t sz) {
167 Status(StringPrintf("Sending '%s' (%u KB)", name.c_str(), sz / 1024));
168 RUN_COMMAND(fb->Download(fd, sz));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800169}
170
Tom Cherry11f12092018-08-29 21:36:28 -0700171void fb_upload(const std::string& outfile) {
172 Status("Uploading '" + outfile + "'");
173 RUN_COMMAND(fb->Upload(outfile));
Jocelyn Bohr98cc2832017-01-26 19:20:53 -0800174}
175
Tom Cherry11f12092018-08-29 21:36:28 -0700176void fb_notice(const std::string& notice) {
177 Status(notice);
178 fprintf(stderr, "\n");
Jocelyn Bohr91fefad2017-01-27 14:17:56 -0800179}
180
Tom Cherry11f12092018-08-29 21:36:28 -0700181void fb_wait_for_disconnect() {
182 fb->WaitForDisconnect();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800183}
David Anderson1d887432018-08-27 16:47:32 -0700184
185bool fb_reboot_to_userspace() {
Tom Cherry11f12092018-08-29 21:36:28 -0700186 Status("Rebooting to userspace fastboot");
David Anderson1d887432018-08-27 16:47:32 -0700187 verbose("\n");
188
189 if (fb->RebootTo("fastboot") != fastboot::RetCode::SUCCESS) {
190 fprintf(stderr, "FAILED (%s)\n", fb->Error().c_str());
191 return false;
192 }
193 fprintf(stderr, "OKAY\n");
194
David Anderson03de6452018-09-04 14:32:54 -0700195 fb_reinit(nullptr);
David Anderson1d887432018-08-27 16:47:32 -0700196 return true;
197}