Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
mbed-cloud-client/update-client-hub/modules/lwm2m-mbed/source/lwm2m-source.cpp
- Committer:
- MACRUM
- Date:
- 2018-07-02
- Revision:
- 0:276e7a263c35
File content as of revision 0:276e7a263c35:
// ---------------------------------------------------------------------------- // Copyright 2016-2017 ARM Ltd. // // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ---------------------------------------------------------------------------- #include "update-client-common/arm_uc_common.h" #include "update-client-lwm2m/lwm2m-source.h" #include "update-client-lwm2m/FirmwareUpdateResource.h" #include "update-client-lwm2m/DeviceMetadataResource.h" /* forward declaration */ static void ARM_UCS_PackageCallback(const uint8_t* buffer, uint16_t length); /* local copy of the received manifest */ static uint8_t* arm_ucs_manifest_buffer = NULL; static uint16_t arm_ucs_manifest_length = 0; /* callback function pointer and struct */ static void (*ARM_UCS_EventHandler)(uint32_t event) = 0; static arm_uc_callback_t callbackNodeManifest = { NULL, 0, NULL, 0 }; static arm_uc_callback_t callbackNodeNotification = { NULL, 0, NULL, 0 }; /** * @brief Get driver version. * @return Driver version. */ uint32_t ARM_UCS_LWM2M_SOURCE_GetVersion(void) { return 0; } /** * @brief Get Source capabilities. * @return Struct containing capabilites. See definition above. */ ARM_SOURCE_CAPABILITIES ARM_UCS_LWM2M_SOURCE_GetCapabilities(void) { ARM_SOURCE_CAPABILITIES result = { .notify = 0, .manifest_default = 0, .manifest_url = 0, .firmware = 0, .keytable = 0 }; /* the event handler must be set before module can be used */ if (ARM_UCS_EventHandler != 0) { result.notify = 1; result.manifest_default = 1; } return result; } /** * @brief Initialize Source. * @details Function pointer to event handler is passed as argument. * * @param cb_event Function pointer to event handler. See events above. * @return Error code. */ arm_uc_error_t ARM_UCS_LWM2M_SOURCE_Initialize(ARM_SOURCE_SignalEvent_t cb_event) { UC_SRCE_TRACE("ARM_UCS_LWM2M_SOURCE_Initialize: %p", cb_event); arm_uc_error_t result = { .code = SRCE_ERR_INVALID_PARAMETER }; if (cb_event != 0) { /* store callback handler */ ARM_UCS_EventHandler = cb_event; /* Initialize LWM2M Firmware Update Object */ FirmwareUpdateResource::Initialize(); /* Register callback handler */ FirmwareUpdateResource::addPackageCallback(ARM_UCS_PackageCallback); DeviceMetadataResource::Initialize(); result.code = SRCE_ERR_NONE; } return result; } /** * @brief Uninitialized Source. * @return Error code. */ arm_uc_error_t ARM_UCS_LWM2M_SOURCE_Uninitialize(void) { arm_uc_error_t retval = { .code = SRCE_ERR_NONE }; DeviceMetadataResource::Uninitialize(); FirmwareUpdateResource::Uninitialize(); return retval; } /** * @brief Cost estimation for retrieving manifest from the default location. * @details The estimation can vary over time and should not be cached too long. * 0x00000000 - The manifest is already downloaded. * 0xFFFFFFFF - Cannot retrieve manifest from this Source. * * @param cost Pointer to variable for the return value. * @return Error code. */ arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetManifestDefaultCost(uint32_t* cost) { arm_uc_error_t result = { .code = SRCE_ERR_INVALID_PARAMETER }; if (cost != 0) { /* set cost to 0 when manifest is cached */ if (arm_ucs_manifest_buffer && arm_ucs_manifest_length) { *cost = 0; } /* set cost to 0xFFFFFFFF when manifest has been read */ else { *cost = 0xFFFFFFFF; } result.code = SRCE_ERR_NONE; } return result; } /** * @brief Retrieve manifest from the default location. * @details Manifest is stored in supplied buffer. * Event is generated once manifest is in buffer. * * @param buffer Struct containing byte array, maximum size, and actual size. * @return Error code. */ arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetManifestDefault(arm_uc_buffer_t* buffer, uint32_t offset) { arm_uc_error_t result = { .code = SRCE_ERR_INVALID_PARAMETER }; /* copy manifest from cache into buffer */ if ((buffer != NULL) && (buffer->ptr != NULL) && (arm_ucs_manifest_buffer != NULL) && (arm_ucs_manifest_length != 0) && (offset < arm_ucs_manifest_length)) { /* remaining length based on offset request */ uint16_t length = arm_ucs_manifest_length - offset; /* set actual length based on buffer size */ if (length > buffer->size_max) { length = buffer->size_max; } /* size check */ if (length > 0) { /* copy manifest from local buffer to external buffer */ memcpy(buffer->ptr, &arm_ucs_manifest_buffer[offset], length); buffer->size = length; /* delete local buffer once the entire manifest has been read */ if (offset + length >= arm_ucs_manifest_length) { delete[] arm_ucs_manifest_buffer; arm_ucs_manifest_buffer = NULL; arm_ucs_manifest_length = 0; } result.code = SRCE_ERR_NONE; /* signal event handler that manifest has been copied to buffer */ if (ARM_UCS_EventHandler) { ARM_UC_PostCallback(&callbackNodeManifest, ARM_UCS_EventHandler, EVENT_MANIFEST); } } } return result; } static void ARM_UCS_PackageCallback(const uint8_t* buffer, uint16_t length) { uint32_t event_code = EVENT_ERROR; if (arm_ucs_manifest_buffer) { UC_SRCE_ERR_MSG("received new manifest before reading the old one"); /* delete old buffer to make space for the new one */ delete[] arm_ucs_manifest_buffer; arm_ucs_manifest_length = 0; } /* allocate a local buffer of the same size as the manifest */ arm_ucs_manifest_buffer = new uint8_t[length]; if (arm_ucs_manifest_buffer) { /* copy manifest from payload to local buffer */ memcpy(arm_ucs_manifest_buffer, buffer, length); arm_ucs_manifest_length = length; event_code = EVENT_NOTIFICATION; } /* signal event handler with result */ if (ARM_UCS_EventHandler) { ARM_UC_PostCallback(&callbackNodeNotification, ARM_UCS_EventHandler, event_code); } } /*****************************************************************************/ /* Capabilities not supported by this source */ /*****************************************************************************/ /** * @brief Cost estimation for retrieving manifest from URL. * @details The estimation can vary over time and should not be cached too long. * 0x00000000 - The manifest is already downloaded. * 0xFFFFFFFF - Cannot retrieve manifest from this Source. * * @param uri URI struct with manifest location. * @param cost Pointer to variable for the return value. * @return Error code. */ arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetManifestURLCost(arm_uc_uri_t* uri, uint32_t* cost) { (void) uri; (void) cost; arm_uc_error_t result = { .code = SRCE_ERR_INVALID_PARAMETER }; /* not supported - return default cost regardless of actual uri location */ if (cost) { *cost = 0xFFFFFFFF; result.code = SRCE_ERR_NONE; } return result; } /** * @brief Cost estimation for retrieving firmware from URL. * @details The estimation can vary over time and should not be cached too long. * 0x00000000 - The firmware is already downloaded. * 0xFFFFFFFF - Cannot retrieve firmware from this Source. * * @param uri URI struct with firmware location. * @param cost Pointer to variable for the return value. * @return Error code. */ arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetFirmwareURLCost(arm_uc_uri_t* uri, uint32_t* cost) { (void) uri; (void) cost; arm_uc_error_t result = { .code = SRCE_ERR_INVALID_PARAMETER }; /* not supported - return default cost regardless of actual uri location */ if (cost != 0) { *cost = 0xFFFFFFFF; result.code = SRCE_ERR_NONE; } return result; } /** * @brief Cost estimation for retrieving key table from URL. * @details The estimation can vary over time and should not be cached too long. * 0x00000000 - The firmware is already downloaded. * 0xFFFFFFFF - Cannot retrieve firmware from this Source. * * @param uri URI struct with keytable location. * @param cost Pointer to variable for the return value. * @return Error code. */ arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetKeytableURLCost(arm_uc_uri_t* uri, uint32_t* cost) { (void) uri; (void) cost; arm_uc_error_t result = { .code = SRCE_ERR_INVALID_PARAMETER }; /* not supported - return default cost regardless of actual uri location */ if ((uri != 0) && (cost != 0)) { *cost = 0xFFFFFFFF; result.code = SRCE_ERR_NONE; } return result; } /** * @brief Retrieve manifest from URL. * @details Manifest is stored in supplied buffer. * Event is generated once manifest is in buffer. * * @param uri URI struct with manifest location. * @param buffer Struct containing byte array, maximum size, and actual size. * * @return Error code. */ arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetManifestURL(arm_uc_uri_t* uri, arm_uc_buffer_t* buffer, uint32_t offset) { (void) uri; (void) buffer; (void) offset; arm_uc_error_t retval = { .code = SRCE_ERR_INVALID_PARAMETER }; return retval; } /** * @brief Retrieve firmware fragment. * @details Firmware fragment is stored in supplied buffer. * Event is generated once fragment is in buffer. * * @param uri URI struct with firmware location. * @param buffer Struct containing byte array, maximum size, and actual size. * @param offset Firmware offset to retrieve fragment from. * @return Error code. */ arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetFirmwareFragment(arm_uc_uri_t* uri, arm_uc_buffer_t* buffer, uint32_t offset) { (void) uri; (void) buffer; (void) offset; arm_uc_error_t retval = { .code = SRCE_ERR_INVALID_PARAMETER }; return retval; } /** * @brief Retrieve a key table from a URL. * @details Key table is stored in supplied buffer. * Event is generated once fragment is in buffer. * * @param uri URI struct with keytable location. * @param buffer Struct containing byte array, maximum size, and actual size. * @return Error code. */ arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetKeytableURL(arm_uc_uri_t* uri, arm_uc_buffer_t* buffer) { (void) uri; (void) buffer; arm_uc_error_t retval = { .code = SRCE_ERR_INVALID_PARAMETER }; return retval; } ARM_UPDATE_SOURCE ARM_UCS_LWM2M_SOURCE = { .GetVersion = ARM_UCS_LWM2M_SOURCE_GetVersion, .GetCapabilities = ARM_UCS_LWM2M_SOURCE_GetCapabilities, .Initialize = ARM_UCS_LWM2M_SOURCE_Initialize, .Uninitialize = ARM_UCS_LWM2M_SOURCE_Uninitialize, .GetManifestDefaultCost = ARM_UCS_LWM2M_SOURCE_GetManifestDefaultCost, .GetManifestURLCost = ARM_UCS_LWM2M_SOURCE_GetManifestURLCost, .GetFirmwareURLCost = ARM_UCS_LWM2M_SOURCE_GetFirmwareURLCost, .GetKeytableURLCost = ARM_UCS_LWM2M_SOURCE_GetKeytableURLCost, .GetManifestDefault = ARM_UCS_LWM2M_SOURCE_GetManifestDefault, .GetManifestURL = ARM_UCS_LWM2M_SOURCE_GetManifestURL, .GetFirmwareFragment = ARM_UCS_LWM2M_SOURCE_GetFirmwareFragment, .GetKeytableURL = ARM_UCS_LWM2M_SOURCE_GetKeytableURL };