| /* |
| * |
| * Copyright (c) 2020 Project CHIP Authors |
| * Copyright (c) 2019 Google LLC. |
| * |
| * 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. |
| */ |
| |
| /** |
| * @file |
| * Defines the public interface for the Device Layer SoftwareUpdateManager object. |
| */ |
| |
| #pragma once |
| |
| #if CHIP_DEVICE_CONFIG_ENABLE_SOFTWARE_UPDATE_MANAGER |
| |
| #include <core/CHIPTLV.h> |
| #include <platform/internal/CHIPDeviceLayerInternal.h> |
| |
| namespace chip { |
| namespace DeviceLayer { |
| |
| using namespace chip::TLV; |
| |
| class SoftwareUpdateManagerImpl; |
| |
| class SoftwareUpdateManager |
| { |
| using ImplClass = SoftwareUpdateManagerImpl; |
| |
| public: |
| // ===== Members that define the public interface of the SoftwareUpdateManager |
| |
| enum State |
| { |
| kState_Idle = 1, |
| kState_ScheduledHoldoff = 2, |
| kState_PrepareQuery = 3, |
| kState_Query = 4, |
| kState_PrepareImageStorage = 5, |
| kState_Download = 6, |
| kState_Install = 7, |
| |
| kState_ApplicationManaged = 8, |
| |
| kState_MaxState |
| }; |
| |
| /** |
| * API events generated by the \c SoftwareUpdateManager object. |
| */ |
| enum EventType |
| { |
| /** |
| * Prepare ImageQuery message |
| * |
| * Generated when a software update check has been triggered. Provides an opportunity |
| * for the application to supply product related information to the |
| * SofwareUpdate:ImageQuery message. |
| */ |
| kEvent_PrepareQuery, |
| |
| /** |
| * Prepare meta-data for ImageQuery request |
| * |
| * Provides an opportunity for the application to append additional meta-data |
| * to the SofwareUpdate:ImageQuery message if needed. Generated when implementation |
| * is ready to get meta-data from the application. |
| */ |
| kEvent_PrepareQuery_Metadata, |
| |
| /** |
| * Error preparing an ImageQuery request |
| * |
| * Generated when the implementation encounters an error while preparing to send out |
| * a software update query. |
| */ |
| kEvent_QueryPrepareFailed, |
| |
| /** |
| * ImageQuery request has been sent |
| * |
| * Informational event to signal that a SofwareUpdate:ImageQuery message has been sent. |
| */ |
| kEvent_QuerySent, |
| |
| /** |
| * Software update is available |
| * |
| * Generated when a SofwareUpdate:ImageQueryResponse is received in response to |
| * a query containing information of the available update. |
| */ |
| kEvent_SoftwareUpdateAvailable, |
| |
| /** |
| * Fetch persisted state information for a partially downloaded image |
| * |
| * Provides an opportunity for the application to disclose information |
| * of a partial image previously downloaded so that the download |
| * may be continued from the point where it last stopped. URI of the available |
| * software update is provided as an input parameter that the application can use |
| * to compare if the image being downloaded is the same as the partial image. |
| * |
| * The application is expected to return the length of the partial image in the |
| * PartialImageLenInBytes output parameter. The application can set the value |
| * of PartialImageLenInBytes to 0 to indicate that no partial image exists or |
| * that the URI of the partial image does not match. |
| * |
| * The application may choose to ignore this event by passing it to the default |
| * event handler. If this is done, the system will always download the entirety |
| * of the available firmware image. |
| */ |
| kEvent_FetchPartialImageInfo, |
| |
| /** |
| * Prepare for storage of a new image |
| * |
| * Requests the application to perform any steps necessary to prepare local storage |
| * for the download of a new firmware image. The application can use this, for example, |
| * to erase flash pages. |
| * |
| * The PrepareImageStorage event is generated only in the case where a new firmware |
| * image is being downloaded. When a previously interrupted download is resumed, |
| * PrepareImageStorage is not generated. |
| * |
| * The application must signal completion of the prepare operation by calling the |
| * \c PrepareImageStorageComplete() method. It may do this within the event callback |
| * itself, or at a later time. If called from a task other than the chip task, |
| * the caller must hold the chip stack lock. |
| * |
| * The application can choose to ignore the PrepareImageStorage event by passing it |
| * to the default event handler. If this is done, the system automatically proceeds |
| * to the image download state. |
| * |
| * To support resuming an interrupted download, the application should persist the |
| * image URI (supplied as an event parameter), and use this when handling subsequent |
| * FetchPartialImageInfo events. |
| */ |
| kEvent_PrepareImageStorage, |
| |
| /** |
| * Image download has begun |
| * |
| * Informational event to signal the start of an image download transaction. |
| */ |
| kEvent_StartImageDownload, |
| |
| /** |
| * Store a block of image data |
| * |
| * Generated whenever a data block is received from the file download server. |
| * Parameters included with this event provide the data and the length of the data. |
| * |
| * To support resuming an interrupted download, the application should maintain a |
| * persistent count of the total number of image bytes stored, and use this value |
| * when handling subsequent FetchPartialImageInfo events. |
| */ |
| kEvent_StoreImageBlock, |
| |
| /** |
| * Compute an image integrity check value |
| * |
| * Requests the application to compute an integrity check value over the downloaded |
| * image. Generated once downloading is complete. |
| */ |
| kEvent_ComputeImageIntegrity, |
| |
| /** |
| * Reset state of partially downloaded image |
| * |
| * Requests the application to forget the persisted state associated with a downloaded |
| * image. A ResetPartialImageInfo event is generated whenever a downloaded image fails |
| * its integrity check. After a ResetPartialImageInfo event has been processed, |
| * subsequent FetchPartialImageInfo events should indicate that no partial image is |
| * available. |
| * |
| * Note that, when handling the ResetPartialImageInfo event, the application is NOT |
| * required to clear image data itself, only the state information associated with the |
| * image (i.e. the URI and partial image length). |
| * |
| * If the application does not support image download resumption, it may ignore this |
| * event by passing it to the default event handler. |
| */ |
| kEvent_ResetPartialImageInfo, |
| |
| /** |
| * Image is ready to be installed |
| * |
| * Informational event to signal that image is ready to be installed. |
| * Generated once an image passes the integrity check. |
| */ |
| kEvent_ReadyToInstall, |
| |
| /** |
| * Begin image installation |
| * |
| * Requests the application to being the process of installing a downloaded firmware |
| * image. |
| */ |
| kEvent_StartInstallImage, |
| |
| /** |
| * Software update process finished |
| * |
| * Generated when a software update check has finished with or without |
| * errors. Parameters included with this event provide the reason for failure |
| * if the attempt finished due to a failure. |
| */ |
| kEvent_Finished, |
| |
| /** |
| * Check default event handling behavior. |
| * |
| * Used to verify correct default event handling in the application. |
| * |
| * Applications must NOT handle this event. |
| */ |
| kEvent_DefaultCheck = 100, |
| |
| }; |
| |
| /** |
| * When a software update is available, the application can chose one of |
| * the following actions as part of the SoftwareUpdateAvailable API event |
| * callback. The default action will be set to kAction_Now. |
| */ |
| enum ActionType |
| { |
| /** |
| * Ignore the download completely. A kEvent_Finished API event callback will |
| * be generated with error CHIP_DEVICE_ERROR_SOFTWARE_UPDATE_CANCELLED if |
| * this option is selected and the retry logic will not be invoked. |
| */ |
| kAction_Ignore, |
| |
| /** |
| * Start the download right away. A kEvent_FetchPartialImageInfo API event |
| * callback will be generated right after. |
| */ |
| kAction_DownloadNow, |
| |
| /** |
| * Pause download on start. Scheduled software update checks (if enabled) will be suspended. |
| * State machine will remain in Download state. When ready, application can |
| * call the resume download API to proceed with download or call Abort to cancel. |
| */ |
| kAction_DownloadLater, |
| |
| /** |
| * Allows application to manage the rest of the phases of software update such as |
| * download, image integrity validation and install. Software update manager |
| * state machine will move to the ApplicationManaged state. Scheduled software update checks (if enabled) |
| * will be suspended till application calls Abort or ImageInstallComplete API. |
| */ |
| kAction_ApplicationManaged, |
| }; |
| |
| /** |
| * Incoming parameters sent with events generated directly from this component |
| * |
| */ |
| union InEventParam; |
| |
| /** |
| * Outgoing parameters sent with events generated directly from this component |
| * |
| */ |
| union OutEventParam; |
| |
| struct RetryParam |
| { |
| /** |
| * Specifies the retry attempt number. |
| * It is reset on a successful software update attempt. |
| */ |
| uint32_t NumRetries; |
| }; |
| |
| typedef void (*EventCallback)(void * apAppState, EventType aEvent, const InEventParam & aInParam, OutEventParam & aOutParam); |
| typedef void (*RetryPolicyCallback)(void * aAppState, RetryParam & aRetryParam, uint32_t & aOutIntervalMsec); |
| |
| CHIP_ERROR Abort(); |
| CHIP_ERROR CheckNow(); |
| CHIP_ERROR ImageInstallComplete(CHIP_ERROR aError); |
| CHIP_ERROR PrepareImageStorageComplete(CHIP_ERROR aError); |
| CHIP_ERROR SetEventCallback(void * aAppState, EventCallback aEventCallback); |
| CHIP_ERROR SetQueryIntervalWindow(uint32_t aMinWaitTimeMs, uint32_t aMaxWaitTimeMs); |
| |
| bool IsInProgress(); |
| |
| void SetRetryPolicyCallback(RetryPolicyCallback aRetryPolicyCallback); |
| |
| State GetState(); |
| |
| static void DefaultEventHandler(void * apAppState, EventType aEvent, const InEventParam & aInParam, OutEventParam & aOutParam); |
| |
| private: |
| // ===== Members for internal use by the following friends. |
| |
| // friend class SoftwareUpdateManagerImpl; |
| template <class> |
| friend class Internal::GenericPlatformManagerImpl; |
| |
| CHIP_ERROR Init(); |
| |
| protected: |
| // Construction/destruction limited to subclasses. |
| SoftwareUpdateManager() = default; |
| ~SoftwareUpdateManager() = default; |
| |
| // No copy, move or assignment. |
| SoftwareUpdateManager(const SoftwareUpdateManager &) = delete; |
| SoftwareUpdateManager(const SoftwareUpdateManager &&) = delete; |
| SoftwareUpdateManager & operator=(const SoftwareUpdateManager &) = delete; |
| }; |
| |
| /** |
| * Returns a reference to the public interface of the SoftwareUpdateManager singleton object. |
| * |
| * chip application should use this to access features of the SoftwareUpdateManager object |
| * that are common to all platforms. |
| */ |
| extern SoftwareUpdateManager & SoftwareUpdateMgr(); |
| |
| /** |
| * Returns the platform-specific implementation of the SoftwareUpdateManager singleton object. |
| * |
| * chip applications can use this to gain access to features of the SoftwareUpdateManager |
| * that are specific to the selected platform. |
| */ |
| extern SoftwareUpdateManagerImpl & SoftwareUpdateMgrImpl(); |
| |
| } // namespace DeviceLayer |
| } // namespace chip |
| |
| /* Include a header file containing the implementation of the SoftwareUpdateManager |
| * object for the selected platform. |
| */ |
| #ifdef EXTERNAL_SOFTWAREUPDATEMANAGERIMPL_HEADER |
| #include EXTERNAL_SOFTWAREUPDATEMANAGERIMPL_HEADER |
| #else |
| #define SOFTWAREUPDATEMANAGERIMPL_HEADER <platform/SoftwareUpdateManagerImpl.h> |
| #include SOFTWAREUPDATEMANAGERIMPL_HEADER |
| #endif |
| |
| namespace chip { |
| namespace DeviceLayer { |
| |
| using namespace chip::TLV; |
| |
| union SoftwareUpdateManager::InEventParam |
| { |
| void Clear() { memset(this, 0, sizeof(*this)); } |
| |
| SoftwareUpdateManager * Source; |
| struct |
| { |
| TLVWriter * MetaDataWriter; |
| } PrepareQuery_Metadata; |
| |
| struct |
| { |
| CHIP_ERROR Error; |
| } QueryPrepareFailed; |
| |
| struct |
| { |
| uint8_t IntegrityType; |
| const char * URI; |
| const char * Version; |
| } SoftwareUpdateAvailable; |
| |
| struct |
| { |
| const char * URI; |
| } FetchPartialImageInfo; |
| |
| struct |
| { |
| const char * URI; |
| uint8_t IntegrityType; |
| } PrepareImageStorage; |
| |
| struct |
| { |
| uint8_t * DataBlock; |
| uint32_t DataBlockLen; |
| } StoreImageBlock; |
| |
| struct |
| { |
| uint8_t IntegrityType; |
| uint8_t * IntegrityValueBuf; // Pointer to the buffer for the app to copy Integrity Value into. |
| uint8_t IntegrityValueBufLen; // Length of the provided buffer. |
| } ComputeImageIntegrity; |
| |
| struct |
| { |
| CHIP_ERROR Error; |
| } Finished; |
| }; |
| |
| union SoftwareUpdateManager::OutEventParam |
| { |
| void Clear() { memset(this, 0, sizeof(*this)); } |
| |
| bool DefaultHandlerCalled; |
| struct |
| { |
| const char * PackageSpecification; |
| const char * DesiredLocale; |
| CHIP_ERROR Error; |
| } PrepareQuery; |
| |
| struct |
| { |
| CHIP_ERROR Error; |
| } PrepareQuery_Metadata; |
| |
| struct |
| { |
| ActionType Action; |
| } SoftwareUpdateAvailable; |
| |
| struct |
| { |
| uint64_t PartialImageLen; |
| } FetchPartialImageInfo; |
| |
| struct |
| { |
| CHIP_ERROR Error; |
| } StoreImageBlock; |
| |
| struct |
| { |
| CHIP_ERROR Error; |
| } ComputeImageIntegrity; |
| }; |
| |
| inline CHIP_ERROR SoftwareUpdateManager::Init() |
| { |
| return static_cast<ImplClass *>(this)->_Init(); |
| } |
| |
| inline CHIP_ERROR SoftwareUpdateManager::CheckNow() |
| { |
| return static_cast<ImplClass *>(this)->_CheckNow(); |
| } |
| |
| inline CHIP_ERROR SoftwareUpdateManager::ImageInstallComplete(CHIP_ERROR aError) |
| { |
| return static_cast<ImplClass *>(this)->_ImageInstallComplete(aError); |
| } |
| |
| inline CHIP_ERROR SoftwareUpdateManager::PrepareImageStorageComplete(CHIP_ERROR aError) |
| { |
| return static_cast<ImplClass *>(this)->_PrepareImageStorageComplete(aError); |
| } |
| |
| inline SoftwareUpdateManager::State SoftwareUpdateManager::GetState() |
| { |
| return static_cast<ImplClass *>(this)->_GetState(); |
| } |
| |
| inline CHIP_ERROR SoftwareUpdateManager::Abort() |
| { |
| return static_cast<ImplClass *>(this)->_Abort(); |
| } |
| |
| inline bool SoftwareUpdateManager::IsInProgress() |
| { |
| return static_cast<ImplClass *>(this)->_IsInProgress(); |
| } |
| |
| inline CHIP_ERROR SoftwareUpdateManager::SetQueryIntervalWindow(uint32_t aMinRangeSecs, uint32_t aMaxRangeSecs) |
| { |
| return static_cast<ImplClass *>(this)->_SetQueryIntervalWindow(aMinRangeSecs, aMaxRangeSecs); |
| } |
| |
| inline void SoftwareUpdateManager::SetRetryPolicyCallback(const RetryPolicyCallback aRetryPolicyCallback) |
| { |
| static_cast<ImplClass *>(this)->_SetRetryPolicyCallback(aRetryPolicyCallback); |
| } |
| |
| inline CHIP_ERROR SoftwareUpdateManager::SetEventCallback(void * const aAppState, const EventCallback aEventCallback) |
| { |
| return static_cast<ImplClass *>(this)->_SetEventCallback(aAppState, aEventCallback); |
| } |
| |
| inline void SoftwareUpdateManager::DefaultEventHandler(void * apAppState, EventType aEvent, const InEventParam & aInParam, |
| OutEventParam & aOutParam) |
| { |
| ImplClass::_DefaultEventHandler(apAppState, aEvent, aInParam, aOutParam); |
| } |
| |
| } // namespace DeviceLayer |
| } // namespace chip |
| |
| #endif // CHIP_DEVICE_CONFIG_ENABLE_SOFTWARE_UPDATE_MANAGER |