blob: 087d7cfbf82b423117ba197a8333774b56981ee0 [file] [log] [blame]
Tao Baoc3901232018-05-21 16:05:56 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
Tao Bao6a7e4af2018-06-14 21:57:43 -070019#include <ostream>
Tao Baoc3901232018-05-21 16:05:56 -070020#include <string>
Tao Bao6a7e4af2018-06-14 21:57:43 -070021#include <vector>
Tao Baoc3901232018-05-21 16:05:56 -070022
Tao Bao6a7e4af2018-06-14 21:57:43 -070023#include <gtest/gtest_prod.h> // FRIEND_TEST
24
25#include "otautil/rangeset.h"
26
27// Represents the target info used in a Command. TargetInfo contains the ranges of the blocks and
28// the expected hash.
29class TargetInfo {
30 public:
31 TargetInfo() = default;
32
33 TargetInfo(std::string hash, RangeSet ranges)
34 : hash_(std::move(hash)), ranges_(std::move(ranges)) {}
35
36 const std::string& hash() const {
37 return hash_;
38 }
39
40 const RangeSet& ranges() const {
41 return ranges_;
42 }
43
44 size_t blocks() const {
45 return ranges_.blocks();
46 }
47
48 bool operator==(const TargetInfo& other) const {
49 return hash_ == other.hash_ && ranges_ == other.ranges_;
50 }
51
52 private:
53 friend std::ostream& operator<<(std::ostream& os, const TargetInfo& source);
54
55 // The hash of the data represented by the object.
56 std::string hash_;
57 // The block ranges that the data should be written to.
58 RangeSet ranges_;
59};
60
61std::ostream& operator<<(std::ostream& os, const TargetInfo& source);
62
63// Represents the stash info used in a Command.
64class StashInfo {
65 public:
66 StashInfo() = default;
67
68 StashInfo(std::string id, RangeSet ranges) : id_(std::move(id)), ranges_(std::move(ranges)) {}
69
70 size_t blocks() const {
71 return ranges_.blocks();
72 }
73
74 const std::string& id() const {
75 return id_;
76 }
77
78 const RangeSet& ranges() const {
79 return ranges_;
80 }
81
82 bool operator==(const StashInfo& other) const {
83 return id_ == other.id_ && ranges_ == other.ranges_;
84 }
85
86 private:
87 friend std::ostream& operator<<(std::ostream& os, const StashInfo& stash);
88
89 // The id (i.e. hash) of the stash.
90 std::string id_;
91 // The matching location of the stash.
92 RangeSet ranges_;
93};
94
95std::ostream& operator<<(std::ostream& os, const StashInfo& stash);
96
97// Represents the source info in a Command, whose data could come from source image, stashed blocks,
98// or both.
99class SourceInfo {
100 public:
101 SourceInfo() = default;
102
103 SourceInfo(std::string hash, RangeSet ranges, RangeSet location, std::vector<StashInfo> stashes)
104 : hash_(std::move(hash)),
105 ranges_(std::move(ranges)),
106 location_(std::move(location)),
107 stashes_(std::move(stashes)) {
108 blocks_ = ranges_.blocks();
109 for (const auto& stash : stashes_) {
110 blocks_ += stash.ranges().blocks();
111 }
112 }
113
114 const std::string& hash() const {
115 return hash_;
116 }
117
118 size_t blocks() const {
119 return blocks_;
120 }
121
122 bool operator==(const SourceInfo& other) const {
123 return hash_ == other.hash_ && ranges_ == other.ranges_ && location_ == other.location_ &&
124 stashes_ == other.stashes_;
125 }
126
127 private:
128 friend std::ostream& operator<<(std::ostream& os, const SourceInfo& source);
129
130 // The hash of the data represented by the object.
131 std::string hash_;
132 // The block ranges from the source image to read data from. This could be a subset of all the
133 // blocks represented by the object, or empty if all the data should be loaded from stash.
134 RangeSet ranges_;
135 // The location in the buffer to load ranges_ into. Empty if ranges_ alone covers all the blocks
136 // (i.e. nothing needs to be loaded from stash).
137 RangeSet location_;
138 // The info for the stashed blocks that are part of the source. Empty if there's none.
139 std::vector<StashInfo> stashes_;
140 // Total number of blocks represented by the object.
141 size_t blocks_{ 0 };
142};
143
144std::ostream& operator<<(std::ostream& os, const SourceInfo& source);
145
146class PatchInfo {
147 public:
148 PatchInfo() = default;
149
150 PatchInfo(size_t offset, size_t length) : offset_(offset), length_(length) {}
151
152 size_t offset() const {
153 return offset_;
154 }
155
156 size_t length() const {
157 return length_;
158 }
159
160 bool operator==(const PatchInfo& other) const {
161 return offset_ == other.offset_ && length_ == other.length_;
162 }
163
164 private:
165 size_t offset_{ 0 };
166 size_t length_{ 0 };
167};
168
169// Command class holds the info for an update command that performs block-based OTA (BBOTA). Each
170// command consists of one or several args, namely TargetInfo, SourceInfo, StashInfo and PatchInfo.
171// The currently used BBOTA version is v4.
172//
173// zero <tgt_ranges>
174// - Fill the indicated blocks with zeros.
175// - Meaningful args: TargetInfo
176//
177// new <tgt_ranges>
178// - Fill the blocks with data read from the new_data file.
179// - Meaningful args: TargetInfo
180//
181// erase <tgt_ranges>
182// - Mark the given blocks as empty.
183// - Meaningful args: TargetInfo
184//
185// move <hash> <...>
186// - Read the source blocks, write result to target blocks.
187// - Meaningful args: TargetInfo, SourceInfo
188//
189// See the note below for <...>.
190//
191// bsdiff <patchstart> <patchlen> <srchash> <dsthash> <...>
192// imgdiff <patchstart> <patchlen> <srchash> <dsthash> <...>
193// - Read the source blocks, apply a patch, and write result to target blocks.
194// - Meaningful args: PatchInfo, TargetInfo, SourceInfo
195//
196// It expects <...> in one of the following formats:
197//
198// <tgt_ranges> <src_block_count> - <[stash_id:stash_location] ...>
199// (loads data from stashes only)
200//
201// <tgt_ranges> <src_block_count> <src_ranges>
202// (loads data from source image only)
203//
204// <tgt_ranges> <src_block_count> <src_ranges> <src_ranges_location>
205// <[stash_id:stash_location] ...>
206// (loads data from both of source image and stashes)
207//
208// stash <stash_id> <src_ranges>
209// - Load the given source blocks and stash the data in the given slot of the stash table.
210// - Meaningful args: StashInfo
211//
212// free <stash_id>
213// - Free the given stash data.
214// - Meaningful args: StashInfo
215//
Tao Bao91a649a2018-05-21 16:05:56 -0700216// abort
217// - Abort the current update. Allowed for testing code only.
218//
Tao Bao6a7e4af2018-06-14 21:57:43 -0700219class Command {
220 public:
Tao Baoc3901232018-05-21 16:05:56 -0700221 enum class Type {
Tao Bao91a649a2018-05-21 16:05:56 -0700222 ABORT,
Tao Baoc3901232018-05-21 16:05:56 -0700223 BSDIFF,
Tao Bao6a7e4af2018-06-14 21:57:43 -0700224 ERASE,
Tao Baoc3901232018-05-21 16:05:56 -0700225 FREE,
Tao Bao6a7e4af2018-06-14 21:57:43 -0700226 IMGDIFF,
227 MOVE,
228 NEW,
229 STASH,
230 ZERO,
Tao Baoc3901232018-05-21 16:05:56 -0700231 LAST, // Not a valid type.
232 };
233
Tao Bao6a7e4af2018-06-14 21:57:43 -0700234 Command() = default;
235
236 Command(Type type, size_t index, std::string cmdline, PatchInfo patch, TargetInfo target,
237 SourceInfo source, StashInfo stash)
238 : type_(type),
239 index_(index),
240 cmdline_(std::move(cmdline)),
241 patch_(std::move(patch)),
242 target_(std::move(target)),
243 source_(std::move(source)),
244 stash_(std::move(stash)) {}
245
246 // Parses the given command 'line' into a Command object and returns it. The 'index' is specified
247 // by the caller to index the object. On parsing error, it returns an empty Command object that
248 // evaluates to false, and the specific error message will be set in 'err'.
249 static Command Parse(const std::string& line, size_t index, std::string* err);
250
251 // Parses the command type from the given string.
Tao Baoc3901232018-05-21 16:05:56 -0700252 static Type ParseType(const std::string& type_str);
Tao Bao6a7e4af2018-06-14 21:57:43 -0700253
254 Type type() const {
255 return type_;
256 }
257
258 size_t index() const {
259 return index_;
260 }
261
262 const std::string& cmdline() const {
263 return cmdline_;
264 }
265
266 const PatchInfo& patch() const {
267 return patch_;
268 }
269
270 const TargetInfo& target() const {
271 return target_;
272 }
273
274 const SourceInfo& source() const {
275 return source_;
276 }
277
278 const StashInfo& stash() const {
279 return stash_;
280 }
281
282 constexpr explicit operator bool() const {
283 return type_ != Type::LAST;
284 }
285
286 private:
Tao Bao91a649a2018-05-21 16:05:56 -0700287 friend class ResumableUpdaterTest;
288 friend class UpdaterTest;
289
290 FRIEND_TEST(CommandsTest, Parse_ABORT_Allowed);
291 FRIEND_TEST(CommandsTest, Parse_InvalidNumberOfArgs);
Tao Bao6a7e4af2018-06-14 21:57:43 -0700292 FRIEND_TEST(CommandsTest, ParseTargetInfoAndSourceInfo_InvalidInput);
293 FRIEND_TEST(CommandsTest, ParseTargetInfoAndSourceInfo_StashesOnly);
294 FRIEND_TEST(CommandsTest, ParseTargetInfoAndSourceInfo_SourceBlocksAndStashes);
295 FRIEND_TEST(CommandsTest, ParseTargetInfoAndSourceInfo_SourceBlocksOnly);
296
297 // Parses the target and source info from the given 'tokens' vector. Saves the parsed info into
298 // 'target' and 'source' objects. Returns the parsing result. Error message will be set in 'err'
299 // on parsing error, and the contents in 'target' and 'source' will be undefined.
300 static bool ParseTargetInfoAndSourceInfo(const std::vector<std::string>& tokens,
301 const std::string& tgt_hash, TargetInfo* target,
302 const std::string& src_hash, SourceInfo* source,
303 std::string* err);
304
Tao Bao91a649a2018-05-21 16:05:56 -0700305 // Allows parsing ABORT command, which should be used for testing purpose only.
306 static bool abort_allowed_;
307
Tao Bao6a7e4af2018-06-14 21:57:43 -0700308 // The type of the command.
309 Type type_{ Type::LAST };
310 // The index of the Command object, which is specified by the caller.
311 size_t index_{ 0 };
312 // The input string that the Command object is parsed from.
313 std::string cmdline_;
314 // The patch info. Only meaningful for BSDIFF and IMGDIFF commands.
315 PatchInfo patch_;
316 // The target info, where the command should be written to.
317 TargetInfo target_;
318 // The source info to load the source blocks for the command.
319 SourceInfo source_;
320 // The stash info. Only meaningful for STASH and FREE commands. Note that although SourceInfo may
321 // also load data from stash, such info will be owned and managed by SourceInfo (i.e. in source_).
322 StashInfo stash_;
Tao Baoc3901232018-05-21 16:05:56 -0700323};
Tao Bao6a7e4af2018-06-14 21:57:43 -0700324
325std::ostream& operator<<(std::ostream& os, const Command& command);