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 update_client_hub.c Source File

update_client_hub.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-hub/update_client_hub.h"
00020 
00021 #include "update-client-common/arm_uc_common.h"
00022 #include "update-client-control-center/arm_uc_control_center.h"
00023 #include "update-client-control-center/arm_uc_pre_shared_key.h"
00024 #include "update-client-control-center/arm_uc_certificate.h"
00025 #include "update-client-source-manager/arm_uc_source_manager.h"
00026 #include "update-client-firmware-manager/arm_uc_firmware_manager.h"
00027 #include "update-client-manifest-manager/update-client-manifest-manager.h"
00028 
00029 #include "update_client_hub_state_machine.h"
00030 #include "update_client_hub_event_handlers.h"
00031 #include "update_client_hub_error_handler.h"
00032 
00033 #include "pal4life-device-identity/pal_device_identity.h"
00034 
00035 #define HANDLE_INIT_ERROR(retval, msg, ...)\
00036     if (retval.error != ERR_NONE)\
00037     {\
00038         ARM_UC_HUB_setState(ARM_UC_HUB_STATE_UNINITIALIZED);\
00039         UC_HUB_ERR_MSG(msg " error code %s", ##__VA_ARGS__, ARM_UC_err2Str(retval));\
00040         return retval;\
00041     }
00042 
00043 static const ARM_UPDATE_SOURCE** arm_uc_sources = NULL;
00044 static uint8_t arm_uc_sources_size = 0;
00045 
00046 static arm_uc_mmContext_t manifestManagerInitContext = { 0 };
00047 static arm_uc_mmContext_t* pManifestManagerInitContext = &manifestManagerInitContext;
00048 
00049 /**
00050  * @brief Handle any errors posted by the scheduler.
00051  * @details This explicitly runs *not* in interrupt context, the scheduler has a dedicated
00052  *            callback structure to ensure it can post at least this event.
00053  *          ARM_UC_HUB_ErrorHandler() will invoke the HUB callback that was set up.
00054  *          It is up to the external application to go about inducing a reset etc,
00055  *            if that is what it decides. Note that the HUB is no longer operable
00056  *            and the app should probably Uninitialize it and report an error.
00057  *            However, the HUB will attempt some cleanup after it returns.
00058  * @param an_event the type of the event causing the error callback.
00059  *        The only possible errors from the scheduler are currently:
00060  *            ARM_UC_EQ_ERR_POOL_EXHAUSTED
00061  *            ARM_UC_EQ_ERR_FAILED_TAKE
00062  *        These are passed on to the Hub error handler as an internal error,
00063  *          and the hub state is now considered unknown from this perspective.
00064  *          (An internal error is considered fatal by the hub.)
00065  */
00066 void UC_HUB_scheduler_error_handler(uint32_t an_event)
00067 {
00068     UC_HUB_ERR_MSG("scheduler error: %" PRIu32, an_event);
00069     ARM_UC_HUB_ErrorHandler(HUB_ERR_INTERNAL_ERROR, ARM_UC_HUB_getState());
00070 }
00071 
00072 /**
00073  * @brief Call initialiser of all components of the client.
00074  *        finish asynchronously, will invoke callback when initialization is done.
00075  * @param init_cb the callback to be invoked at the end of initialization.
00076  */
00077 arm_uc_error_t ARM_UC_HUB_Initialize(void (*init_cb)(int32_t))
00078 {
00079     arm_uc_error_t retval;
00080 
00081     if (ARM_UC_HUB_getState() != ARM_UC_HUB_STATE_UNINITIALIZED)
00082     {
00083         UC_HUB_ERR_MSG("Already Initialized/Initializing");
00084         return (arm_uc_error_t){ ERR_INVALID_STATE };
00085     }
00086     ARM_UC_HUB_setState(ARM_UC_HUB_STATE_INITIALIZING);
00087 
00088     ARM_UC_SchedulerInit();
00089     ARM_UC_HUB_setInitializationCallback(init_cb);
00090     ARM_UC_SetSchedulerErrorHandler(UC_HUB_scheduler_error_handler);
00091 
00092     /* Register event handler with Control Center. */
00093     retval = ARM_UC_ControlCenter_Initialize(ARM_UC_HUB_ControlCenterEventHandler);
00094     HANDLE_INIT_ERROR(retval, "Control Center init failed")
00095 
00096     /* Register event handler with Firmware Manager */
00097     retval = ARM_UC_FirmwareManager.Initialize(ARM_UC_HUB_FirmwareManagerEventHandler);
00098     HANDLE_INIT_ERROR(retval, "Firmware Manager init failed")
00099 
00100     /* Register event handler with Source Manager */
00101     retval = ARM_UC_SourceManager.Initialize(ARM_UC_HUB_SourceManagerEventHandler);
00102     HANDLE_INIT_ERROR(retval, "Source Manager init failed")
00103 
00104     for (uint8_t index = 0; index < arm_uc_sources_size; index++)
00105     {
00106         ARM_UC_SourceManager.AddSource(arm_uc_sources[index]);
00107     }
00108 
00109     /* Register event handler and add config store implementation to manifest
00110        manager.
00111     */
00112     retval = ARM_UC_mmInit(&pManifestManagerInitContext,
00113                            ARM_UC_HUB_ManifestManagerEventHandler,
00114                            NULL);
00115     HANDLE_INIT_ERROR(retval, "Manifest manager init failed")
00116 
00117     /* add hard coded certificates to the manifest manager */
00118     // retval = ARM_UC_mmStoreCertificate(CA_PATH, cert, CERT_SIZE);
00119     // if ((retval.error != ERR_NONE) && (retval.code != MFST_ERR_PENDING))
00120     // {
00121     //     HANDLE_INIT_ERROR(retval, "Manifest manager StoreCertificate failed")
00122     // }
00123 
00124     return (arm_uc_error_t){ ERR_NONE };
00125 }
00126 
00127 /**
00128  * @brief Process events in the event queue.
00129  */
00130 arm_uc_error_t ARM_UC_HUB_ProcessEvents()
00131 {
00132     ARM_UC_ProcessQueue();
00133 
00134     return (arm_uc_error_t){ ERR_NONE };
00135 }
00136 
00137 /**
00138  * @brief Register callback function for when callbacks are added to an empty queue.
00139  */
00140 arm_uc_error_t ARM_UC_HUB_AddNotificationHandler(void (*handler)(void))
00141 {
00142     ARM_UC_AddNotificationHandler(handler);
00143 
00144     return (arm_uc_error_t){ ERR_NONE };
00145 }
00146 
00147 /**
00148  * @brief Add source to the Update Client.
00149  */
00150 arm_uc_error_t ARM_UC_HUB_SetSources(const ARM_UPDATE_SOURCE* sources[],
00151                                      uint8_t size)
00152 {
00153     arm_uc_sources = sources;
00154     arm_uc_sources_size = size;
00155 
00156     return (arm_uc_error_t){ ERR_NONE };
00157 }
00158 
00159 /**
00160  * Set PAAL Update implementation
00161  */
00162 arm_uc_error_t ARM_UC_HUB_SetStorage(const ARM_UC_PAAL_UPDATE* implementation)
00163 {
00164     return ARM_UCP_SetPAALUpdate(implementation);
00165 }
00166 
00167 /**
00168  * @brief Add monitor to the control center.
00169  */
00170 arm_uc_error_t ARM_UC_HUB_AddMonitor(const ARM_UPDATE_MONITOR* monitor)
00171 {
00172     return ARM_UC_ControlCenter_AddMonitor(monitor);
00173 }
00174 
00175 /**
00176  * @brief Temporary error reporting function.
00177  */
00178 void ARM_UC_HUB_AddErrorCallback(void (*callback)(int32_t error))
00179 {
00180     ARM_UC_HUB_AddErrorCallbackInternal(callback);
00181 }
00182 
00183 /**
00184  * @brief Authorize request.
00185  */
00186 arm_uc_error_t ARM_UC_Authorize(arm_uc_request_t request)
00187 {
00188     return ARM_UC_ControlCenter_Authorize(request);
00189 }
00190 
00191 /**
00192  * @brief Set callback for receiving download progress.
00193  * @details User application call for setting callback handler.
00194  *          The callback function takes the progreess in percent as argument.
00195  *
00196  * @param callback Function pointer to the progress function.
00197  * @return Error code.
00198  */
00199 arm_uc_error_t ARM_UC_SetProgressHandler(void (*callback)(uint32_t progress, uint32_t total))
00200 {
00201     return ARM_UC_ControlCenter_SetProgressHandler(callback);
00202 }
00203 
00204 /**
00205  * @brief Set callback function for authorizing requests.
00206  * @details User application call for setting callback handler.
00207  *          The callback function takes an enum request and an authorization
00208  *          function pointer. To authorize the given request, the caller
00209  *          invokes the authorization function.
00210  *
00211  * @param callback Function pointer to the authorization function.
00212  * @return Error code.
00213  */
00214 arm_uc_error_t ARM_UC_SetAuthorizeHandler(void (*callback)(int32_t))
00215 {
00216     return ARM_UC_ControlCenter_SetAuthorityHandler(callback);
00217 }
00218 
00219 /**
00220  * @brief Override update authorization handler.
00221  * @details Force download and update to progress regardless of authorization
00222  *          handler. This function is used for unblocking an update in a buggy
00223  *          application.
00224  */
00225 void ARM_UC_OverrideAuthorization(void)
00226 {
00227     ARM_UC_ControlCenter_OverrideAuthorization();
00228 }
00229 
00230 /**
00231  * @brief Add certificate.
00232  * @details [long description]
00233  *
00234  * @param certificate Pointer to certiface being added.
00235  * @param certificate_length Certificate length.
00236  * @param fingerprint Pointer to the fingerprint of the certificate being added.
00237  * @param fingerprint_length Fingerprint length.
00238  * @return Error code.
00239  */
00240 arm_uc_error_t ARM_UC_AddCertificate(const uint8_t* certificate,
00241                                      uint16_t certificate_length,
00242                                      const uint8_t* fingerprint,
00243                                      uint16_t fingerprint_length,
00244                                      void (*callback)(arm_uc_error_t, const arm_uc_buffer_t*))
00245 {
00246     return ARM_UC_Certificate_Add(certificate,
00247                                   certificate_length,
00248                                   fingerprint,
00249                                   fingerprint_length,
00250                                   callback);
00251 }
00252 
00253 /**
00254  * @brief Set pointer to pre-shared-key with the given size.
00255  *
00256  * @param key Pointer to pre-shared-key.
00257  * @param bits Key size in bits.
00258  *
00259  * @return Error code.
00260  */
00261 arm_uc_error_t ARM_UC_AddPreSharedKey(const uint8_t* key, uint16_t bits)
00262 {
00263     return ARM_UC_PreSharedKey_SetKey(key, bits);
00264 }
00265 
00266 /**
00267  * @brief Function for setting the vendor ID.
00268  * @details The ID is copied to a 16 byte struct. Any data after the first
00269  *          16 bytes will be ignored.
00270  * @param id Pointer to ID.
00271  * @param length Length of ID.
00272  * @return Error code.
00273  */
00274 arm_uc_error_t ARM_UC_SetVendorId(const uint8_t* id, uint8_t length)
00275 {
00276     arm_uc_guid_t uuid = { 0 };
00277 
00278     if (id)
00279     {
00280         for (uint8_t index = 0;
00281              (index < sizeof(arm_uc_guid_t) && (index < length));
00282              index++)
00283         {
00284             ((uint8_t*) uuid)[index] = id[index];
00285         }
00286     }
00287 
00288     return pal_setVendorGuid(&uuid);
00289 }
00290 
00291 /**
00292  * @brief Function for setting the class ID.
00293  * @details The ID is copied to a 16 byte struct. Any data after the first
00294  *          16 bytes will be ignored.
00295  * @param id Pointer to ID.
00296  * @param length Length of ID.
00297  * @return Error code.
00298  */
00299 arm_uc_error_t ARM_UC_SetClassId(const uint8_t* id, uint8_t length)
00300 {
00301     arm_uc_guid_t uuid = { 0 };
00302 
00303     if (id)
00304     {
00305         for (uint8_t index = 0;
00306              (index < sizeof(arm_uc_guid_t) && (index < length));
00307              index++)
00308         {
00309             ((uint8_t*) uuid)[index] = id[index];
00310         }
00311     }
00312 
00313     return pal_setClassGuid(&uuid);
00314 }
00315 
00316 /**
00317  * @brief Function for setting the device ID.
00318  * @details The ID is copied to a 16 byte struct. Any data after the first
00319  *          16 bytes will be ignored.
00320  * @param id Pointer to ID.
00321  * @param length Length of ID.
00322  * @return Error code.
00323  */
00324 arm_uc_error_t ARM_UC_SetDeviceId(const uint8_t* id, uint8_t length)
00325 {
00326     arm_uc_guid_t uuid = { 0 };
00327 
00328     if (id)
00329     {
00330         for (uint8_t index = 0;
00331              (index < sizeof(arm_uc_guid_t) && (index < length));
00332              index++)
00333         {
00334             ((uint8_t*) uuid)[index] = id[index];
00335         }
00336     }
00337 
00338     return pal_setDeviceGuid(&uuid);
00339 }
00340 
00341 /**
00342  * @brief Function for reporting the vendor ID.
00343  * @details 16 bytes are copied into the supplied buffer.
00344  * @param id Pointer to storage for ID. MUST be at least 16 bytes long.
00345  * @param id_max the size of the ID buffer
00346  * @param id_size pointer to a variable to receive the size of the ID
00347  *                written into the buffer (always 16).
00348  * @return Error code.
00349  */
00350 arm_uc_error_t ARM_UC_GetVendorId(uint8_t* id,
00351                                   const size_t id_max,
00352                                   size_t* id_size)
00353 {
00354     arm_uc_guid_t guid = {0};
00355     arm_uc_error_t err = {ERR_NONE};
00356     if (id_max < sizeof(arm_uc_guid_t))
00357     {
00358         err.code = ARM_UC_DI_ERR_SIZE;
00359     }
00360     if (err.error == ERR_NONE)
00361     {
00362         err = pal_getVendorGuid(&guid);
00363     }
00364     if (err.error == ERR_NONE)
00365     {
00366         memcpy(id, guid, sizeof(arm_uc_guid_t));
00367         if (id_size != NULL)
00368         {
00369             *id_size = sizeof(arm_uc_guid_t);
00370         }
00371     }
00372     return err;
00373 }
00374 
00375 /**
00376  * @brief Function for reporting the class ID.
00377  * @details 16 bytes are copied into the supplied buffer.
00378  * @param id Pointer to storage for ID. MUST be at least 16 bytes long.
00379  * @param id_max the size of the ID buffer
00380  * @param id_size pointer to a variable to receive the size of the ID
00381  *                written into the buffer (always 16).
00382  * @return Error code.
00383  */
00384 arm_uc_error_t ARM_UC_GetClassId(uint8_t* id,
00385                                   const size_t id_max,
00386                                   size_t* id_size)
00387 {
00388     arm_uc_guid_t guid = {0};
00389     arm_uc_error_t err = {ERR_NONE};
00390     if (id_max < sizeof(arm_uc_guid_t))
00391     {
00392         err.code = ARM_UC_DI_ERR_SIZE;
00393     }
00394     if (err.error == ERR_NONE)
00395     {
00396         err = pal_getClassGuid(&guid);
00397     }
00398     if (err.error == ERR_NONE)
00399     {
00400         memcpy(id, guid, sizeof(arm_uc_guid_t));
00401         if (id_size != NULL)
00402         {
00403             *id_size = sizeof(arm_uc_guid_t);
00404         }
00405     }
00406     return err;
00407 }
00408 
00409 /**
00410  * @brief Function for reporting the device ID.
00411  * @details 16 bytes are copied into the supplied buffer.
00412  * @param id Pointer to storage for ID. MUST be at least 16 bytes long.
00413  * @param id_max the size of the ID buffer
00414  * @param id_size pointer to a variable to receive the size of the ID
00415  *                written into the buffer (always 16).
00416  * @return Error code.
00417  */
00418 arm_uc_error_t ARM_UC_GetDeviceId(uint8_t* id,
00419                                   const size_t id_max,
00420                                   size_t* id_size)
00421 {
00422     arm_uc_guid_t guid = {0};
00423     arm_uc_error_t err = {ERR_NONE};
00424     if (id_max < sizeof(arm_uc_guid_t))
00425     {
00426         err.code = ARM_UC_DI_ERR_SIZE;
00427     }
00428     if (err.error == ERR_NONE)
00429     {
00430         err = pal_getDeviceGuid(&guid);
00431     }
00432     if (err.error == ERR_NONE)
00433     {
00434         memcpy(id, guid, sizeof(arm_uc_guid_t));
00435         if (id_size != NULL)
00436         {
00437             *id_size = sizeof(arm_uc_guid_t);
00438         }
00439     }
00440     return err;
00441 }
00442 
00443 arm_uc_error_t ARM_UC_HUB_Uninitialize(void)
00444 {
00445     if (ARM_UC_HUB_getState() != ARM_UC_HUB_STATE_INITIALIZED)
00446     {
00447        UC_HUB_ERR_MSG("Update Client not initialized");
00448        return (arm_uc_error_t){ ERR_INVALID_STATE };
00449     }
00450 
00451     arm_uc_error_t err = ARM_UC_SourceManager.Uninitialize();
00452     ARM_UC_HUB_setState(ARM_UC_HUB_STATE_UNINITIALIZED);
00453     return err;
00454 }
00455 
00456 /**
00457  * @brief Return the details of the active firmware.
00458  * @param details Pointer to the firmware details structure.
00459  * @return ARM_UC_HUB_ERR_NOT_AVAILABLE if the active firmware details
00460  *         are not yet available, ERR_INVALID_PARAMETER if "details" is
00461  *         NULL or ERR_NONE for success.
00462  */
00463 arm_uc_error_t ARM_UC_API_GetActiveFirmwareDetails(arm_uc_firmware_details_t* details)
00464 {
00465     arm_uc_error_t err = {ARM_UC_HUB_ERR_NOT_AVAILABLE};
00466 
00467     if (details == NULL)
00468     {
00469         err.code = ERR_INVALID_PARAMETER;
00470     }
00471     else
00472     {
00473         arm_uc_firmware_details_t *hub_details = ARM_UC_HUB_getActiveFirmwareDetails();
00474         if (hub_details)
00475         {
00476             memcpy(details, hub_details, sizeof(arm_uc_firmware_details_t));
00477             err.code = ERR_NONE;
00478         }
00479     }
00480     return err;
00481 }