| /* |
| * |
| * Copyright (c) 2019 Google LLC. |
| * All rights reserved. |
| * |
| * 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. |
| */ |
| |
| #ifndef SOFTWARE_UPDATE_MANAGER_H |
| #define SOFTWARE_UPDATE_MANAGER_H |
| |
| #if WEAVE_DEVICE_CONFIG_ENABLE_SOFTWARE_UPDATE_MANAGER |
| |
| #include <Weave/Profiles/software-update/SoftwareUpdateProfile.h> |
| #include <Weave/DeviceLayer/internal/WeaveDeviceLayerInternal.h> |
| |
| namespace nl { |
| namespace Weave { |
| namespace DeviceLayer { |
| |
| class SoftwareUpdateManagerImpl; |
| |
| class SoftwareUpdateManager |
| { |
| typedef ::nl::Weave::TLV::TLVWriter TLVWriter; |
| typedef ::nl::Weave::Profiles::SoftwareUpdate::UpdatePriority UpdatePriority; |
| typedef ::nl::Weave::Profiles::SoftwareUpdate::UpdateCondition UpdateCondition; |
| |
| 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 Weave task, |
| * the caller must hold the Weave 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 WEAVE_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); |
| |
| WEAVE_ERROR Abort(void); |
| WEAVE_ERROR CheckNow(void); |
| WEAVE_ERROR ImageInstallComplete(WEAVE_ERROR aError); |
| WEAVE_ERROR PrepareImageStorageComplete(WEAVE_ERROR aError); |
| WEAVE_ERROR SetEventCallback(void * const aAppState, const EventCallback aEventCallback); |
| WEAVE_ERROR SetQueryIntervalWindow(uint32_t aMinWaitTimeMs, uint32_t aMaxWaitTimeMs); |
| |
| bool IsInProgress(void); |
| |
| void SetRetryPolicyCallback(const RetryPolicyCallback aRetryPolicyCallback); |
| |
| State GetState(void); |
| |
| 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; |
| |
| WEAVE_ERROR Init(void); |
| |
| 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. |
| * |
| * Weave application should use this to access features of the SoftwareUpdateManager object |
| * that are common to all platforms. |
| */ |
| extern SoftwareUpdateManager & SoftwareUpdateMgr(void); |
| |
| /** |
| * Returns the platform-specific implementation of the SoftwareUpdateManager singleton object. |
| * |
| * Weave applications can use this to gain access to features of the SoftwareUpdateManager |
| * that are specific to the selected platform. |
| */ |
| extern SoftwareUpdateManagerImpl & SoftwareUpdateMgrImpl(void); |
| |
| } // namespace DeviceLayer |
| } // namespace Weave |
| } // namespace nl |
| |
| /* 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 <Weave/DeviceLayer/WEAVE_DEVICE_LAYER_TARGET/SoftwareUpdateManagerImpl.h> |
| #include SOFTWAREUPDATEMANAGERIMPL_HEADER |
| #endif |
| |
| namespace nl { |
| namespace Weave { |
| namespace DeviceLayer { |
| |
| union SoftwareUpdateManager::InEventParam |
| { |
| void Clear(void) { memset(this, 0, sizeof(*this)); } |
| |
| SoftwareUpdateManager * Source; |
| struct |
| { |
| TLVWriter * MetaDataWriter; |
| } PrepareQuery_Metadata; |
| |
| struct |
| { |
| WEAVE_ERROR Error; |
| Profiles::StatusReporting::StatusReport *StatusReport; |
| } QueryPrepareFailed; |
| |
| struct |
| { |
| UpdatePriority Priority; |
| UpdateCondition Condition; |
| 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 |
| { |
| WEAVE_ERROR Error; |
| Profiles::StatusReporting::StatusReport *StatusReport; |
| } Finished; |
| }; |
| |
| union SoftwareUpdateManager::OutEventParam |
| { |
| void Clear(void) { memset(this, 0, sizeof(*this)); } |
| |
| bool DefaultHandlerCalled; |
| struct |
| { |
| const char *PackageSpecification; |
| const char *DesiredLocale; |
| WEAVE_ERROR Error; |
| } PrepareQuery; |
| |
| struct |
| { |
| WEAVE_ERROR Error; |
| } PrepareQuery_Metadata; |
| |
| struct |
| { |
| ActionType Action; |
| } SoftwareUpdateAvailable; |
| |
| struct |
| { |
| uint64_t PartialImageLen; |
| } FetchPartialImageInfo; |
| |
| struct |
| { |
| WEAVE_ERROR Error; |
| } StoreImageBlock; |
| |
| struct |
| { |
| WEAVE_ERROR Error; |
| } ComputeImageIntegrity; |
| }; |
| |
| inline WEAVE_ERROR SoftwareUpdateManager::Init(void) |
| { |
| return static_cast<ImplClass*>(this)->_Init(); |
| } |
| |
| inline WEAVE_ERROR SoftwareUpdateManager::CheckNow(void) |
| { |
| return static_cast<ImplClass*>(this)->_CheckNow(); |
| } |
| |
| inline WEAVE_ERROR SoftwareUpdateManager::ImageInstallComplete(WEAVE_ERROR aError) |
| { |
| return static_cast<ImplClass*>(this)->_ImageInstallComplete(aError); |
| } |
| |
| inline WEAVE_ERROR SoftwareUpdateManager::PrepareImageStorageComplete(WEAVE_ERROR aError) |
| { |
| return static_cast<ImplClass*>(this)->_PrepareImageStorageComplete(aError); |
| } |
| |
| inline SoftwareUpdateManager::State SoftwareUpdateManager::GetState(void) |
| { |
| return static_cast<ImplClass*>(this)->_GetState(); |
| } |
| |
| inline WEAVE_ERROR SoftwareUpdateManager::Abort(void) |
| { |
| return static_cast<ImplClass*>(this)->_Abort(); |
| } |
| |
| inline bool SoftwareUpdateManager::IsInProgress(void) |
| { |
| return static_cast<ImplClass*>(this)->_IsInProgress(); |
| } |
| |
| inline WEAVE_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 WEAVE_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 Weave |
| } // namespace nl |
| |
| #endif // WEAVE_DEVICE_CONFIG_ENABLE_SOFTWARE_UPDATE_MANAGER |
| #endif // SOFTWARE_UPDATE_MANAGER_H |