| // Copyright 2021 The Pigweed Authors |
| // |
| // 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 |
| // |
| // https://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. |
| syntax = "proto3"; |
| |
| package pw.software_update; |
| |
| import "pw_protobuf_protos/common.proto"; |
| import "pw_tokenizer/proto/options.proto"; |
| import "google/protobuf/any.proto"; |
| |
| message BundledUpdateState { |
| enum Enum { |
| UNKNOWN = 0; // Not an expected state in the OTA system; only for proto. |
| |
| // Valid methods in this state: Start() |
| // |
| // Transition: |
| // Start() succeeds --> TRANSFERRING |
| // Start() fails --> FINISHED |
| INACTIVE = 1; |
| |
| // Valid methods in this state: GetStatus(), Abort(). |
| // |
| // Transitions: |
| // Transfer completes --> TRANSFERRED |
| // Transfer fails --> FINISHED |
| // Abort() called --> ABORTING |
| TRANSFERRING = 2; |
| |
| // Valid methods in this state: GetStatus(), Abort(), Verify(). |
| // |
| // Transitions: |
| // Verify() called --> VERIFYING |
| // Apply() called --> VERIFYING |
| // Abort() called --> ABORTING |
| TRANSFERRED = 3; |
| |
| // Valid methods in this state: GetStatus(), Abort(). |
| // |
| // Transitions: |
| // Verifying finished --> VERIFIED |
| // Verifying failed --> FINISHED |
| // Abort() called --> ABORTING |
| VERIFYING = 4; |
| |
| // Valid methods in this state: GetStatus(), Abort(), Apply(). |
| // |
| // Transitions: |
| // Apply() called --> APPLYING |
| // Abort() called --> ABORTING |
| VERIFIED = 5; |
| |
| // Valid methods in this state: GetStatus(). |
| // |
| // Transitions: |
| // Apply() finished --> FINISHED; may require persisting across a reboot. |
| // Apply() failed --> FINISHED; with error set. |
| APPLYING = 6; |
| |
| // Valid methods in this state: GetStatus(). |
| // |
| // Transitions: |
| // Abort finishes --> FINISHED |
| // Abort fails --> FINISHED |
| ABORTING = 7; |
| |
| // Valid methods in this state: GetStatus(), Reset(). |
| // |
| // Terminal state indicating a finished update; whether successful or |
| // not. Additional termination information available in completion_state |
| // and possibly note. |
| // |
| // Transitions: |
| // Reset() succeeds --> INACTIVE |
| // Reset() fails --> FINISHED |
| FINISHED = 8; |
| } |
| } |
| |
| message BundledUpdateResult { |
| enum Enum { |
| UNKNOWN = 0; |
| SUCCESS = 1; |
| UNKNOWN_ERROR = 2; |
| ABORTED = 3; |
| TRANSFER_FAILED = 4; |
| VERIFY_FAILED = 5; |
| APPLY_FAILED = 6; |
| } |
| } |
| |
| message BundledUpdateStatus { |
| BundledUpdateState.Enum state = 1; |
| |
| optional BundledUpdateResult.Enum result = 2; |
| |
| // This is the percentage of estimated progress for the current update |
| // state in hundreths of a percent. (e.g. 5.00% = 500u) |
| optional uint32 current_state_progress_hundreth_percent = 3; |
| |
| // If present, the active transfer ID for the update. |
| optional uint32 transfer_id = 4; |
| |
| // The name of the update bundle. Not present when in INACTIVE state. This is |
| // useful for enabling resuming of transfers across reboots or disconnects, |
| // without transferring an expensive manifest. |
| optional string bundle_filename = 5; |
| |
| // Additional information related to the state may be provided here. |
| // Examples: "Failed verifying: ml_model.bin", "Flash partition couldn't be |
| // acquired and was busy", etc. Can provide more granular information than |
| // just the completion result. |
| optional bytes note = 6 [(tokenizer.format) = TOKENIZATION_OPTIONAL]; |
| |
| // Custom application data. |
| optional google.protobuf.Any extended_status = 7; |
| } |
| |
| message StartRequest { |
| // If present, the filename for the staged file. This should persist across |
| // reboots, and will be returned from GetStatus() until either the update |
| // applies or is aborted. |
| optional string bundle_filename = 1; |
| } |
| |
| // TODO(b/235273688): Add documentation and details of the API contract. |
| service BundledUpdate { |
| // TODO: Offer GetCurrentManifest & GetStagedManifest() methods that leverage |
| // pw_transfer to upload the manifest off the device, to enable host logic. |
| |
| // Get current status of software update. |
| rpc GetStatus(pw.protobuf.Empty) returns (BundledUpdateStatus); |
| |
| // Start a software update. Do any device-specific tasks needed to be ready |
| // for update. Open pw_transfer channel used for staging bundle. |
| // Returned status includes the transfer ID to use for bundle transfer. |
| // |
| // Precondition: Device update state must be INACTIVE. |
| rpc Start(StartRequest) returns (BundledUpdateStatus); |
| |
| // Manually set the bundle status as transferred. It can be used to recover |
| // a previously finished transfer or used when transfer happens on a side |
| // channel without involvement of pw_transfer |
| // |
| // Precondition: Device update state must be INACTIVE or TRANSFERRING |
| rpc SetTransferred(pw.protobuf.Empty) returns (BundledUpdateStatus); |
| |
| // Verify the bundle in the staging area. Returns immediately, but |
| // verification runs asynchronously. Poll for completion with GetStatus(). |
| // |
| // Precondition: Device update state must be TRANSFERRED. |
| rpc Verify(pw.protobuf.Empty) returns (BundledUpdateStatus); |
| |
| // Apply the staged update. The update process will verify the staged bundle |
| // or ensure that it was verified, apply the bundle, and in some cases reboot |
| // the device. During this process, the device may be slow to respond. |
| // |
| // The RPC is async; callers must fetch status with GetStatus(). |
| // |
| // Precondition: Device update state must be TRANSFERRED or VERIFIED. |
| rpc Apply(pw.protobuf.Empty) returns (BundledUpdateStatus); |
| |
| // Abort any current software update in progress. |
| // Precondition: Device update state must not be INACTIVE or FINISHED. |
| rpc Abort(pw.protobuf.Empty) returns (BundledUpdateStatus); |
| |
| // Reset after a finished update. Device goes into INACTIVE state after. |
| // |
| // Precondition: Device update state must be FINISHED. |
| rpc Reset(pw.protobuf.Empty) returns (BundledUpdateStatus); |
| } |