Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Tue Jul 12 2022 19:01:32 by 1.7.2