Mayank Gupta / Mbed OS pelion-example-frdm

Dependencies:   FXAS21002 FXOS8700Q

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arm_uc_resume.h Source File

arm_uc_resume.h

00001 // ----------------------------------------------------------------------------
00002 // Copyright 2016-2017 ARM Ltd.
00003 //
00004 // SPDX-License-Identifier: Apache-2.0
00005 //
00006 // Licensed under the Apache License, Version 2.0 (the "License");
00007 // you may not use this file except in compliance with the License.
00008 // You may obtain a copy of the License at
00009 //
00010 //     http://www.apache.org/licenses/LICENSE-2.0
00011 //
00012 // Unless required by applicable law or agreed to in writing, software
00013 // distributed under the License is distributed on an "AS IS" BASIS,
00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 // See the License for the specific language governing permissions and
00016 // limitations under the License.
00017 // ----------------------------------------------------------------------------
00018 
00019 #ifndef ARM_RESUME_H
00020 #define ARM_RESUME_H
00021 
00022 #ifdef __cplusplus
00023 extern "C" {
00024 #endif
00025 
00026 #include "update-client-common/arm_uc_common.h"
00027 #include "pal.h"
00028 #include <inttypes.h>
00029 
00030 // RESUME MANAGEMENT.
00031 // ------------------
00032 /*
00033  * From the resume-engine perspective:
00034  *
00035  * This is an engine for allowing clients to hand off the responsibility of
00036  *   managing the timing portion of time-bounded and potentially resumable
00037  *   operations. A resumable operation is one which is able to fail temporarily,
00038  *   but retains enough state to continue later, typically after taking recovery
00039  *   actions to return to a state enabling continuation. Resumable operations are
00040  *   a mechanism to implement reliable operations in an unreliable environment.
00041  *
00042  * The resume engine supplies three callbacks - attempt, interval and terminate -
00043  *   which allows the client module to handle events appropriately.
00044  *   - Attempt callbacks are called repeatedly after some specified delay from
00045  *   the beginning of an attempt cycle, typically with exponentially increasing delays.
00046  *   An attempt cycle is the period from the start of an attempt to its end.
00047  *   - Interval callbacks are called at the *beginning* of every attempt cycle,
00048  *   (excluding the zeroth one, which occurs at the very start of an operation)
00049  *   up to some number of events specified by the client (possibly zero).
00050  *   An interval cycle is the period from the start of an interval to the next one.
00051  *   - The terminate callback is called after some specified delay from start,
00052  *   and calling it indicates that the resume is no longer active.
00053  *   An activity cycle is the period from the start of the resume monitor until
00054  *   it ends, either with an on-terminate event, or by the client-module
00055  *   ending it explicitly.
00056  *
00057  * Resynching is the process of clearing out the existing state of a resume, and
00058  *   restarting the whole process of intervals, attempts etc.
00059  *
00060  * From the client-module perspective:
00061  *
00062  * Resuming is handled by starting off what is effectively a parallel monitor
00063  *   whenever a new activity request is begun. The monitor is a timer which invokes
00064  *   client-supplied callbacks whenever the appropriate timer conditions are
00065  *   reached. The role of the resume engine is to supply the logic for a timer
00066  *   and callback structure that the client-module fills with suitable values to
00067  *   fulfil the needs it has.
00068  *
00069  * On expiry of the timer, the resume engine will invoke a callback so that the client
00070  *   module can take whatever action it deems necessary. The appropriate callback is
00071  *   selected based on the event type to which the timer was set to fire.
00072  *
00073  * If an operation completes, the resume-instance is transparently suspended by
00074  *   stopping the timer at the request of the client-module.
00075  *
00076  * There are three possible resume-event types, and one resume-error-event type.
00077  *
00078  * The error event is only invoked if the resume engine is unable to install a callback
00079  *   handler on behalf of the client, and signifies that the client can no longer
00080  *   assume its behaviour is being monitored by the resume engine.
00081  *
00082  * The first event type is the on-terminate event. This occurs when all events
00083  *   that have taken place up to now have not resulted in the resume cycle being
00084  *   completed with a call to arm_uc_resume_end_monitoring(). At this point, the
00085  *   user-specified callback on_resume_terminate_p is invoked, so that the client module
00086  *   can take whatever action it feels is suitable. The on-terminate event is intended
00087  *   to reflect the need to eventually call a halt to resume engine actions as by this
00088  *   point it is assumed that the activity can never be successfully completed by any
00089  *   actions the resume engine is capable of inducing the client to undertake.
00090  *
00091  * The second event type is the on-attempt event. This is an exponentially scaled
00092  *   timeout that is intended to reflect a balance between the need for repeated
00093  *   attempts to recover by the client module, and the need not to blindly continue
00094  *   repeating the same old actions over and over again, at the same pace. The on-attempt
00095  *   timeout is exponentially scaled to allow faster initial attempts, and then to
00096  *   slow down and be less aggressive with resources in its continued attempts. Once the
00097  *   summed attempts have reached the max-activity-timeout time, the resume cycle will
00098  *   be terminated with an on-terminate event.
00099  *
00100  * The last event type is an on-interval event. This is at a fixed (non-random) delay,
00101  *   and will occur either as many times as specified in the initialization structure,
00102  *   or indefinitely (until it threatens to overrun the current attempt timeout time).
00103  *   This is intended to provide support for repetitive algorithmic actions that are
00104  *   not well served by the exponential attempt timer, for example, simple retries
00105  *   with delays at the start of every attempt.
00106  *
00107  * If an activity completes, the thread is transparently suspended. The client-module
00108  *   must inform the resume-engine that this is so with a call to arm_uc_resume_end_monitoring().
00109  *
00110  *     *           |                         |                                                     |   *
00111  *     | | | |     | | | |                   |                                                     |   |
00112  *     -------------------------------------------------------------------------------------------------
00113  *     S I I I     A I I I                   A I I I                                               A I F
00114  *       1 2 3     2 1 2 3                   3 1 2 3                                               4 1
00115  *
00116  *     ^                                                                                               ^
00117  *     start                                                                                           finish
00118  *
00119  *
00120  *     [----------][------------------------][----------------------------------------------------][---]
00121  *       initial     initial * exponent        (initial * exponent) * exponent                      remainder
00122  *
00123  *      - - -
00124  *      interval gaps * number of intervals
00125  *
00126  *
00127  */
00128 // vectored activity-condition handlers to allow individual callbacks and unit-test mocking.
00129 typedef void (*on_resume_cb_t)(void *a_context_p);
00130 
00131 // storage cache for the current activity-probe state.
00132 typedef struct {
00133     // configuration.
00134     uint32_t exponentiation_factor; // factor by which previous attempt period is multiplied to get next.
00135     uint32_t attempt_initial_delay; // smallest allowed time period between successive attempts.
00136     uint32_t attempt_max_delay;     // largest allowed time period between successive attempts.
00137     uint32_t activity_max_time;     // largest *total* allowed time period for full cycle of activity.
00138     uint32_t interval_delay;        // time period between regular interval events until next.
00139     uint32_t interval_count;        // number of interval events to allow per resume attempt.
00140 
00141     // callbacks.
00142     on_resume_cb_t on_resume_interval_p;    // callback on regular interval.
00143     on_resume_cb_t on_resume_attempt_p;     // callback on resume attempt.
00144     on_resume_cb_t on_resume_terminate_p;   // callback on terminate (exceeded time limit).
00145     on_resume_cb_t on_resume_error_p;       // callback on resume engine error.
00146 
00147     // per-instance context.
00148     void *context_p;                // the client context instance.
00149 
00150     // behaviour support.
00151     palTimerID_t timer_id;          // resume-monitor timer.
00152     bool timer_is_running;          // keep track of timer run-state.
00153 
00154     bool currently_resuming;        // activity in progress, resume-probe is active.
00155     uint32_t num_attempts;          // number of resume attempts without a resynch.
00156     uint32_t num_intervals;         // number of interval events so far in this attempt.
00157 
00158     uint32_t expected_delay;        // period of the current attempt cycle.
00159     uint32_t jitter_delay;          // current expected-delay, allowing for randomization.
00160     uint32_t saved_jitter_delay;    // saved jitter delay for restoring after a resynch.
00161     uint32_t actual_delay;          // current timer period, allowing for intervals.
00162     uint32_t sum_interval_delays;   // summed interval delays from start of attempt.
00163     uint32_t sum_attempt_period;    // summed period of current attempt cycle.
00164     uint32_t sum_total_period;      // summed total period of full operation since last resynch.
00165 } arm_uc_resume_t;
00166 
00167 // Developer-facing #defines allow easier testing of parameterised resume.
00168 // If not available, it becomes extremely difficult to detect exactly when the resume
00169 //   functionality is taking place, or to set values outside of the assumed 'reasonable'
00170 //   range (which can't predict all use cases), which hampers assessment of the settings.
00171 
00172 // Print very high priority messages about resume activity for debugging.
00173 // Also, disable checks on resume initialization values.
00174 // Normally compiler errors out if checks enabled and out of permissible range.
00175 #define ARM_UC_RESUME_DEFAULT_ATTEMPT_TEST_MESSAGES_ENABLE  0
00176 
00177 // !do not modify or delete these definitions!
00178 // default configuration values for HTTP resume functionality.
00179 // to modify from default values, declare as below but without _DEFAULT
00180 //   eg. ARM_UC_HTTP_RESUME_EXPONENTIATION_FACTOR   3
00181 
00182 #define ARM_UC_RESUME_DEFAULT_EXPONENTIATION_FACTOR         2
00183 #define ARM_UC_RESUME_DEFAULT_INITIAL_DELAY_SECS            30
00184 #define ARM_UC_RESUME_DEFAULT_MAXIMUM_DELAY_SECS            (60*60)
00185 #define ARM_UC_RESUME_DEFAULT_MAXIMUM_DOWNLOAD_TIME_SECS    (7*24*60*60)
00186 
00187 /**
00188  * @brief Initialize a client resume-struct with values to be used for resuming.
00189  * @param a_resume_p A pointer to the struct to be initialized with values.
00190  * @param an_exponentiation_factor The factor by which a previous delay is multiplied to get next.
00191  * @param an_attempt_initial_delay The smallest allowed gap between successive attempts.
00192  * @param an_attempt_max_delay The largest allowed gap between successive attempts.
00193  * @param an_activity_max_time The largest *total* allowed period for full cycle of activity.
00194  * @param an_interval_delay The gap between regular interval events until next.
00195  * @param an_interval_count The number of interval events to allow per resume attempt.
00196  * @param an_on_interval_cb The callback to be invoked on an interval event.
00197  * @param an_on_attempt_cb The callback to be invoked on an attempt event.
00198  * @param an_on_termination_cb The callback to be invoked on a termination event.
00199  * @param a_context_p The client instance address.
00200  * @param an_on_error_cb The callback to be invoked on an error event (runs in ISR context!).
00201  */
00202 arm_uc_error_t arm_uc_resume_initialize(
00203     arm_uc_resume_t *a_resume_p,
00204     uint32_t an_exponentiation_factor,
00205     uint32_t an_attempt_initial_delay,
00206     uint32_t an_attempt_max_delay,
00207     uint32_t an_activity_max_time,
00208     uint32_t an_interval_delay,
00209     uint32_t an_interval_count,
00210     on_resume_cb_t an_on_interval_cb,
00211     on_resume_cb_t an_on_attempt_cb,
00212     on_resume_cb_t an_on_termination_cb,
00213     on_resume_cb_t an_on_error_cb,
00214     void *a_context_p);
00215 
00216 /**
00217  * @brief Check a client resume-struct with values to be used for resuming.
00218  * @param a_resume_p A pointer to the struct holding the values to be checked.
00219  */
00220 arm_uc_error_t arm_uc_resume_check_settings(arm_uc_resume_t *a_resume_p);
00221 
00222 /**
00223  * @brief Start off a new resume monitor, including initialisation if needed.
00224  * @details Initialise a supplied resume-struct with suitable values as passed in,
00225  *            then initiate the process of monitoring for resume purposes.
00226  * @param a_resume_p Pointer to the active resume structure.
00227  * @param a_resume_init_p Pointer to the initial values for active resume structure.
00228  */
00229 arm_uc_error_t arm_uc_resume_start_monitoring(arm_uc_resume_t *a_resume_p);
00230 
00231 /**
00232  * @brief Notify resume probe that recent valid activity has taken place.
00233  * @details Reset the resume engine such that timing begins again from now.
00234  * @param a_resume_p Pointer to the active resume structure.
00235  */
00236 arm_uc_error_t arm_uc_resume_resynch_monitoring(arm_uc_resume_t *a_resume_p);
00237 
00238 /**
00239  * @brief Notify resume probe that full firmware download has completed.
00240  * @details Halt the resume engine running on this resume-struct.
00241  * @param a_resume_p Pointer to the active resume structure.
00242  */
00243 arm_uc_error_t arm_uc_resume_end_monitoring(arm_uc_resume_t *a_resume_p);
00244 
00245 #ifdef __cplusplus
00246 }
00247 #endif
00248 
00249 #endif