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. 14syntax = "proto3"; 15 16package pw.software_update; 17 18import "google/protobuf/any.proto"; 19import "pw_protobuf_protos/common.proto"; 20import "pw_tokenizer_proto/options.proto"; 21 22option java_multiple_files = true; 23option java_package = "dev.pigweed.pw_software_update"; 24 25message BundledUpdateState { 26 enum Enum { 27 UNKNOWN = 0; // Not an expected state in the OTA system; only for proto. 28 29 // Valid methods in this state: Start() 30 // 31 // Transition: 32 // Start() succeeds --> TRANSFERRING 33 // Start() fails --> FINISHED 34 INACTIVE = 1; 35 36 // Valid methods in this state: GetStatus(), Abort(). 37 // 38 // Transitions: 39 // Transfer completes --> TRANSFERRED 40 // Transfer fails --> FINISHED 41 // Abort() called --> ABORTING 42 TRANSFERRING = 2; 43 44 // Valid methods in this state: GetStatus(), Abort(), Verify(). 45 // 46 // Transitions: 47 // Verify() called --> VERIFYING 48 // Apply() called --> VERIFYING 49 // Abort() called --> ABORTING 50 TRANSFERRED = 3; 51 52 // Valid methods in this state: GetStatus(), Abort(). 53 // 54 // Transitions: 55 // Verifying finished --> VERIFIED 56 // Verifying failed --> FINISHED 57 // Abort() called --> ABORTING 58 VERIFYING = 4; 59 60 // Valid methods in this state: GetStatus(), Abort(), Apply(). 61 // 62 // Transitions: 63 // Apply() called --> APPLYING 64 // Abort() called --> ABORTING 65 VERIFIED = 5; 66 67 // Valid methods in this state: GetStatus(). 68 // 69 // Transitions: 70 // Apply() finished --> FINISHED; may require persisting across a reboot. 71 // Apply() failed --> FINISHED; with error set. 72 APPLYING = 6; 73 74 // Valid methods in this state: GetStatus(). 75 // 76 // Transitions: 77 // Abort finishes --> FINISHED 78 // Abort fails --> FINISHED 79 ABORTING = 7; 80 81 // Valid methods in this state: GetStatus(), Reset(). 82 // 83 // Terminal state indicating a finished update; whether successful or 84 // not. Additional termination information available in completion_state 85 // and possibly note. 86 // 87 // Transitions: 88 // Reset() succeeds --> INACTIVE 89 // Reset() fails --> FINISHED 90 FINISHED = 8; 91 } 92} 93 94message BundledUpdateResult { 95 enum Enum { 96 UNKNOWN = 0; 97 SUCCESS = 1; 98 UNKNOWN_ERROR = 2; 99 ABORTED = 3; 100 TRANSFER_FAILED = 4; 101 VERIFY_FAILED = 5; 102 APPLY_FAILED = 6; 103 } 104} 105 106message BundledUpdateStatus { 107 BundledUpdateState.Enum state = 1; 108 109 optional BundledUpdateResult.Enum result = 2; 110 111 // This is the percentage of estimated progress for the current update 112 // state in hundreths of a percent. (e.g. 5.00% = 500u) 113 optional uint32 current_state_progress_hundreth_percent = 3; 114 115 // If present, the active transfer ID for the update. 116 optional uint32 transfer_id = 4; 117 118 // The name of the update bundle. Not present when in INACTIVE state. This is 119 // useful for enabling resuming of transfers across reboots or disconnects, 120 // without transferring an expensive manifest. 121 optional string bundle_filename = 5; 122 123 // Additional information related to the state may be provided here. 124 // Examples: "Failed verifying: ml_model.bin", "Flash partition couldn't be 125 // acquired and was busy", etc. Can provide more granular information than 126 // just the completion result. 127 optional bytes note = 6 [(tokenizer.format) = TOKENIZATION_OPTIONAL]; 128 129 // Custom application data. 130 optional google.protobuf.Any extended_status = 7; 131} 132 133message StartRequest { 134 // If present, the filename for the staged file. This should persist across 135 // reboots, and will be returned from GetStatus() until either the update 136 // applies or is aborted. 137 optional string bundle_filename = 1; 138} 139 140// TODO: b/235273688 - Add documentation and details of the API contract. 141service BundledUpdate { 142 // TODO(keir): Offer GetCurrentManifest & GetStagedManifest() methods that 143 // leverage pw_transfer to upload the manifest off the device, to enable host 144 // logic. 145 146 // Get current status of software update. 147 rpc GetStatus(pw.protobuf.Empty) returns (BundledUpdateStatus); 148 149 // Start a software update. Do any device-specific tasks needed to be ready 150 // for update. Open pw_transfer channel used for staging bundle. 151 // Returned status includes the transfer ID to use for bundle transfer. 152 // 153 // Precondition: Device update state must be INACTIVE. 154 rpc Start(StartRequest) returns (BundledUpdateStatus); 155 156 // Manually set the bundle status as transferred. It can be used to recover 157 // a previously finished transfer or used when transfer happens on a side 158 // channel without involvement of pw_transfer 159 // 160 // Precondition: Device update state must be INACTIVE or TRANSFERRING 161 rpc SetTransferred(pw.protobuf.Empty) returns (BundledUpdateStatus); 162 163 // Verify the bundle in the staging area. Returns immediately, but 164 // verification runs asynchronously. Poll for completion with GetStatus(). 165 // 166 // Precondition: Device update state must be TRANSFERRED. 167 rpc Verify(pw.protobuf.Empty) returns (BundledUpdateStatus); 168 169 // Apply the staged update. The update process will verify the staged bundle 170 // or ensure that it was verified, apply the bundle, and in some cases reboot 171 // the device. During this process, the device may be slow to respond. 172 // 173 // The RPC is async; callers must fetch status with GetStatus(). 174 // 175 // Precondition: Device update state must be TRANSFERRED or VERIFIED. 176 rpc Apply(pw.protobuf.Empty) returns (BundledUpdateStatus); 177 178 // Abort any current software update in progress. 179 // Precondition: Device update state must not be INACTIVE or FINISHED. 180 rpc Abort(pw.protobuf.Empty) returns (BundledUpdateStatus); 181 182 // Reset after a finished update. Device goes into INACTIVE state after. 183 // 184 // Precondition: Device update state must be FINISHED. 185 rpc Reset(pw.protobuf.Empty) returns (BundledUpdateStatus); 186} 187