blob: 697e3dd410697d23262bce4060c58052941cd199 [file] [log] [blame]
// 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(pwbug/478): 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);
}