Simulated product dispenser

Dependencies:   HTS221

Fork of mbed-cloud-workshop-connect-HTS221 by Jim Carver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arm_uc_control_center.c Source File

arm_uc_control_center.c

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 #include "update-client-control-center/arm_uc_control_center.h"
00020 
00021 #include <stdbool.h>
00022 
00023 /* event handler */
00024 static void (*arm_uccc_event_handler)(uint32_t) = NULL;
00025 static arm_uc_callback_t arm_uccc_authorize_callback = { 0 };
00026 static arm_uc_callback_t arm_uccc_monitor_callback = { 0 };
00027 
00028 /* authorization callback */
00029 static void (*arm_uc_authority_callback)(int32_t) = NULL;
00030 static bool arm_uc_download_token_armed = false;
00031 static bool arm_uc_install_token_armed = false;
00032 
00033 /* force authorization */
00034 static arm_uc_callback_t arm_uccc_override_callback = { 0 };
00035 
00036 static void arm_uccc_override_task(uint32_t unused);
00037 
00038 /* progress callback */
00039 static void (*arm_uc_progress_callback)(uint32_t, uint32_t) = NULL;
00040 
00041 /* function pointer structs */
00042 static const ARM_UPDATE_MONITOR* arm_uc_monitor_struct = NULL;
00043 
00044 static void ARM_UC_ControlCenter_Notification_Handler(void)
00045 {
00046     if (arm_uccc_event_handler)
00047     {
00048         ARM_UC_PostCallback(&arm_uccc_monitor_callback,
00049                             arm_uccc_event_handler,
00050                             ARM_UCCC_EVENT_MONITOR_SEND_DONE);
00051     }
00052 }
00053 
00054 /**
00055  * @brief Initialize Control Center.
00056  *
00057  * @param callback Event handler to signal authorizations.
00058  * @return Error code.
00059  */
00060 arm_uc_error_t ARM_UC_ControlCenter_Initialize(void (*callback)(uint32_t))
00061 {
00062     UC_CONT_TRACE("ARM_UC_ControlCenter_Initialize: %p", callback);
00063 
00064     arm_uccc_event_handler = callback;
00065 
00066     return (arm_uc_error_t){ ERR_NONE };
00067 }
00068 
00069 /**
00070  * @brief Add monitor struct for sending status and results remotely.
00071  *
00072  * @param monitor Pointer to an ARM_UPDATE_MONITOR struct.
00073  * @return Error code.
00074  */
00075 arm_uc_error_t ARM_UC_ControlCenter_AddMonitor(const ARM_UPDATE_MONITOR* monitor)
00076 {
00077     UC_CONT_TRACE("ARM_UC_ControlCenter_AddMonitor: %p", monitor);
00078 
00079     arm_uc_error_t result = (arm_uc_error_t){ ERR_INVALID_PARAMETER };
00080 
00081     arm_uc_monitor_struct = monitor;
00082 
00083     if (arm_uc_monitor_struct)
00084     {
00085         result = arm_uc_monitor_struct->Initialize(ARM_UC_ControlCenter_Notification_Handler);
00086     }
00087 
00088     return result;
00089 }
00090 
00091 /**
00092  * @brief Set callback for receiving download progress.
00093  * @details User application call for setting callback handler.
00094  *          The callback function takes the progreess in percent as argument.
00095  *
00096  * @param callback Function pointer to the progress function.
00097  * @return Error code.
00098  */
00099 arm_uc_error_t ARM_UC_ControlCenter_SetProgressHandler(void (*callback)(uint32_t progress, uint32_t total))
00100 {
00101     UC_CONT_TRACE("ARM_UC_ControlCenter_SetProgressHandler: %p", callback);
00102 
00103     arm_uc_progress_callback = callback;
00104 
00105     return (arm_uc_error_t){ ERR_NONE };
00106 }
00107 
00108 /**
00109  * @brief Set callback function for authorizing requests.
00110  * @details The callback function takes an enum request and an authorization
00111  *          function pointer. To authorize the given request, the caller
00112  *          invokes the authorization function.
00113  *
00114  * @param callback Function pointer to the authorization function.
00115  * @return Error code.
00116  */
00117 arm_uc_error_t ARM_UC_ControlCenter_SetAuthorityHandler(void (*callback)(int32_t))
00118 {
00119     UC_CONT_TRACE("ARM_UC_ControlCenter_SetAuthorityHandler: %p", callback);
00120 
00121     arm_uc_authority_callback = callback;
00122 
00123     return (arm_uc_error_t){ ERR_NONE };
00124 }
00125 
00126 /**
00127  * @brief Request authorization from Control Center.
00128  *
00129  * @param type Request type.
00130  * @return Error code.
00131  */
00132 arm_uc_error_t ARM_UC_ControlCenter_GetAuthorization(arm_uc_request_t request)
00133 {
00134     UC_CONT_TRACE("ARM_UC_ControlCenter_GetAuthorization: %d", (int) request);
00135 
00136     arm_uc_error_t result = (arm_uc_error_t){ ERR_INVALID_PARAMETER };
00137 
00138     switch (request)
00139     {
00140         case ARM_UCCC_REQUEST_DOWNLOAD:
00141             /* Arm callback token */
00142             arm_uc_download_token_armed = true;
00143 
00144             if (arm_uc_authority_callback)
00145             {
00146                 arm_uc_authority_callback(ARM_UCCC_REQUEST_DOWNLOAD);
00147             }
00148             else
00149             {
00150                 ARM_UC_ControlCenter_Authorize(ARM_UCCC_REQUEST_DOWNLOAD);
00151             }
00152             result.code = ERR_NONE;
00153             break;
00154 
00155         case ARM_UCCC_REQUEST_INSTALL:
00156             /* Arm callback token */
00157             arm_uc_install_token_armed = true;
00158 
00159             if (arm_uc_authority_callback)
00160             {
00161                 arm_uc_authority_callback(ARM_UCCC_REQUEST_INSTALL);
00162             }
00163             else
00164             {
00165                 ARM_UC_ControlCenter_Authorize(ARM_UCCC_REQUEST_INSTALL);
00166             }
00167             result.code = ERR_NONE;
00168             break;
00169         default:
00170             break;
00171     }
00172 
00173     return result;
00174 }
00175 
00176 /**
00177  * @brief Authorize request.
00178  *
00179  * @param request Request type. Must match the type in callback function.
00180  */
00181 arm_uc_error_t ARM_UC_ControlCenter_Authorize(arm_uc_request_t request)
00182 {
00183     UC_CONT_TRACE("ARM_UC_ControlCenter_Authorize: %d", (int) request);
00184 
00185     arm_uc_error_t result = (arm_uc_error_t){ ERR_INVALID_PARAMETER };
00186 
00187     switch (request)
00188     {
00189         case ARM_UCCC_REQUEST_DOWNLOAD:
00190             if (arm_uccc_event_handler && arm_uc_download_token_armed)
00191             {
00192                 arm_uc_download_token_armed = false;
00193 
00194                 ARM_UC_PostCallback(&arm_uccc_authorize_callback,
00195                                     arm_uccc_event_handler,
00196                                     ARM_UCCC_EVENT_AUTHORIZE_DOWNLOAD);
00197 
00198                 result.code = ERR_NONE;
00199             }
00200             break;
00201 
00202         case ARM_UCCC_REQUEST_INSTALL:
00203             if (arm_uccc_event_handler && arm_uc_install_token_armed)
00204             {
00205                 arm_uc_install_token_armed = false;
00206 
00207                 ARM_UC_PostCallback(&arm_uccc_authorize_callback,
00208                                     arm_uccc_event_handler,
00209                                     ARM_UCCC_EVENT_AUTHORIZE_INSTALL);
00210 
00211                 result.code = ERR_NONE;
00212             }
00213             break;
00214 
00215         default:
00216             break;
00217     }
00218 
00219     return result;
00220 }
00221 
00222 /**
00223  * @brief Override update authorization handler.
00224  * @details Force download and update to progress regardless of authorization
00225  *          handler. This function is used for unblocking an update in a buggy
00226  *          application.
00227  */
00228 void ARM_UC_ControlCenter_OverrideAuthorization(void)
00229 {
00230     ARM_UC_PostCallback(&arm_uccc_override_callback,
00231                         arm_uccc_override_task,
00232                         0);
00233 }
00234 
00235 static void arm_uccc_override_task(uint32_t unused)
00236 {
00237     (void) unused;
00238 
00239     UC_CONT_TRACE("arm_uccc_override_task");
00240 
00241     if (arm_uc_download_token_armed)
00242     {
00243         arm_uc_download_token_armed = false;
00244 
00245         /* force authorization */
00246         if (arm_uccc_event_handler)
00247         {
00248             arm_uccc_event_handler(ARM_UCCC_EVENT_AUTHORIZE_DOWNLOAD);
00249         }
00250     }
00251     else if (arm_uc_install_token_armed)
00252     {
00253         arm_uc_install_token_armed = false;
00254 
00255         /* force authorization */
00256         if (arm_uccc_event_handler)
00257         {
00258             arm_uccc_event_handler(ARM_UCCC_EVENT_AUTHORIZE_INSTALL);
00259         }
00260     }
00261 
00262     /* disable authorization function */
00263     arm_uc_authority_callback = NULL;
00264 }
00265 
00266 /**
00267  * @brief Report download progress.
00268  * @details Update Client call for informing the Control Center about the
00269  *          current download progress. The Control Center will send this to the
00270  *          appication handler and the monitor if either/both are attached.
00271  *
00272  * @param progrss Bytes already downloaded.
00273  * @param total Total amount of bytes in download.
00274  * @return Error code.
00275  */
00276 arm_uc_error_t ARM_UC_ControlCenter_ReportProgress(uint32_t progress, uint32_t total)
00277 {
00278     UC_CONT_TRACE("ARM_UC_ControlCenter_ReportProgress: %" PRIu32 " / %" PRIu32, progress, total);
00279 
00280     /* only forward request if callback is set. */
00281     if (arm_uc_progress_callback)
00282     {
00283         arm_uc_progress_callback(progress, total);
00284     }
00285 
00286     return (arm_uc_error_t){ ERR_NONE };
00287 }
00288 
00289 /**
00290  * @brief Send Update Client state.
00291  * @param state Update Client state.
00292  *
00293  * @return Error code.
00294  */
00295 arm_uc_error_t ARM_UC_ControlCenter_ReportState(arm_uc_monitor_state_t state)
00296 {
00297     UC_CONT_TRACE("ARM_UC_ControlCenter_ReportState: %d", (int) state);
00298 
00299     arm_uc_error_t result = (arm_uc_error_t){ ERR_INVALID_PARAMETER };
00300 
00301     if (arm_uc_monitor_struct)
00302     {
00303         arm_uc_monitor_struct->SendState(state);
00304         result.code = ERR_NONE;
00305     }
00306 
00307     return result;
00308 }
00309 
00310 /**
00311  * @brief Set update result.
00312  * @param result Update result.
00313  *
00314  * @return Error code.
00315  */
00316 arm_uc_error_t ARM_UC_ControlCenter_ReportUpdateResult(arm_uc_monitor_result_t updateResult)
00317 {
00318     UC_CONT_TRACE("ARM_UC_ControlCenter_ReportUpdateResult: %d", (int) updateResult);
00319 
00320     arm_uc_error_t result = (arm_uc_error_t){ ERR_INVALID_PARAMETER };
00321 
00322     if (arm_uc_monitor_struct)
00323     {
00324         arm_uc_monitor_struct->SendUpdateResult(updateResult);
00325         result.code = ERR_NONE;
00326     }
00327 
00328     return result;
00329 }
00330 
00331 /**
00332  * @brief Set current firmware name.
00333  * @details Update Client call for informing the Control Center about the
00334  *          current firmware name. The Control Center will send this to the
00335  *          monitor. The firmware name is the SHA256 hash.
00336  *
00337  * @param name Pointer to buffer struct. Hash is stored as byte array.
00338  * @return Error code.
00339  */
00340 arm_uc_error_t ARM_UC_ControlCenter_ReportName(arm_uc_buffer_t* name)
00341 {
00342     UC_CONT_TRACE("ARM_UC_ControlCenter_ReportName: %p", name);
00343 
00344     arm_uc_error_t result = (arm_uc_error_t){ ERR_INVALID_PARAMETER };
00345 
00346     if (arm_uc_monitor_struct)
00347     {
00348         arm_uc_monitor_struct->SendName(name);
00349         result.code = ERR_NONE;
00350     }
00351 
00352     return result;
00353 }
00354 
00355 /**
00356  * @brief Set current firmware version.
00357  * @details The firmware version is the SHA256 hash.
00358  *
00359  * @param version Pointer to buffer struct. Hash is stored as byte array.
00360  * @return Error code.
00361  */
00362 arm_uc_error_t ARM_UC_ControlCenter_ReportVersion(uint64_t version)
00363 {
00364     UC_CONT_TRACE("ARM_UC_ControlCenter_ReportVersion: %llu", version);
00365 
00366     arm_uc_error_t result = (arm_uc_error_t){ ERR_INVALID_PARAMETER };
00367 
00368     if (arm_uc_monitor_struct)
00369     {
00370         arm_uc_monitor_struct->SendVersion(version);
00371         result.code = ERR_NONE;
00372     }
00373 
00374     return result;
00375 }
00376 
00377 /**
00378  * @brief Send bootloader hash to monitor.
00379  * @details The bootloader hash is a hash of the bootloader. This is
00380  *          used for tracking the version of the bootloader used.
00381  *
00382  * @param name Pointer to buffer struct. Hash is stored as byte array.
00383  * @return Error code.
00384  */
00385 arm_uc_error_t ARM_UC_ControlCenter_ReportBootloaderHash(arm_uc_buffer_t* hash)
00386 {
00387     UC_CONT_TRACE("ARM_UC_ControlCenter_ReportBootloaderHash");
00388 
00389     arm_uc_error_t result = (arm_uc_error_t){ ERR_INVALID_PARAMETER };
00390 
00391     if (arm_uc_monitor_struct && arm_uc_monitor_struct->SetBootloaderHash)
00392     {
00393         result = arm_uc_monitor_struct->SetBootloaderHash(hash);
00394     }
00395 
00396     return result;
00397 }
00398 
00399 /**
00400  * @brief Send the OEM bootloader hash to monitor.
00401  * @details If the end-user has modified the bootloader the hash of the
00402  *          modified bootloader can be set here.
00403  *
00404  * @param name Pointer to buffer struct. Hash is stored as byte array.
00405  * @return Error code.
00406  */
00407 arm_uc_error_t ARM_UC_ControlCenter_ReportOEMBootloaderHash(arm_uc_buffer_t* hash)
00408 {
00409     UC_CONT_TRACE("ARM_UC_ControlCenter_ReportOEMBootloaderHash");
00410 
00411     arm_uc_error_t result = (arm_uc_error_t){ ERR_INVALID_PARAMETER };
00412 
00413     if (arm_uc_monitor_struct && arm_uc_monitor_struct->SetOEMBootloaderHash)
00414     {
00415         result = arm_uc_monitor_struct->SetOEMBootloaderHash(hash);
00416     }
00417 
00418     return result;
00419 }