/** * @license * Copyright 2022-2026 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ import { AsyncObservable, Bytes, CancelablePromise, Duration, MaybePromise, Timer } from "@matter/general"; import { OtaImageHeader, PersistedFileDesignator } from "@matter/protocol"; import { OtaSoftwareUpdateProvider } from "@matter/types/clusters/ota-software-update-provider"; import { OtaSoftwareUpdateRequestor } from "@matter/types/clusters/ota-software-update-requestor"; import { OtaSoftwareUpdateRequestorBehavior } from "./OtaSoftwareUpdateRequestorBehavior.js"; export interface ProviderLocation extends OtaSoftwareUpdateRequestor.ProviderLocation { } export interface ActiveProviderLocation { location: ProviderLocation; previousQueryTimestamp: number | null; metadataForNode?: Bytes; } export interface UpdateInProgressDetails { newSoftwareVersion: number; location?: ProviderLocation; updateToken?: Bytes; } /** * This is the default server implementation of {@link OtaSoftwareUpdateRequestorBehavior}. * * To use OTA updates for matter.js based devices, you need to implement "applying the update" yourself! * The default implementation provides anything needed to check for updates and transfer new updates, according to the * Matter specification, but applying the update is too specific to your use case and the environment where the device * is used. * * The following custom state attributes are available to configure the behavior of the cluster: * * {@link updateQueryInterval}: Interval to check for updates, default: 24h as defined in Matter specification * * * {@link transferProtocolsSupported}: List of Transfer protocols that are announced as supported. By default, we only * export BDX; we also support HTTPS (but basically no one else) * * * {@link canConsent}: Can the node request consent from the user for the update itself? Default is set to true, and the * controller needs to take care to get the necessary consent when calling {@link requestUserConsent}. * * * {@link downloadLocation}: Option to provide a custom storage location (also backed by an own Storage solution) to store * the received update file in. If not provided, a default location is used. * * * For this the following extension points exist that need to be implemented: * * {@link requestUserConsent}: This method is needed to be implemented when you set {@link canConsent} to true and needs to * implement user consent gathering. * * * {@link applyUpdate}: The method is called with the new SoftwareVersion and the PersistedFileDescriptor where a downloaded * update is placed and needs to trigger the update process including shutdown and restart of the node and also * sending "bootReason" event after the update! * * * {@link validateUpdateFile}: This method in default implementation reads the received OTA file and validates header and * checksums and basic details. Override this method and use this.getDownloadLocation() for access if any custom * validations are needed */ export declare class OtaSoftwareUpdateRequestorServer extends OtaSoftwareUpdateRequestorBehavior { #private; protected internal: OtaSoftwareUpdateRequestorServer.Internal; readonly state: OtaSoftwareUpdateRequestorServer.State; readonly events: OtaSoftwareUpdateRequestorServer.Events; static readonly schema: import("@matter/model").ClusterModel; initialize(): Promise; getDownloadLocation(): Promise; /** * Default implementation for the announceOtaProvider command. * A Node announced itself as OTA Update Provider, so schedule an update check with it. * Depending on the announcementReason, we schedule the update query earlier with this provider or wait for the * next regular check. */ announceOtaProvider({ providerNodeId, vendorId, announcementReason, metadataForNode, endpoint }: OtaSoftwareUpdateRequestor.AnnounceOtaProviderRequest): Promise; /** * Validate the update file * The default implementation does basic validations based on the matter OTA file format and expected software * version. * The method SHALL be overridden to add additional checks like validating the signature of the file. * throws an error if the file is invalid */ protected validateUpdateFile(newSoftwareVersion?: number): Promise; protected applyUpdate(_newSoftwareVersion: number, _fileDesignator: PersistedFileDesignator): MaybePromise; protected requestUserConsent(_newSoftwareVersion: number, _newSoftwareVersionString: string): MaybePromise; [Symbol.asyncDispose](): Promise; } export declare namespace OtaSoftwareUpdateRequestorServer { class State extends OtaSoftwareUpdateRequestorBehavior.State { /** * The list of OTA providers that were recently active (by announcement or by being used). * The error counter is increased when a provider could not be reached or returned an unexpected error. * After 3 errors the provider is removed from this list and also from the defaultProviders list. * This value is persisted. */ activeOtaProviders: ActiveProviderLocation[]; /** * Details of an upgrade in progress that is checked on restart if the upgrade was successful. * This value is persisted. */ updateInProgressDetails: UpdateInProgressDetails | null; /** How often to query for updates. Default is 24 hours ("daily") as proposed by spec. */ updateQueryInterval: Duration; /** * The transfer protocols supported by this requestor. Default is BDX Synchronous. * If it was verified that the node really have access to the public internet, HTTPS can be added as protocol * as well. */ transferProtocolsSupported: OtaSoftwareUpdateProvider.DownloadProtocol[]; /** * If true the requestor is able to get user consent for an update. This requires the implementation of the * requestUserConsent() extension interface method. * If false the OTA provider will only provide updates that do not require user consent or where user consent * was already given. * Default is false. */ canConsent: boolean; /** * Optional custom persisted location as PersistedFileDescriptor to store the downloaded update files. * If not provided, the default storage context for "bdx" of the node is used with a filename like * "ota-{vendorId}-{productId}.update". * This can be used to store the files in a different persistent storage if needed. */ downloadLocation?: PersistedFileDesignator; } class Events extends OtaSoftwareUpdateRequestorBehavior.Events { /** Emitted when a new software update file was downloaded and should now be applied. */ updateReadyToApply: AsyncObservable; } class Internal { /** Timer for the next update query */ updateQueryTimer: Timer | undefined; /** * The preferred provider to use for the next update query. * Mainly used for the Busy case to reuse the same provider for the next try. */ selectedProviderLocation?: ProviderLocation; /** How often we already retried to connect to the current provider */ providerRetryCount: number; /** * Stores the time of a current update delay to allow cancelling it */ updateDelayPromise: CancelablePromise | undefined; /** * Persisted location as PersistedFileDescriptor to store the downloaded update files. * It is initialized from the state or with an internal default on startup. */ downloadLocation: PersistedFileDesignator; } const ExtensionInterface: { requestUserConsent(newSoftwareVersion: number, newSoftwareVersionString: string): MaybePromise; applyUpdate(newSoftwareVersion: number, fileDesignator: PersistedFileDesignator): MaybePromise; validateUpdateFile(newSoftwareVersion?: number): MaybePromise; }; } //# sourceMappingURL=OtaSoftwareUpdateRequestorServer.d.ts.map