All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.avsystem.anjay.AnjayFirmwareUpdateHandlers Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2020-2021 AVSystem 
 *
 * 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
 *
 *     http://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.
 */

package com.avsystem.anjay;

import com.avsystem.anjay.Anjay.CoapUdpTxParams;
import java.util.Optional;

/**
 * Handler callbacks that shall implement the platform-specific part of firmware update process.
 *
 * 

The Firmware Update object logic may be in one of the following states: * *

    *
  • Idle. This is the state in which the object is just after creation (unless * initialized with either {@link AnjayFirmwareUpdate.InitialState.InitialResult#DOWNLOADED * DOWNLOADED} or {@link AnjayFirmwareUpdate.InitialState.InitialResult#DOWNLOADING * DOWNLOADING}. The following handlers may be called in this state: *
      *
    • {@link #streamOpen streamOpen()} - shall open the download stream; moves the object * into the Downloading state *
    • {@link #getSecurityConfig} - shall fill in security info that shall be used for a * given URL *
    • {@link #reset} - shall cleanup the object state if neccessary *
    *
  • Downloading. The object might be initialized directly into this state by * using {@link AnjayFirmwareUpdate.InitialState.InitialResult#DOWNLOADING DOWNLOADING}. In * this state, the download stream is open and data may be transferred. The following handlers * may be called in this state: *
      *
    • {@link #streamWrite streamWrite()} - shall write a chunk of data into the download * stream; it normally does not change state - however, if it fails, it will be * immediately followed by a call to {@link #reset()} *
    • {@link #streamFinish()} - shall close the download stream and perform integrity check * on the downloaded image; if successful, this moves the object into the * Downloaded state. If failed - into the Idle state; note that {@link * #reset()} will NOT be called in that case *
    • {@link #reset()} - shall remove all downloaded data; moves the object into the * Idle state *
    *
  • Downloaded. The object might be initialized directly into this state by * using {@link AnjayFirmwareUpdate.InitialState.InitialResult#DOWNLOADED DOWNLOADED}. In this * state, the firmware package has been downloaded and checked and is ready to be flashed. The * following handlers may be called in this state: *
      *
    • {@link #reset()} - shall reset all downloaded data; moves the object into the * Idle state *
    • {@link #getName()} - shall return the package name, if available *
    • {@link #getVersion()} - shall return the package version, if available *
    • {@link #performUpgrade()} - shall perform the actual upgrade; if it fails, it does * not cause a state change and may be called again; upon success, it may be treated as * a transition to a "terminal" state, after which the device is expected to reboot *
    *
*/ public interface AnjayFirmwareUpdateHandlers { /** * Opens the stream that will be used to write the firmware package to. * *

The intended way of implementing this handler is to open a temporary file using or * allocate some memory buffer that may then be used to store the downloaded data in. The * library will not attempt to call {@link #streamWrite streamWrite} without having previously * called {@link #streamOpen streamOpen()}. * *

Note that this handler will NOT be called after initializing the object with the {@link * AnjayFirmwareUpdate.InitialState.InitialResult#DOWNLOADING DOWNLOADING} state, so any * necessary resources shall be already open before calling @ref {@link * AnjayFirmwareUpdate#install install()}. * * @param packageUri URI of the package from which a Pull-mode download is performed, or empty * if it is a Push-mode download. This argument may either be ignored, or persisted in * non-volatile storage if the client supports download resumption after an unexpected * reboot (see {@link AnjayFirmwareUpdate.InitialState} and its fields). * @param etag ETag of the data being downloaded in Pull mode, or empty if it is a Push-mode * download or ETags are not supported by the remote server. This argument may either be * ignored, or persisted in non-volatile storage if the client supports download resumption * after an unexpected reboot (see {@link AnjayFirmwareUpdate.InitialState} and its fields). * @throws Exception In case of failure. */ void streamOpen(Optional packageUri, Optional etag) throws Exception; /** * Writes data to the download stream. * *

May be called multipled times after {@link #streamOpen streamOpen()}, once for each * consecutive chunk of downloaded data. * * @param data Chunk of the firmware package being downloaded. Guaranteed to be non-null * . * @throws AnjayFirmwareUpdateException In case of failure. The corresponding value will be set * in the Update Result Resource. */ void streamWrite(byte[] data) throws AnjayFirmwareUpdateException; /** * Closes the download stream and prepares the firmware package to be applied. * *

Will be called after a series of {@link #streamWrite(byte[]) streamWrite()} calls after * the whole package is downloaded. * *

The intended way of implementing this handler is to e.g. close the file and perform * integrity check on it. It might also be uncompressed or decrypted as necessary, so that it is * ready to be applied. The exact split of responsibility between {@link #streamFinish()} and * {@link #performUpgrade()} is not clearly defined and up to the implementor. * *

Note that regardless of the exception thrown, the stream is considered to be closed. That * is, upon successful return, the Firmware Update object is considered to be in the * Downloaded state, and upon throwing an exception - in the Idle state. * * @throws AnjayFirmwareUpdateException In case of failure. The corresponding value will be set * in the Update Result Resource. */ void streamFinish() throws AnjayFirmwareUpdateException; /** * Resets the firmware update state and performs any applicable cleanup of temporary storage if * necessary. * *

Will be called at request of the server, or after a failed download. Note that it may be * called without previously calling {@link #streamFinish()}, so it shall also close the * currently open download stream, if any. */ void reset(); /** * Returns the name of downloaded firmware package. * *

The name will be exposed in the data model as the PkgName Resource. If this callback * returns null or is not implemented at all, that Resource will not be present in * the data model. * *

It only makes sense for this handler to return non-null values if there is a * valid package already downloaded. The library will not call this handler in any state other * than Downloaded. * * @return The callback shall return the package name, or null if it is not * currently available. */ String getName(); /** * Returns the version of downloaded firmware package. * *

The version will be exposed in the data model as the PkgVersion Resource. If this callback * returns null or is not implemented at all, that Resource will not be present in * the data model. * *

It only makes sense for this handler to return non-null values if there is a * valid package already downloaded. The library will not call this handler in any state other * than Downloaded. * * @return The callback shall return the package version, or null if it is not * currently available. */ String getVersion(); /** * Performs the actual upgrade with previously downloaded package. * *

Will be called at request of the server, after a package has been downloaded. * *

Most users will want to implement firmware update in a way that involves a reboot. In such * case, it is expected that this callback will do either one of the following: * *

    *
  • return, causing the outermost event loop to terminate, shutdown the library and then * perform the firmware upgrade and then the device to reboot *
  • perform the firmware upgrade internally and never return, causing a reboot in the * process. *
* *

After rebooting, the result of the upgrade process may be passed to the library during * initialization via the {@link AnjayFirmwareUpdate.InitialState.InitialResult InitialResult} * argument to {@link AnjayFirmwareUpdate#install install()}. * *

Alternatively, if the update can be performed without reinitializing Anjay, you can use * {@link AnjayFirmwareUpdate#setResult(Result)} (either from within the handler or some time * after returning from it) to pass the update result. * * @throws AnjayFirmwareUpdateException The callback shall throw an exception if it can be * determined without a reboot that the firmware upgrade cannot be successfully performed. * The corresponding value will be set in the Update Result Resource. */ void performUpgrade() throws AnjayFirmwareUpdateException; /** * Queries security information that shall be used for an encrypted connection with a PULL-mode * download server. * *

May be called before {@link #streamOpen} if the download is to be performed in PULL mode * and the connection needs to use TLS or DTLS encryption. * *

If this handler is not implemented at all or null is returned, Anjay will * attempt to obtain security information from Data Model (in a way equivalent to how {@link * Anjay#securityConfigFromDm} works). * * You may also use this function yourself, for example as a fallback mechanism. * * @param uri URI on which the download will be started. * @return instance of {@link AnjaySecurityConfig} or null. */ default AnjaySecurityConfig getSecurityConfig(String uri) { return null; } /** * Returns CoAP transmission parameters used to override default ones. * *

If this handler is not implemented at all or null is returned, tx params from * {@link Anjay} object are used. * * @param downloadUri Target firmware URI. * @return Object with CoAP transmission parameters. */ default CoapUdpTxParams getCoapTxParams(Optional downloadUri) { return null; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy