1 // Copyright 2021 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 #pragma once 15 16 #include "pw_protobuf/message.h" 17 #include "pw_result/result.h" 18 #include "pw_stream/stream.h" 19 20 namespace pw::software_update { 21 // ManifestAccessor exposes manifest information from either a *verified* update 22 // bundle (`message UpdateBundle`) or a *trusted* on-device manifest 23 // (`message Manifest`). 24 // 25 // Instantiation MUST go-through the UpdateBundleAccessor class. e.g.: 26 // 27 // ManifestAccessor manifest = bundle.GetManifest(); 28 // PW_TRY(manifest.status()); // Fails if `bundle` is not yet verified. 29 class ManifestAccessor { 30 public: 31 ManifestAccessor() = default; 32 status()33 Status status() { return targets_metadata_.status(); } ok()34 bool ok() { return status().ok(); } 35 36 // Retrieves the "user manifest" blob, which is product specific and optional. GetUserManifest()37 pw::stream::IntervalReader GetUserManifest() { 38 return user_manifest_.GetBytesReader(); 39 } 40 41 // Enumerates all target files as a list of `message TargetFile{...}`. 42 protobuf::RepeatedMessages GetTargetFiles(); 43 44 // Given a name, return a `message TargetFile{...}` descriptor. 45 protobuf::Message GetTargetFile(protobuf::String name); 46 protobuf::Message GetTargetFile(std::string_view name); 47 48 // Returns the manifest version number. 49 protobuf::Uint32 GetVersion(); 50 51 // TODO(alizhang): Deprecate WriteManifest() once backend code has changed 52 // to UpdateBundleAccessor::PersistManifest() where the backend is given 53 // chances to prepare and release the manifest writer. WriteManifest(stream::Writer & writer)54 Status WriteManifest(stream::Writer& writer) { return Export(writer); } 55 56 private: 57 friend class UpdateBundleAccessor; 58 59 protobuf::Message targets_metadata_; 60 protobuf::Bytes user_manifest_; 61 ManifestAccessor(Status status)62 ManifestAccessor(Status status) : targets_metadata_(status) {} ManifestAccessor(protobuf::Message targets_metadata,protobuf::Bytes user_manifest)63 ManifestAccessor(protobuf::Message targets_metadata, 64 protobuf::Bytes user_manifest) 65 : targets_metadata_(targets_metadata), user_manifest_(user_manifest) {} 66 67 // Constructs a `ManifestAccessor` from an update bundle. 68 static ManifestAccessor FromBundle(protobuf::Message bundle); 69 70 // Constructs a `ManifestAccessor` from a saved `message Manifest{...}`. 71 static ManifestAccessor FromManifest(protobuf::Message manifest); 72 73 // Exports a serialized `message Manifest{...}`. 74 Status Export(stream::Writer& writer); 75 }; 76 77 } // namespace pw::software_update 78