Mbed Cloud example program for workshop in W27 2018.

Dependencies:   MMA7660 LM75B

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lwm2m-source.cpp Source File

lwm2m-source.cpp

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-common/arm_uc_common.h"
00020 #include "update-client-lwm2m/lwm2m-source.h"
00021 #include "update-client-lwm2m/FirmwareUpdateResource.h"
00022 #include "update-client-lwm2m/DeviceMetadataResource.h"
00023 
00024 
00025 /* forward declaration */
00026 static void ARM_UCS_PackageCallback(const uint8_t* buffer, uint16_t length);
00027 
00028 /* local copy of the received manifest */
00029 static uint8_t* arm_ucs_manifest_buffer = NULL;
00030 static uint16_t arm_ucs_manifest_length = 0;
00031 
00032 /* callback function pointer and struct */
00033 static void (*ARM_UCS_EventHandler)(uint32_t event) = 0;
00034 static arm_uc_callback_t callbackNodeManifest = { NULL, 0, NULL, 0 };
00035 static arm_uc_callback_t callbackNodeNotification = { NULL, 0, NULL, 0 };
00036 
00037 /**
00038  * @brief Get driver version.
00039  * @return Driver version.
00040  */
00041 uint32_t ARM_UCS_LWM2M_SOURCE_GetVersion(void)
00042 {
00043     return 0;
00044 }
00045 
00046 /**
00047  * @brief Get Source capabilities.
00048  * @return Struct containing capabilites. See definition above.
00049  */
00050 ARM_SOURCE_CAPABILITIES ARM_UCS_LWM2M_SOURCE_GetCapabilities(void)
00051 {
00052     ARM_SOURCE_CAPABILITIES result = { .notify = 0,
00053                                        .manifest_default = 0,
00054                                        .manifest_url = 0,
00055                                        .firmware = 0,
00056                                        .keytable = 0 };
00057 
00058     /* the event handler must be set before module can be used */
00059     if (ARM_UCS_EventHandler != 0)
00060     {
00061         result.notify = 1;
00062         result.manifest_default = 1;
00063     }
00064 
00065     return result;
00066 }
00067 
00068 /**
00069  * @brief Initialize Source.
00070  * @details Function pointer to event handler is passed as argument.
00071  *
00072  * @param cb_event Function pointer to event handler. See events above.
00073  * @return Error code.
00074  */
00075 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_Initialize(ARM_SOURCE_SignalEvent_t cb_event)
00076 {
00077     UC_SRCE_TRACE("ARM_UCS_LWM2M_SOURCE_Initialize: %p", cb_event);
00078 
00079     arm_uc_error_t result = { .code = SRCE_ERR_INVALID_PARAMETER };
00080 
00081     if (cb_event != 0)
00082     {
00083         /* store callback handler */
00084         ARM_UCS_EventHandler = cb_event;
00085 
00086         /* Initialize LWM2M Firmware Update Object */
00087         FirmwareUpdateResource::Initialize();
00088 
00089         /* Register callback handler */
00090         FirmwareUpdateResource::addPackageCallback(ARM_UCS_PackageCallback);
00091 
00092         DeviceMetadataResource::Initialize();
00093 
00094         result.code = SRCE_ERR_NONE;
00095     }
00096 
00097     return result;
00098 }
00099 
00100 /**
00101  * @brief Uninitialized Source.
00102  * @return Error code.
00103  */
00104 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_Uninitialize(void)
00105 {
00106     arm_uc_error_t retval = { .code = SRCE_ERR_NONE };
00107 
00108     return retval;
00109 }
00110 
00111 /**
00112  * @brief Cost estimation for retrieving manifest from the default location.
00113  * @details The estimation can vary over time and should not be cached too long.
00114  *          0x00000000 - The manifest is already downloaded.
00115  *          0xFFFFFFFF - Cannot retrieve manifest from this Source.
00116  *
00117  * @param cost Pointer to variable for the return value.
00118  * @return Error code.
00119  */
00120 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetManifestDefaultCost(uint32_t* cost)
00121 {
00122     arm_uc_error_t result = { .code = SRCE_ERR_INVALID_PARAMETER };
00123 
00124     if (cost != 0)
00125     {
00126         /* set cost to 0 when manifest is cached */
00127         if (arm_ucs_manifest_buffer && arm_ucs_manifest_length)
00128         {
00129             *cost = 0;
00130         }
00131         /* set cost to 0xFFFFFFFF when manifest has been read */
00132         else
00133         {
00134             *cost = 0xFFFFFFFF;
00135         }
00136 
00137         result.code = SRCE_ERR_NONE;
00138     }
00139 
00140     return result;
00141 }
00142 
00143 /**
00144  * @brief Retrieve manifest from the default location.
00145  * @details Manifest is stored in supplied buffer.
00146  *          Event is generated once manifest is in buffer.
00147  *
00148  * @param buffer Struct containing byte array, maximum size, and actual size.
00149  * @return Error code.
00150  */
00151 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetManifestDefault(arm_uc_buffer_t* buffer,
00152                                                        uint32_t offset)
00153 {
00154     arm_uc_error_t result = { .code = SRCE_ERR_INVALID_PARAMETER };
00155 
00156     /* copy manifest from cache into buffer */
00157     if ((buffer != NULL) &&
00158         (buffer->ptr != NULL) &&
00159         (arm_ucs_manifest_buffer != NULL) &&
00160         (arm_ucs_manifest_length != 0) &&
00161         (offset < arm_ucs_manifest_length))
00162     {
00163         /* remaining length based on offset request */
00164         uint16_t length = arm_ucs_manifest_length - offset;
00165 
00166         /* set actual length based on buffer size */
00167         if (length > buffer->size_max)
00168         {
00169             length = buffer->size_max;
00170         }
00171 
00172         /* size check */
00173         if (length > 0)
00174         {
00175             /* copy manifest from local buffer to external buffer */
00176             memcpy(buffer->ptr, &arm_ucs_manifest_buffer[offset], length);
00177             buffer->size = length;
00178 
00179             /* delete local buffer once the entire manifest has been read */
00180             if (offset + length >= arm_ucs_manifest_length)
00181             {
00182                 delete[] arm_ucs_manifest_buffer;
00183                 arm_ucs_manifest_buffer = NULL;
00184                 arm_ucs_manifest_length = 0;
00185             }
00186 
00187             result.code = SRCE_ERR_NONE;
00188 
00189             /* signal event handler that manifest has been copied to buffer */
00190             if (ARM_UCS_EventHandler)
00191             {
00192                 ARM_UC_PostCallback(&callbackNodeManifest,
00193                                     ARM_UCS_EventHandler,
00194                                     EVENT_MANIFEST);
00195             }
00196         }
00197     }
00198 
00199     return result;
00200 }
00201 
00202 static void ARM_UCS_PackageCallback(const uint8_t* buffer, uint16_t length)
00203 {
00204     uint32_t event_code = EVENT_ERROR;
00205 
00206     if (arm_ucs_manifest_buffer)
00207     {
00208         UC_SRCE_ERR_MSG("received new manifest before reading the old one");
00209 
00210         /* delete old buffer to make space for the new one */
00211         delete[] arm_ucs_manifest_buffer;
00212         arm_ucs_manifest_length = 0;
00213     }
00214 
00215     /* allocate a local buffer of the same size as the manifest */
00216     arm_ucs_manifest_buffer = new uint8_t[length];
00217 
00218     if (arm_ucs_manifest_buffer)
00219     {
00220         /* copy manifest from payload to local buffer */
00221         memcpy(arm_ucs_manifest_buffer, buffer, length);
00222         arm_ucs_manifest_length = length;
00223 
00224         event_code = EVENT_NOTIFICATION;
00225     }
00226 
00227     /* signal event handler with result */
00228     if (ARM_UCS_EventHandler)
00229     {
00230         ARM_UC_PostCallback(&callbackNodeNotification,
00231                             ARM_UCS_EventHandler,
00232                             event_code);
00233     }
00234 }
00235 
00236 /*****************************************************************************/
00237 /* Capabilities not supported by this source                                 */
00238 /*****************************************************************************/
00239 
00240 /**
00241  * @brief Cost estimation for retrieving manifest from URL.
00242  * @details The estimation can vary over time and should not be cached too long.
00243  *          0x00000000 - The manifest is already downloaded.
00244  *          0xFFFFFFFF - Cannot retrieve manifest from this Source.
00245  *
00246  * @param uri URI struct with manifest location.
00247  * @param cost Pointer to variable for the return value.
00248  * @return Error code.
00249  */
00250 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetManifestURLCost(arm_uc_uri_t* uri,
00251                                                        uint32_t* cost)
00252 {
00253     (void) uri;
00254     (void) cost;
00255 
00256     arm_uc_error_t result = { .code = SRCE_ERR_INVALID_PARAMETER };
00257 
00258     /* not supported - return default cost regardless of actual uri location */
00259     if (cost)
00260     {
00261         *cost = 0xFFFFFFFF;
00262         result.code = SRCE_ERR_NONE;
00263     }
00264 
00265     return result;
00266 }
00267 
00268 /**
00269  * @brief Cost estimation for retrieving firmware from URL.
00270  * @details The estimation can vary over time and should not be cached too long.
00271  *          0x00000000 - The firmware is already downloaded.
00272  *          0xFFFFFFFF - Cannot retrieve firmware from this Source.
00273  *
00274  * @param uri URI struct with firmware location.
00275  * @param cost Pointer to variable for the return value.
00276  * @return Error code.
00277  */
00278 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetFirmwareURLCost(arm_uc_uri_t* uri,
00279                                                        uint32_t* cost)
00280 {
00281     (void) uri;
00282     (void) cost;
00283 
00284     arm_uc_error_t result = { .code = SRCE_ERR_INVALID_PARAMETER };
00285 
00286     /* not supported - return default cost regardless of actual uri location */
00287     if (cost != 0)
00288     {
00289         *cost = 0xFFFFFFFF;
00290         result.code = SRCE_ERR_NONE;
00291     }
00292 
00293     return result;
00294 }
00295 
00296 /**
00297  * @brief Cost estimation for retrieving key table from URL.
00298  * @details The estimation can vary over time and should not be cached too long.
00299  *          0x00000000 - The firmware is already downloaded.
00300  *          0xFFFFFFFF - Cannot retrieve firmware from this Source.
00301  *
00302  * @param uri URI struct with keytable location.
00303  * @param cost Pointer to variable for the return value.
00304  * @return Error code.
00305  */
00306 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetKeytableURLCost(arm_uc_uri_t* uri,
00307                                                        uint32_t* cost)
00308 {
00309     (void) uri;
00310     (void) cost;
00311 
00312     arm_uc_error_t result = { .code = SRCE_ERR_INVALID_PARAMETER };
00313 
00314     /* not supported - return default cost regardless of actual uri location */
00315     if ((uri != 0) && (cost != 0))
00316     {
00317         *cost = 0xFFFFFFFF;
00318         result.code = SRCE_ERR_NONE;
00319     }
00320 
00321     return result;
00322 }
00323 
00324 /**
00325  * @brief Retrieve manifest from URL.
00326  * @details Manifest is stored in supplied buffer.
00327  *          Event is generated once manifest is in buffer.
00328  *
00329  * @param uri URI struct with manifest location.
00330  * @param buffer Struct containing byte array, maximum size, and actual size.
00331  *
00332  * @return Error code.
00333  */
00334 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetManifestURL(arm_uc_uri_t* uri,
00335                                                    arm_uc_buffer_t* buffer,
00336                                                    uint32_t offset)
00337 {
00338     (void) uri;
00339     (void) buffer;
00340     (void) offset;
00341 
00342     arm_uc_error_t retval = { .code = SRCE_ERR_INVALID_PARAMETER };
00343 
00344     return retval;
00345 }
00346 
00347 /**
00348  * @brief Retrieve firmware fragment.
00349  * @details Firmware fragment is stored in supplied buffer.
00350  *          Event is generated once fragment is in buffer.
00351  *
00352  * @param uri URI struct with firmware location.
00353  * @param buffer Struct containing byte array, maximum size, and actual size.
00354  * @param offset Firmware offset to retrieve fragment from.
00355  * @return Error code.
00356  */
00357 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetFirmwareFragment(arm_uc_uri_t* uri,
00358                                                         arm_uc_buffer_t* buffer,
00359                                                         uint32_t offset)
00360 {
00361     (void) uri;
00362     (void) buffer;
00363     (void) offset;
00364 
00365     arm_uc_error_t retval = { .code = SRCE_ERR_INVALID_PARAMETER };
00366 
00367     return retval;
00368 }
00369 
00370 /**
00371  * @brief Retrieve a key table from a URL.
00372  * @details Key table is stored in supplied buffer.
00373  *          Event is generated once fragment is in buffer.
00374  *
00375  * @param uri URI struct with keytable location.
00376  * @param buffer Struct containing byte array, maximum size, and actual size.
00377  * @return Error code.
00378  */
00379 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetKeytableURL(arm_uc_uri_t* uri,
00380                                                    arm_uc_buffer_t* buffer)
00381 {
00382     (void) uri;
00383     (void) buffer;
00384 
00385     arm_uc_error_t retval = { .code = SRCE_ERR_INVALID_PARAMETER };
00386 
00387     return retval;
00388 }
00389 
00390 ARM_UPDATE_SOURCE ARM_UCS_LWM2M_SOURCE =
00391 {
00392     .GetVersion             = ARM_UCS_LWM2M_SOURCE_GetVersion,
00393     .GetCapabilities        = ARM_UCS_LWM2M_SOURCE_GetCapabilities,
00394     .Initialize             = ARM_UCS_LWM2M_SOURCE_Initialize,
00395     .Uninitialize           = ARM_UCS_LWM2M_SOURCE_Uninitialize,
00396     .GetManifestDefaultCost = ARM_UCS_LWM2M_SOURCE_GetManifestDefaultCost,
00397     .GetManifestURLCost     = ARM_UCS_LWM2M_SOURCE_GetManifestURLCost,
00398     .GetFirmwareURLCost     = ARM_UCS_LWM2M_SOURCE_GetFirmwareURLCost,
00399     .GetKeytableURLCost     = ARM_UCS_LWM2M_SOURCE_GetKeytableURLCost,
00400     .GetManifestDefault     = ARM_UCS_LWM2M_SOURCE_GetManifestDefault,
00401     .GetManifestURL         = ARM_UCS_LWM2M_SOURCE_GetManifestURL,
00402     .GetFirmwareFragment    = ARM_UCS_LWM2M_SOURCE_GetFirmwareFragment,
00403     .GetKeytableURL         = ARM_UCS_LWM2M_SOURCE_GetKeytableURL
00404 };