Example

Dependencies:   FXAS21002 FXOS8700Q

Committer:
maygup01
Date:
Tue Nov 19 09:49:38 2019 +0000
Revision:
0:11cc2b7889af
Example

Who changed what in which revision?

UserRevisionLine numberNew contents of line
maygup01 0:11cc2b7889af 1 // ----------------------------------------------------------------------------
maygup01 0:11cc2b7889af 2 // Copyright 2016-2017 ARM Ltd.
maygup01 0:11cc2b7889af 3 //
maygup01 0:11cc2b7889af 4 // SPDX-License-Identifier: Apache-2.0
maygup01 0:11cc2b7889af 5 //
maygup01 0:11cc2b7889af 6 // Licensed under the Apache License, Version 2.0 (the "License");
maygup01 0:11cc2b7889af 7 // you may not use this file except in compliance with the License.
maygup01 0:11cc2b7889af 8 // You may obtain a copy of the License at
maygup01 0:11cc2b7889af 9 //
maygup01 0:11cc2b7889af 10 // http://www.apache.org/licenses/LICENSE-2.0
maygup01 0:11cc2b7889af 11 //
maygup01 0:11cc2b7889af 12 // Unless required by applicable law or agreed to in writing, software
maygup01 0:11cc2b7889af 13 // distributed under the License is distributed on an "AS IS" BASIS,
maygup01 0:11cc2b7889af 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
maygup01 0:11cc2b7889af 15 // See the License for the specific language governing permissions and
maygup01 0:11cc2b7889af 16 // limitations under the License.
maygup01 0:11cc2b7889af 17 // ----------------------------------------------------------------------------
maygup01 0:11cc2b7889af 18 // Note: this macro is needed on armcc to get the the PRI*32 macros
maygup01 0:11cc2b7889af 19 // from inttypes.h in a C++ code.
maygup01 0:11cc2b7889af 20 #ifndef __STDC_FORMAT_MACROS
maygup01 0:11cc2b7889af 21 #define __STDC_FORMAT_MACROS
maygup01 0:11cc2b7889af 22 #endif
maygup01 0:11cc2b7889af 23
maygup01 0:11cc2b7889af 24 #include <inttypes.h>
maygup01 0:11cc2b7889af 25
maygup01 0:11cc2b7889af 26 #include "update-lwm2m-mbed-apis.h"
maygup01 0:11cc2b7889af 27 #include "update-client-common/arm_uc_common.h"
maygup01 0:11cc2b7889af 28 #include "update-client-lwm2m/lwm2m-source.h"
maygup01 0:11cc2b7889af 29 #include "update-client-lwm2m/FirmwareUpdateResource.h"
maygup01 0:11cc2b7889af 30 #include "update-client-lwm2m/DeviceMetadataResource.h"
maygup01 0:11cc2b7889af 31 #include "update-client-common/arm_uc_config.h"
maygup01 0:11cc2b7889af 32
maygup01 0:11cc2b7889af 33 /* error management */
maygup01 0:11cc2b7889af 34 static arm_uc_error_t arm_ucs_lwm2m_error = {ERR_NONE};
maygup01 0:11cc2b7889af 35 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetError(void) { return arm_ucs_lwm2m_error; }
maygup01 0:11cc2b7889af 36 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_SetError(arm_uc_error_t an_error) { return (arm_ucs_lwm2m_error = an_error); }
maygup01 0:11cc2b7889af 37
maygup01 0:11cc2b7889af 38 /* forward declaration */
maygup01 0:11cc2b7889af 39 static void ARM_UCS_PackageCallback(const uint8_t *buffer, uint16_t length);
maygup01 0:11cc2b7889af 40
maygup01 0:11cc2b7889af 41 /* local copy of the received manifest */
maygup01 0:11cc2b7889af 42 static uint8_t *arm_ucs_manifest_buffer = NULL;
maygup01 0:11cc2b7889af 43 static uint16_t arm_ucs_manifest_length = 0;
maygup01 0:11cc2b7889af 44
maygup01 0:11cc2b7889af 45 /* callback function pointer and struct */
maygup01 0:11cc2b7889af 46 static void (*ARM_UCS_EventHandler)(uintptr_t event) = 0;
maygup01 0:11cc2b7889af 47 static arm_uc_callback_t callbackNodeManifest = { NULL, 0, NULL, 0 };
maygup01 0:11cc2b7889af 48 static arm_uc_callback_t callbackNodeNotification = { NULL, 0, NULL, 0 };
maygup01 0:11cc2b7889af 49
maygup01 0:11cc2b7889af 50 #if defined(ARM_UC_FEATURE_FW_SOURCE_COAP) && (ARM_UC_FEATURE_FW_SOURCE_COAP == 1)
maygup01 0:11cc2b7889af 51 static bool arm_uc_get_data_request_transaction_ongoing = false;
maygup01 0:11cc2b7889af 52 static size_t arm_uc_received_file_size = 0;
maygup01 0:11cc2b7889af 53 static size_t arm_uc_total_file_size = 0;
maygup01 0:11cc2b7889af 54 static void arm_uc_get_data_req_callback(const uint8_t *buffer, size_t buffer_size, size_t total_size, bool last_block,
maygup01 0:11cc2b7889af 55 void *context);
maygup01 0:11cc2b7889af 56 static void arm_uc_get_data_req_error_callback(get_data_req_error_t error_code, void *context);
maygup01 0:11cc2b7889af 57
maygup01 0:11cc2b7889af 58 #define ARM_UCS_DEFAULT_COST (900)
maygup01 0:11cc2b7889af 59 #define ARM_UCS_HASH_LENGTH (40)
maygup01 0:11cc2b7889af 60
maygup01 0:11cc2b7889af 61 // The hub uses a double buffer system to speed up firmware download and storage
maygup01 0:11cc2b7889af 62 #define BUFFER_SIZE_MAX (ARM_UC_BUFFER_SIZE / 2) // define size of the double buffers
maygup01 0:11cc2b7889af 63
maygup01 0:11cc2b7889af 64 #if BUFFER_SIZE_MAX < SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
maygup01 0:11cc2b7889af 65 #error MBED_CLOUD_CLIENT_UPDATE_BUFFER must be at least double the size of SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
maygup01 0:11cc2b7889af 66 #endif
maygup01 0:11cc2b7889af 67
maygup01 0:11cc2b7889af 68 // Set proper Storage buffer size with requirements:
maygup01 0:11cc2b7889af 69 // 1. Storage buffer size >= Block size (SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE)
maygup01 0:11cc2b7889af 70 // 1. & 2 AND is >= page size (BUFFER_SIZE_MAX)
maygup01 0:11cc2b7889af 71 // 2. & 3. AND is multiple of Block size (X * SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE)
maygup01 0:11cc2b7889af 72 #define STORAGE_BUFFER_SIZE max_storage(SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE, BUFFER_SIZE_MAX)
maygup01 0:11cc2b7889af 73 // 1. 2. 3.
maygup01 0:11cc2b7889af 74 #define max_storage(X,Y) ((X) > (Y) ? (X) : ( (Y%X==0) ? (Y) :(BLOCK_MULTIPLIER(X,Y)*X)))
maygup01 0:11cc2b7889af 75
maygup01 0:11cc2b7889af 76 #define BLOCK_MULTIPLIER(X,Y) ((Y/X)+1)
maygup01 0:11cc2b7889af 77
maygup01 0:11cc2b7889af 78 static uint8_t storage_message[STORAGE_BUFFER_SIZE];
maygup01 0:11cc2b7889af 79 static arm_uc_buffer_t storage_buffer = {
maygup01 0:11cc2b7889af 80 .size_max = STORAGE_BUFFER_SIZE,
maygup01 0:11cc2b7889af 81 .size = 0,
maygup01 0:11cc2b7889af 82 .ptr = storage_message
maygup01 0:11cc2b7889af 83 };
maygup01 0:11cc2b7889af 84
maygup01 0:11cc2b7889af 85 static arm_uc_buffer_t *output_buffer_ptr = NULL;
maygup01 0:11cc2b7889af 86 static char *copy_full_url = NULL;
maygup01 0:11cc2b7889af 87 static DownloadType download_type = FIRMWARE_DOWNLOAD; //default FIRMWARE = COAP download using filepath of server;
maygup01 0:11cc2b7889af 88
maygup01 0:11cc2b7889af 89 #endif // ARM_UC_FEATURE_FW_SOURCE_COAP
maygup01 0:11cc2b7889af 90
maygup01 0:11cc2b7889af 91 /**
maygup01 0:11cc2b7889af 92 * @brief Get driver version.
maygup01 0:11cc2b7889af 93 * @return Driver version.
maygup01 0:11cc2b7889af 94 */
maygup01 0:11cc2b7889af 95 uint32_t ARM_UCS_LWM2M_SOURCE_GetVersion(void)
maygup01 0:11cc2b7889af 96 {
maygup01 0:11cc2b7889af 97 return 0;
maygup01 0:11cc2b7889af 98 }
maygup01 0:11cc2b7889af 99
maygup01 0:11cc2b7889af 100 /**
maygup01 0:11cc2b7889af 101 * @brief Get Source capabilities.
maygup01 0:11cc2b7889af 102 * @return Struct containing capabilites. See definition above.
maygup01 0:11cc2b7889af 103 */
maygup01 0:11cc2b7889af 104 ARM_SOURCE_CAPABILITIES ARM_UCS_LWM2M_SOURCE_GetCapabilities(void)
maygup01 0:11cc2b7889af 105 {
maygup01 0:11cc2b7889af 106 ARM_SOURCE_CAPABILITIES result;
maygup01 0:11cc2b7889af 107 UC_SRCE_TRACE("ARM_UCS_LWM2M_SOURCE_GetCapabilities:");
maygup01 0:11cc2b7889af 108
maygup01 0:11cc2b7889af 109 result.notify = 0;
maygup01 0:11cc2b7889af 110 result.manifest_default = 0;
maygup01 0:11cc2b7889af 111 result.manifest_url = 0;
maygup01 0:11cc2b7889af 112 result.firmware = 0;
maygup01 0:11cc2b7889af 113 result.keytable = 0;
maygup01 0:11cc2b7889af 114
maygup01 0:11cc2b7889af 115 /* the event handler must be set before module can be used */
maygup01 0:11cc2b7889af 116 if (ARM_UCS_EventHandler != 0) {
maygup01 0:11cc2b7889af 117 result.notify = 1;
maygup01 0:11cc2b7889af 118 result.manifest_default = 1;
maygup01 0:11cc2b7889af 119 result.manifest_url = 1;
maygup01 0:11cc2b7889af 120 #if defined(ARM_UC_FEATURE_FW_SOURCE_COAP) && (ARM_UC_FEATURE_FW_SOURCE_COAP == 1)
maygup01 0:11cc2b7889af 121 result.firmware = 1;
maygup01 0:11cc2b7889af 122 #endif
maygup01 0:11cc2b7889af 123 result.keytable = 1;
maygup01 0:11cc2b7889af 124 }
maygup01 0:11cc2b7889af 125
maygup01 0:11cc2b7889af 126 return result;
maygup01 0:11cc2b7889af 127 }
maygup01 0:11cc2b7889af 128
maygup01 0:11cc2b7889af 129 /**
maygup01 0:11cc2b7889af 130 * @brief Initialize Source.
maygup01 0:11cc2b7889af 131 * @details Function pointer to event handler is passed as argument.
maygup01 0:11cc2b7889af 132 *
maygup01 0:11cc2b7889af 133 * @param cb_event Function pointer to event handler. See events above.
maygup01 0:11cc2b7889af 134 * @return Error code.
maygup01 0:11cc2b7889af 135 */
maygup01 0:11cc2b7889af 136 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_Initialize(ARM_SOURCE_SignalEvent_t cb_event)
maygup01 0:11cc2b7889af 137 {
maygup01 0:11cc2b7889af 138 UC_SRCE_TRACE("ARM_UCS_LWM2M_SOURCE_Initialize: %p", cb_event);
maygup01 0:11cc2b7889af 139 ARM_UC_INIT_ERROR(result, SRCE_ERR_INVALID_PARAMETER);
maygup01 0:11cc2b7889af 140
maygup01 0:11cc2b7889af 141 #if defined(ARM_UC_FEATURE_FW_SOURCE_COAP) && (ARM_UC_FEATURE_FW_SOURCE_COAP == 1)
maygup01 0:11cc2b7889af 142 arm_uc_get_data_request_transaction_ongoing = false;
maygup01 0:11cc2b7889af 143 arm_uc_received_file_size = 0;
maygup01 0:11cc2b7889af 144 arm_uc_total_file_size = 0;
maygup01 0:11cc2b7889af 145 #endif
maygup01 0:11cc2b7889af 146
maygup01 0:11cc2b7889af 147 if (cb_event != 0) {
maygup01 0:11cc2b7889af 148 /* store callback handler */
maygup01 0:11cc2b7889af 149 ARM_UCS_EventHandler = cb_event;
maygup01 0:11cc2b7889af 150
maygup01 0:11cc2b7889af 151 /* Initialize LWM2M Firmware Update Object */
maygup01 0:11cc2b7889af 152 FirmwareUpdateResource::Initialize();
maygup01 0:11cc2b7889af 153
maygup01 0:11cc2b7889af 154 /* Register callback handler */
maygup01 0:11cc2b7889af 155 FirmwareUpdateResource::addPackageCallback(ARM_UCS_PackageCallback);
maygup01 0:11cc2b7889af 156
maygup01 0:11cc2b7889af 157 DeviceMetadataResource::Initialize();
maygup01 0:11cc2b7889af 158
maygup01 0:11cc2b7889af 159 ARM_UC_SET_ERROR(result, ERR_NONE);
maygup01 0:11cc2b7889af 160 }
maygup01 0:11cc2b7889af 161
maygup01 0:11cc2b7889af 162 if (ARM_UC_IS_ERROR(result)) {
maygup01 0:11cc2b7889af 163 ARM_UCS_LWM2M_SOURCE_SetError(result);
maygup01 0:11cc2b7889af 164 }
maygup01 0:11cc2b7889af 165 return result;
maygup01 0:11cc2b7889af 166 }
maygup01 0:11cc2b7889af 167
maygup01 0:11cc2b7889af 168 /**
maygup01 0:11cc2b7889af 169 * @brief Uninitialized Source.
maygup01 0:11cc2b7889af 170 * @return Error code.
maygup01 0:11cc2b7889af 171 */
maygup01 0:11cc2b7889af 172 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_Uninitialize(void)
maygup01 0:11cc2b7889af 173 {
maygup01 0:11cc2b7889af 174 ARM_UC_INIT_ERROR(retval, ERR_NONE);
maygup01 0:11cc2b7889af 175 DeviceMetadataResource::Uninitialize();
maygup01 0:11cc2b7889af 176 FirmwareUpdateResource::Uninitialize();
maygup01 0:11cc2b7889af 177
maygup01 0:11cc2b7889af 178 return retval;
maygup01 0:11cc2b7889af 179 }
maygup01 0:11cc2b7889af 180
maygup01 0:11cc2b7889af 181 /**
maygup01 0:11cc2b7889af 182 * @brief Cost estimation for retrieving manifest from the default location.
maygup01 0:11cc2b7889af 183 * @details The estimation can vary over time and should not be cached too long.
maygup01 0:11cc2b7889af 184 * 0x00000000 - The manifest is already downloaded.
maygup01 0:11cc2b7889af 185 * 0xFFFFFFFF - Cannot retrieve manifest from this Source.
maygup01 0:11cc2b7889af 186 *
maygup01 0:11cc2b7889af 187 * @param cost Pointer to variable for the return value.
maygup01 0:11cc2b7889af 188 * @return Error code.
maygup01 0:11cc2b7889af 189 */
maygup01 0:11cc2b7889af 190 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetManifestDefaultCost(uint32_t *cost)
maygup01 0:11cc2b7889af 191 {
maygup01 0:11cc2b7889af 192 ARM_UC_INIT_ERROR(result, SRCE_ERR_INVALID_PARAMETER);
maygup01 0:11cc2b7889af 193
maygup01 0:11cc2b7889af 194 if (cost != 0) {
maygup01 0:11cc2b7889af 195 /* set cost to 0 when manifest is cached */
maygup01 0:11cc2b7889af 196 if (arm_ucs_manifest_buffer && arm_ucs_manifest_length) {
maygup01 0:11cc2b7889af 197 *cost = 0;
maygup01 0:11cc2b7889af 198 }
maygup01 0:11cc2b7889af 199 /* set cost to 0xFFFFFFFF when manifest has been read */
maygup01 0:11cc2b7889af 200 else {
maygup01 0:11cc2b7889af 201 *cost = 0xFFFFFFFF;
maygup01 0:11cc2b7889af 202 }
maygup01 0:11cc2b7889af 203
maygup01 0:11cc2b7889af 204 ARM_UC_SET_ERROR(result, ERR_NONE);
maygup01 0:11cc2b7889af 205 }
maygup01 0:11cc2b7889af 206
maygup01 0:11cc2b7889af 207 if (ARM_UC_IS_ERROR(result)) {
maygup01 0:11cc2b7889af 208 ARM_UCS_LWM2M_SOURCE_SetError(result);
maygup01 0:11cc2b7889af 209 }
maygup01 0:11cc2b7889af 210 return result;
maygup01 0:11cc2b7889af 211 }
maygup01 0:11cc2b7889af 212
maygup01 0:11cc2b7889af 213 /**
maygup01 0:11cc2b7889af 214 * @brief Retrieve manifest from the default location.
maygup01 0:11cc2b7889af 215 * @details Manifest is stored in supplied buffer.
maygup01 0:11cc2b7889af 216 * Event is generated once manifest is in buffer.
maygup01 0:11cc2b7889af 217 *
maygup01 0:11cc2b7889af 218 * @param buffer Struct containing byte array, maximum size, and actual size.
maygup01 0:11cc2b7889af 219 * @return Error code.
maygup01 0:11cc2b7889af 220 */
maygup01 0:11cc2b7889af 221 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetManifestDefault(arm_uc_buffer_t *buffer,
maygup01 0:11cc2b7889af 222 uint32_t offset)
maygup01 0:11cc2b7889af 223 {
maygup01 0:11cc2b7889af 224 ARM_UC_INIT_ERROR(result, SRCE_ERR_INVALID_PARAMETER);
maygup01 0:11cc2b7889af 225
maygup01 0:11cc2b7889af 226 /* copy manifest from cache into buffer */
maygup01 0:11cc2b7889af 227 if ((buffer != NULL) &&
maygup01 0:11cc2b7889af 228 (buffer->ptr != NULL) &&
maygup01 0:11cc2b7889af 229 (arm_ucs_manifest_buffer != NULL) &&
maygup01 0:11cc2b7889af 230 (arm_ucs_manifest_length != 0) &&
maygup01 0:11cc2b7889af 231 (offset < arm_ucs_manifest_length)) {
maygup01 0:11cc2b7889af 232 /* remaining length based on offset request */
maygup01 0:11cc2b7889af 233 uint16_t length = arm_ucs_manifest_length - offset;
maygup01 0:11cc2b7889af 234
maygup01 0:11cc2b7889af 235 /* set actual length based on buffer size */
maygup01 0:11cc2b7889af 236 if (length > buffer->size_max) {
maygup01 0:11cc2b7889af 237 length = buffer->size_max;
maygup01 0:11cc2b7889af 238 }
maygup01 0:11cc2b7889af 239
maygup01 0:11cc2b7889af 240 /* size check */
maygup01 0:11cc2b7889af 241 if (length > 0) {
maygup01 0:11cc2b7889af 242 /* copy manifest from local buffer to external buffer */
maygup01 0:11cc2b7889af 243 memcpy(buffer->ptr, &arm_ucs_manifest_buffer[offset], length);
maygup01 0:11cc2b7889af 244 buffer->size = length;
maygup01 0:11cc2b7889af 245
maygup01 0:11cc2b7889af 246 /* delete local buffer once the entire manifest has been read */
maygup01 0:11cc2b7889af 247 if (offset + length >= arm_ucs_manifest_length) {
maygup01 0:11cc2b7889af 248 delete[] arm_ucs_manifest_buffer;
maygup01 0:11cc2b7889af 249 arm_ucs_manifest_buffer = NULL;
maygup01 0:11cc2b7889af 250 arm_ucs_manifest_length = 0;
maygup01 0:11cc2b7889af 251 }
maygup01 0:11cc2b7889af 252
maygup01 0:11cc2b7889af 253 ARM_UC_SET_ERROR(result, ERR_NONE);
maygup01 0:11cc2b7889af 254
maygup01 0:11cc2b7889af 255 /* signal event handler that manifest has been copied to buffer */
maygup01 0:11cc2b7889af 256 if (ARM_UCS_EventHandler) {
maygup01 0:11cc2b7889af 257 ARM_UC_PostCallback(&callbackNodeManifest,
maygup01 0:11cc2b7889af 258 ARM_UCS_EventHandler,
maygup01 0:11cc2b7889af 259 EVENT_MANIFEST);
maygup01 0:11cc2b7889af 260 }
maygup01 0:11cc2b7889af 261 }
maygup01 0:11cc2b7889af 262 }
maygup01 0:11cc2b7889af 263
maygup01 0:11cc2b7889af 264 if (ARM_UC_IS_ERROR(result)) {
maygup01 0:11cc2b7889af 265 ARM_UCS_LWM2M_SOURCE_SetError(result);
maygup01 0:11cc2b7889af 266 }
maygup01 0:11cc2b7889af 267 return result;
maygup01 0:11cc2b7889af 268 }
maygup01 0:11cc2b7889af 269
maygup01 0:11cc2b7889af 270 static void ARM_UCS_PackageCallback(const uint8_t *buffer, uint16_t length)
maygup01 0:11cc2b7889af 271 {
maygup01 0:11cc2b7889af 272 uint32_t event_code = EVENT_ERROR;
maygup01 0:11cc2b7889af 273
maygup01 0:11cc2b7889af 274 if (arm_ucs_manifest_buffer) {
maygup01 0:11cc2b7889af 275 UC_SRCE_ERR_MSG("received new manifest before reading the old one");
maygup01 0:11cc2b7889af 276
maygup01 0:11cc2b7889af 277 /* delete old buffer to make space for the new one */
maygup01 0:11cc2b7889af 278 delete[] arm_ucs_manifest_buffer;
maygup01 0:11cc2b7889af 279 arm_ucs_manifest_length = 0;
maygup01 0:11cc2b7889af 280 }
maygup01 0:11cc2b7889af 281
maygup01 0:11cc2b7889af 282 /* allocate a local buffer of the same size as the manifest */
maygup01 0:11cc2b7889af 283 arm_ucs_manifest_buffer = new uint8_t[length];
maygup01 0:11cc2b7889af 284
maygup01 0:11cc2b7889af 285 if (arm_ucs_manifest_buffer) {
maygup01 0:11cc2b7889af 286 /* copy manifest from payload to local buffer */
maygup01 0:11cc2b7889af 287 memcpy(arm_ucs_manifest_buffer, buffer, length);
maygup01 0:11cc2b7889af 288 arm_ucs_manifest_length = length;
maygup01 0:11cc2b7889af 289
maygup01 0:11cc2b7889af 290 event_code = EVENT_NOTIFICATION;
maygup01 0:11cc2b7889af 291 }
maygup01 0:11cc2b7889af 292
maygup01 0:11cc2b7889af 293 /* signal event handler with result */
maygup01 0:11cc2b7889af 294 if (ARM_UCS_EventHandler) {
maygup01 0:11cc2b7889af 295 ARM_UC_PostCallback(&callbackNodeNotification,
maygup01 0:11cc2b7889af 296 ARM_UCS_EventHandler,
maygup01 0:11cc2b7889af 297 event_code);
maygup01 0:11cc2b7889af 298 }
maygup01 0:11cc2b7889af 299 }
maygup01 0:11cc2b7889af 300
maygup01 0:11cc2b7889af 301
maygup01 0:11cc2b7889af 302 /**
maygup01 0:11cc2b7889af 303 * @brief Cost estimation for retrieving firmware from URL.
maygup01 0:11cc2b7889af 304 * @details The estimation can vary over time and should not be cached too long.
maygup01 0:11cc2b7889af 305 * 0x00000000 - The firmware is already downloaded.
maygup01 0:11cc2b7889af 306 * 0xFFFFFFFF - Cannot retrieve firmware from this Source.
maygup01 0:11cc2b7889af 307 *
maygup01 0:11cc2b7889af 308 * @param uri URI struct with firmware location.
maygup01 0:11cc2b7889af 309 * @param cost Pointer to variable for the return value.
maygup01 0:11cc2b7889af 310 * @return Error code.
maygup01 0:11cc2b7889af 311 */
maygup01 0:11cc2b7889af 312 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetFirmwareURLCost(arm_uc_uri_t *uri,
maygup01 0:11cc2b7889af 313 uint32_t *cost)
maygup01 0:11cc2b7889af 314 {
maygup01 0:11cc2b7889af 315 UC_SRCE_TRACE("ARM_UCS_LWM2M_SOURCE_GetFirmwareURLCost");
maygup01 0:11cc2b7889af 316
maygup01 0:11cc2b7889af 317 ARM_UC_INIT_ERROR(result, SRCE_ERR_INVALID_PARAMETER);
maygup01 0:11cc2b7889af 318
maygup01 0:11cc2b7889af 319 #if defined(ARM_UC_FEATURE_FW_SOURCE_COAP) && (ARM_UC_FEATURE_FW_SOURCE_COAP == 1)
maygup01 0:11cc2b7889af 320 /* not supported - return default cost regardless of actual uri location */
maygup01 0:11cc2b7889af 321 if ((uri != 0) && (cost != 0)) {
maygup01 0:11cc2b7889af 322 UC_SRCE_TRACE("ARM_UCS_LWM2M_SOURCE_GetFirmwareURLCost uri and cost");
maygup01 0:11cc2b7889af 323 *cost = ARM_UCS_DEFAULT_COST;
maygup01 0:11cc2b7889af 324 result.code = ERR_NONE ;
maygup01 0:11cc2b7889af 325 }
maygup01 0:11cc2b7889af 326 #else
maygup01 0:11cc2b7889af 327 /* not supported */
maygup01 0:11cc2b7889af 328 if (cost != 0) {
maygup01 0:11cc2b7889af 329 UC_SRCE_TRACE("ARM_UCS_LWM2M_SOURCE_GetFirmwareURLCost cost 0xFFFFFFFF");
maygup01 0:11cc2b7889af 330 *cost = 0xFFFFFFFF;
maygup01 0:11cc2b7889af 331 result.code = ERR_NONE ;
maygup01 0:11cc2b7889af 332 }
maygup01 0:11cc2b7889af 333 #endif
maygup01 0:11cc2b7889af 334 if (ARM_UC_IS_ERROR(result)) {
maygup01 0:11cc2b7889af 335 ARM_UCS_LWM2M_SOURCE_SetError(result);
maygup01 0:11cc2b7889af 336 }
maygup01 0:11cc2b7889af 337 return result;
maygup01 0:11cc2b7889af 338 }
maygup01 0:11cc2b7889af 339
maygup01 0:11cc2b7889af 340
maygup01 0:11cc2b7889af 341 /**
maygup01 0:11cc2b7889af 342 * @brief Retrieve firmware fragment.
maygup01 0:11cc2b7889af 343 * @details Firmware fragment is stored in supplied buffer.
maygup01 0:11cc2b7889af 344 * Event is generated once fragment is in buffer.
maygup01 0:11cc2b7889af 345 *
maygup01 0:11cc2b7889af 346 * @param uri URI struct with firmware location.
maygup01 0:11cc2b7889af 347 * @param buffer Struct containing byte array, maximum size, and actual size.
maygup01 0:11cc2b7889af 348 * @param offset Firmware offset to retrieve fragment from.
maygup01 0:11cc2b7889af 349 * @return Error code.
maygup01 0:11cc2b7889af 350 */
maygup01 0:11cc2b7889af 351 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetFirmwareFragment(arm_uc_uri_t *uri,
maygup01 0:11cc2b7889af 352 arm_uc_buffer_t *buffer,
maygup01 0:11cc2b7889af 353 uint32_t offset)
maygup01 0:11cc2b7889af 354 {
maygup01 0:11cc2b7889af 355
maygup01 0:11cc2b7889af 356 arm_uc_error_t retval = { .code = SRCE_ERR_INVALID_PARAMETER };
maygup01 0:11cc2b7889af 357 #if defined(ARM_UC_FEATURE_FW_SOURCE_COAP) && (ARM_UC_FEATURE_FW_SOURCE_COAP == 1)
maygup01 0:11cc2b7889af 358 if (uri == NULL || buffer == NULL || FirmwareUpdateResource::getM2MInterface() == NULL) {
maygup01 0:11cc2b7889af 359 return retval;
maygup01 0:11cc2b7889af 360 }
maygup01 0:11cc2b7889af 361
maygup01 0:11cc2b7889af 362 UC_SRCE_TRACE("ARM_UCS_LWM2M_SOURCE_GetFirmwareFragment: %s %s, buffer size: %" PRIu32 ", buffer max: %" PRIu32
maygup01 0:11cc2b7889af 363 " offset: %" PRIu32, (const char *)uri->ptr, uri->path, buffer->size, buffer->size_max, offset);
maygup01 0:11cc2b7889af 364 UC_SRCE_TRACE("ARM_UCS_LWM2M_SOURCE_GetFirmwareFragment: total file size %" PRIu32 ", received file size %" PRIu32,
maygup01 0:11cc2b7889af 365 (uint32_t)arm_uc_total_file_size, (uint32_t)arm_uc_received_file_size);
maygup01 0:11cc2b7889af 366
maygup01 0:11cc2b7889af 367 /*
maygup01 0:11cc2b7889af 368 * NOTE: we are using M2MInterface API "get_data_request()" asynchronously, so first call to GetFirmwareFragment()
maygup01 0:11cc2b7889af 369 * will not return anything in the buffer. Instead we will get COAP blocks into callback arm_uc_get_data_req_callback()
maygup01 0:11cc2b7889af 370 * where we will copy those to our internal storage_buffer. When storage_buffer has enough data
maygup01 0:11cc2b7889af 371 * (more or eq than buffer->size_max == Storage Page size) we will copy data from it to output buffer
maygup01 0:11cc2b7889af 372 * and indicate to Hub state machine using event EVENT_FIRMWARE
maygup01 0:11cc2b7889af 373 */
maygup01 0:11cc2b7889af 374 if (offset == 0) {
maygup01 0:11cc2b7889af 375 // First fragment
maygup01 0:11cc2b7889af 376 storage_buffer.size = 0;
maygup01 0:11cc2b7889af 377 arm_uc_received_file_size = 0;
maygup01 0:11cc2b7889af 378 arm_uc_total_file_size = 0;
maygup01 0:11cc2b7889af 379 } else if (arm_uc_received_file_size == 0) {
maygup01 0:11cc2b7889af 380 // The received file size was reset to zero indicating that we have received the full payload
maygup01 0:11cc2b7889af 381 // as indicated by the server but we are asked to carry on downloading from the given offset.
maygup01 0:11cc2b7889af 382 // This indicates a mismatch between the actual payload size in the server and that given in the manifest.
maygup01 0:11cc2b7889af 383 UC_SRCE_TRACE("ARM_UCS_LWM2M_SOURCE_GetFirmwareFragment: payload size indicated in manifest is bigger than that reported by server!");
maygup01 0:11cc2b7889af 384 if (ARM_UCS_EventHandler) {
maygup01 0:11cc2b7889af 385 ARM_UC_PostCallback(&callbackNodeManifest,
maygup01 0:11cc2b7889af 386 ARM_UCS_EventHandler,
maygup01 0:11cc2b7889af 387 EVENT_ERROR);
maygup01 0:11cc2b7889af 388 }
maygup01 0:11cc2b7889af 389 return retval;
maygup01 0:11cc2b7889af 390 }
maygup01 0:11cc2b7889af 391
maygup01 0:11cc2b7889af 392 output_buffer_ptr = buffer;
maygup01 0:11cc2b7889af 393 free(copy_full_url);
maygup01 0:11cc2b7889af 394 copy_full_url = (char *)malloc(arm_uc_calculate_full_uri_length(uri));
maygup01 0:11cc2b7889af 395 if (copy_full_url == NULL) {
maygup01 0:11cc2b7889af 396 //TODO to return SRCE_ERR_OUT_OF_MEMORY
maygup01 0:11cc2b7889af 397 UC_SRCE_TRACE("ARM_UCS_LWM2M_SOURCE_GetFirmwareFragment: ERROR OUT OF MEMORY for uri copy!");
maygup01 0:11cc2b7889af 398 return retval;
maygup01 0:11cc2b7889af 399 }
maygup01 0:11cc2b7889af 400 if (uri->scheme == URI_SCHEME_COAPS) {
maygup01 0:11cc2b7889af 401 strcpy(copy_full_url, UC_COAPS_STRING);
maygup01 0:11cc2b7889af 402 } else if (uri->scheme == URI_SCHEME_HTTP) {
maygup01 0:11cc2b7889af 403 strcpy(copy_full_url, UC_HTTP_STRING);
maygup01 0:11cc2b7889af 404 } else {
maygup01 0:11cc2b7889af 405 UC_SRCE_TRACE("ARM_UCS_LWM2M_SOURCE_GetFirmwareFragment: Not Supported SCHEME! length of copy url: %u",
maygup01 0:11cc2b7889af 406 sizeof(copy_full_url));
maygup01 0:11cc2b7889af 407 return retval;
maygup01 0:11cc2b7889af 408 }
maygup01 0:11cc2b7889af 409 strcat(copy_full_url, (const char *)uri->ptr);
maygup01 0:11cc2b7889af 410 strcat(copy_full_url, uri->path);
maygup01 0:11cc2b7889af 411
maygup01 0:11cc2b7889af 412 if ((arm_uc_received_file_size == arm_uc_total_file_size &&
maygup01 0:11cc2b7889af 413 arm_uc_received_file_size != 0)) {
maygup01 0:11cc2b7889af 414
maygup01 0:11cc2b7889af 415 // If last block - write to buffer and complete
maygup01 0:11cc2b7889af 416 if (storage_buffer.ptr &&
maygup01 0:11cc2b7889af 417 (arm_uc_received_file_size == arm_uc_total_file_size)) {
maygup01 0:11cc2b7889af 418 memcpy(buffer->ptr, storage_buffer.ptr, storage_buffer.size);
maygup01 0:11cc2b7889af 419 buffer->size = storage_buffer.size;
maygup01 0:11cc2b7889af 420 memmove(storage_buffer.ptr, storage_buffer.ptr + storage_buffer.size, (storage_buffer.size_max - storage_buffer.size));
maygup01 0:11cc2b7889af 421 storage_buffer.size -= buffer->size;
maygup01 0:11cc2b7889af 422 }
maygup01 0:11cc2b7889af 423
maygup01 0:11cc2b7889af 424 // We were waiting for one more state machine cycle for previous write to complete
maygup01 0:11cc2b7889af 425 // Now we can return with EVENT_FIRMWARE so that main state machine changes properly
maygup01 0:11cc2b7889af 426 if (ARM_UCS_EventHandler) {
maygup01 0:11cc2b7889af 427 ARM_UC_PostCallback(&callbackNodeManifest,
maygup01 0:11cc2b7889af 428 ARM_UCS_EventHandler,
maygup01 0:11cc2b7889af 429 EVENT_FIRMWARE);
maygup01 0:11cc2b7889af 430 }
maygup01 0:11cc2b7889af 431 retval.code = ERR_NONE;
maygup01 0:11cc2b7889af 432 arm_uc_received_file_size = 0;
maygup01 0:11cc2b7889af 433 arm_uc_total_file_size = 0;
maygup01 0:11cc2b7889af 434 } else if (!arm_uc_get_data_request_transaction_ongoing) {
maygup01 0:11cc2b7889af 435 // We need to get request for next block of data
maygup01 0:11cc2b7889af 436 UC_SRCE_TRACE("ARM_UCS_LWM2M_SOURCE_GetFirmwareFragment: Issue new get request for uri: %s, offset: %" PRIu32,
maygup01 0:11cc2b7889af 437 copy_full_url, (uint32_t)arm_uc_received_file_size);
maygup01 0:11cc2b7889af 438 if (FirmwareUpdateResource::getM2MInterface()) {
maygup01 0:11cc2b7889af 439
maygup01 0:11cc2b7889af 440 FirmwareUpdateResource::getM2MInterface()->get_data_request(download_type,
maygup01 0:11cc2b7889af 441 copy_full_url,
maygup01 0:11cc2b7889af 442 arm_uc_received_file_size,
maygup01 0:11cc2b7889af 443 true,
maygup01 0:11cc2b7889af 444 arm_uc_get_data_req_callback,
maygup01 0:11cc2b7889af 445 arm_uc_get_data_req_error_callback,
maygup01 0:11cc2b7889af 446 FirmwareUpdateResource::getM2MInterface());
maygup01 0:11cc2b7889af 447
maygup01 0:11cc2b7889af 448 arm_uc_get_data_request_transaction_ongoing = true;
maygup01 0:11cc2b7889af 449
maygup01 0:11cc2b7889af 450 retval.code = ERR_NONE;
maygup01 0:11cc2b7889af 451 }
maygup01 0:11cc2b7889af 452 } else {
maygup01 0:11cc2b7889af 453 // There is not enough data in Storage buffer yet
maygup01 0:11cc2b7889af 454 // AND We have Async get_data_request already ongoing
maygup01 0:11cc2b7889af 455 // -> Do nothing we should not get here?
maygup01 0:11cc2b7889af 456 // This can happen if GetFirmwareFragment is called again before
maygup01 0:11cc2b7889af 457 // the previous get completed with buffer and EVENT_FIRMWARE
maygup01 0:11cc2b7889af 458 UC_SRCE_ERR_MSG("Internal error: BLOCK - data request already ongoing");
maygup01 0:11cc2b7889af 459 }
maygup01 0:11cc2b7889af 460 if (ARM_UC_IS_ERROR(retval)) {
maygup01 0:11cc2b7889af 461 ARM_UCS_LWM2M_SOURCE_SetError(retval);
maygup01 0:11cc2b7889af 462 }
maygup01 0:11cc2b7889af 463 return retval;
maygup01 0:11cc2b7889af 464 #else
maygup01 0:11cc2b7889af 465 (void) uri;
maygup01 0:11cc2b7889af 466 (void) buffer;
maygup01 0:11cc2b7889af 467 (void) offset;
maygup01 0:11cc2b7889af 468 return retval;
maygup01 0:11cc2b7889af 469 #endif //ARM_UC_FEATURE_FW_SOURCE_COAP
maygup01 0:11cc2b7889af 470 }
maygup01 0:11cc2b7889af 471
maygup01 0:11cc2b7889af 472 #if defined(ARM_UC_FEATURE_FW_SOURCE_COAP) && (ARM_UC_FEATURE_FW_SOURCE_COAP == 1)
maygup01 0:11cc2b7889af 473 void arm_uc_get_data_req_callback(const uint8_t *buffer, size_t buffer_size, size_t total_size, bool last_block,
maygup01 0:11cc2b7889af 474 void *context)
maygup01 0:11cc2b7889af 475 {
maygup01 0:11cc2b7889af 476 (void)last_block;
maygup01 0:11cc2b7889af 477
maygup01 0:11cc2b7889af 478 UC_SRCE_TRACE("get_data_req_callback: %" PRIu32 ", %" PRIu32, (uint32_t)buffer_size, (uint32_t)total_size);
maygup01 0:11cc2b7889af 479 M2MInterface *interface = (M2MInterface *)context;
maygup01 0:11cc2b7889af 480
maygup01 0:11cc2b7889af 481 if (arm_uc_received_file_size == 0) {
maygup01 0:11cc2b7889af 482 arm_uc_total_file_size = total_size;
maygup01 0:11cc2b7889af 483 }
maygup01 0:11cc2b7889af 484
maygup01 0:11cc2b7889af 485 arm_uc_received_file_size += buffer_size;
maygup01 0:11cc2b7889af 486 UC_SRCE_TRACE("get_data_req_callback: received %" PRIu32 "/%" PRIu32, (uint32_t)arm_uc_received_file_size,
maygup01 0:11cc2b7889af 487 (uint32_t)arm_uc_total_file_size);
maygup01 0:11cc2b7889af 488
maygup01 0:11cc2b7889af 489 if (arm_uc_received_file_size == arm_uc_total_file_size) {
maygup01 0:11cc2b7889af 490 UC_SRCE_TRACE("get_data_req_callback: transfer completed\n");
maygup01 0:11cc2b7889af 491 }
maygup01 0:11cc2b7889af 492
maygup01 0:11cc2b7889af 493 /*
maygup01 0:11cc2b7889af 494 * FLOW:
maygup01 0:11cc2b7889af 495 * 1. If there is space in Storage buffer for the incoming buffer -> copy buffer to storage buffer
maygup01 0:11cc2b7889af 496 * 2. Else signal error event EVENT_ERROR_BUFFER_SIZE
maygup01 0:11cc2b7889af 497 */
maygup01 0:11cc2b7889af 498 // Check there is space available in the storage buffer
maygup01 0:11cc2b7889af 499 if (storage_buffer.size_max - storage_buffer.size >= buffer_size) {
maygup01 0:11cc2b7889af 500 memcpy(storage_buffer.ptr + storage_buffer.size, buffer, buffer_size);
maygup01 0:11cc2b7889af 501 storage_buffer.size += buffer_size;
maygup01 0:11cc2b7889af 502 } else {
maygup01 0:11cc2b7889af 503 // Error - no space available, signal it to source manager
maygup01 0:11cc2b7889af 504 UC_SRCE_TRACE("arm_uc_get_data_req_callback: Storage Buffer OVERFLOW ERROR!! \n");
maygup01 0:11cc2b7889af 505 if (ARM_UCS_EventHandler) {
maygup01 0:11cc2b7889af 506 ARM_UC_PostCallback(&callbackNodeManifest,
maygup01 0:11cc2b7889af 507 ARM_UCS_EventHandler,
maygup01 0:11cc2b7889af 508 EVENT_ERROR_BUFFER_SIZE);
maygup01 0:11cc2b7889af 509 }
maygup01 0:11cc2b7889af 510 return;
maygup01 0:11cc2b7889af 511 }
maygup01 0:11cc2b7889af 512
maygup01 0:11cc2b7889af 513 /*
maygup01 0:11cc2b7889af 514 * FLOW:
maygup01 0:11cc2b7889af 515 * 1. If there is enough data in storage-buffer now to complete to output buffer, copy now and indicate with EVENT_FIRMWARE
maygup01 0:11cc2b7889af 516 * to continue to write -cycle
maygup01 0:11cc2b7889af 517 * 2. Else if this is the last block of data, copy the remaining (<size_max) to output buffer and indicate with
maygup01 0:11cc2b7889af 518 * EVENT_FIRMWARE to continue to write-cycle
maygup01 0:11cc2b7889af 519 * 3. Else Request new block of data using API get_data_request
maygup01 0:11cc2b7889af 520 */
maygup01 0:11cc2b7889af 521 if (storage_buffer.size >= output_buffer_ptr->size_max) {
maygup01 0:11cc2b7889af 522 // 1. We have received into Storage buffer at least one page size of data
maygup01 0:11cc2b7889af 523 // -> Let's return it to UC Hub so that it can be written
maygup01 0:11cc2b7889af 524 UC_SRCE_TRACE("arm_uc_get_data_req_callback: return with Storage buffer size: %" PRIu32 ", buffer size: %" PRIu32,
maygup01 0:11cc2b7889af 525 storage_buffer.size, output_buffer_ptr->size_max);
maygup01 0:11cc2b7889af 526 if (storage_buffer.ptr) {
maygup01 0:11cc2b7889af 527 memcpy(output_buffer_ptr->ptr, storage_buffer.ptr, output_buffer_ptr->size_max);
maygup01 0:11cc2b7889af 528 //storage_buffer.ptr += buffer->size_max;
maygup01 0:11cc2b7889af 529 memmove(storage_buffer.ptr, storage_buffer.ptr + output_buffer_ptr->size_max,
maygup01 0:11cc2b7889af 530 (storage_buffer.size_max - output_buffer_ptr->size_max));
maygup01 0:11cc2b7889af 531 storage_buffer.size -= output_buffer_ptr->size_max;
maygup01 0:11cc2b7889af 532 output_buffer_ptr->size = output_buffer_ptr->size_max;
maygup01 0:11cc2b7889af 533 }
maygup01 0:11cc2b7889af 534
maygup01 0:11cc2b7889af 535 if (ARM_UCS_EventHandler) {
maygup01 0:11cc2b7889af 536 ARM_UC_PostCallback(&callbackNodeManifest,
maygup01 0:11cc2b7889af 537 ARM_UCS_EventHandler,
maygup01 0:11cc2b7889af 538 EVENT_FIRMWARE);
maygup01 0:11cc2b7889af 539 }
maygup01 0:11cc2b7889af 540 arm_uc_get_data_request_transaction_ongoing = false;
maygup01 0:11cc2b7889af 541 } else if (arm_uc_received_file_size == arm_uc_total_file_size &&
maygup01 0:11cc2b7889af 542 arm_uc_received_file_size != 0) {
maygup01 0:11cc2b7889af 543
maygup01 0:11cc2b7889af 544 // 2. this is the last block of data - copy to output buffer and complete with EVENT_FIRMWARE
maygup01 0:11cc2b7889af 545 if (storage_buffer.ptr &&
maygup01 0:11cc2b7889af 546 (arm_uc_received_file_size == arm_uc_total_file_size)) {
maygup01 0:11cc2b7889af 547 memcpy(output_buffer_ptr->ptr, storage_buffer.ptr, storage_buffer.size);
maygup01 0:11cc2b7889af 548 output_buffer_ptr->size = storage_buffer.size;
maygup01 0:11cc2b7889af 549
maygup01 0:11cc2b7889af 550 memmove(storage_buffer.ptr, storage_buffer.ptr + storage_buffer.size, (storage_buffer.size_max - storage_buffer.size));
maygup01 0:11cc2b7889af 551 storage_buffer.size = 0;
maygup01 0:11cc2b7889af 552 }
maygup01 0:11cc2b7889af 553
maygup01 0:11cc2b7889af 554 // We were waiting for one more state machine cycle for previous write to complete
maygup01 0:11cc2b7889af 555 // Now we can return with EVENT_FIRMWARE so that main state machine changes properly
maygup01 0:11cc2b7889af 556 if (ARM_UCS_EventHandler) {
maygup01 0:11cc2b7889af 557 ARM_UC_PostCallback(&callbackNodeManifest,
maygup01 0:11cc2b7889af 558 ARM_UCS_EventHandler,
maygup01 0:11cc2b7889af 559 EVENT_FIRMWARE);
maygup01 0:11cc2b7889af 560 }
maygup01 0:11cc2b7889af 561 arm_uc_get_data_request_transaction_ongoing = false;
maygup01 0:11cc2b7889af 562 free(copy_full_url);
maygup01 0:11cc2b7889af 563 copy_full_url = NULL;
maygup01 0:11cc2b7889af 564 arm_uc_received_file_size = 0;
maygup01 0:11cc2b7889af 565 arm_uc_total_file_size = 0;
maygup01 0:11cc2b7889af 566 } else {
maygup01 0:11cc2b7889af 567 // 3. We want to issue new get data
maygup01 0:11cc2b7889af 568 UC_SRCE_TRACE("arm_uc_get_data_req_callback: Issue new get request for uri: %s, offset: %" PRIu32, copy_full_url,
maygup01 0:11cc2b7889af 569 (uint32_t)arm_uc_received_file_size);
maygup01 0:11cc2b7889af 570 interface->get_data_request(download_type,
maygup01 0:11cc2b7889af 571 copy_full_url,
maygup01 0:11cc2b7889af 572 arm_uc_received_file_size,
maygup01 0:11cc2b7889af 573 true,
maygup01 0:11cc2b7889af 574 arm_uc_get_data_req_callback,
maygup01 0:11cc2b7889af 575 arm_uc_get_data_req_error_callback,
maygup01 0:11cc2b7889af 576 interface);
maygup01 0:11cc2b7889af 577 arm_uc_get_data_request_transaction_ongoing = true;
maygup01 0:11cc2b7889af 578 }
maygup01 0:11cc2b7889af 579 #ifdef ARM_UC_COAP_DATA_PRINTOUT
maygup01 0:11cc2b7889af 580 if (buffer) {
maygup01 0:11cc2b7889af 581 uint32_t i = 0;
maygup01 0:11cc2b7889af 582 int row_len = 40;
maygup01 0:11cc2b7889af 583 uint32_t max_length = 2048;
maygup01 0:11cc2b7889af 584
maygup01 0:11cc2b7889af 585 while (i < buffer_size && i < max_length) {
maygup01 0:11cc2b7889af 586 if (i + row_len > buffer_size) {
maygup01 0:11cc2b7889af 587 row_len = buffer_size - i;
maygup01 0:11cc2b7889af 588 }
maygup01 0:11cc2b7889af 589 UC_SRCE_TRACE("Payload:\t\t%s", tr_array(buffer + i, row_len)); // in HEX
maygup01 0:11cc2b7889af 590
maygup01 0:11cc2b7889af 591 i += row_len;
maygup01 0:11cc2b7889af 592 }
maygup01 0:11cc2b7889af 593
maygup01 0:11cc2b7889af 594 }
maygup01 0:11cc2b7889af 595 #endif
maygup01 0:11cc2b7889af 596 }
maygup01 0:11cc2b7889af 597
maygup01 0:11cc2b7889af 598 void arm_uc_get_data_req_error_callback(get_data_req_error_t error_code, void *context)
maygup01 0:11cc2b7889af 599 {
maygup01 0:11cc2b7889af 600 UC_SRCE_TRACE("get_data_req_error_callback: ERROR: %u\n", error_code);
maygup01 0:11cc2b7889af 601 arm_uc_received_file_size = 0;
maygup01 0:11cc2b7889af 602 arm_uc_total_file_size = 0;
maygup01 0:11cc2b7889af 603 arm_uc_get_data_request_transaction_ongoing = false;
maygup01 0:11cc2b7889af 604 free(copy_full_url);
maygup01 0:11cc2b7889af 605 copy_full_url = NULL;
maygup01 0:11cc2b7889af 606 download_type = FIRMWARE_DOWNLOAD;
maygup01 0:11cc2b7889af 607 if (ARM_UCS_EventHandler) {
maygup01 0:11cc2b7889af 608 ARM_UC_PostCallback(&callbackNodeManifest,
maygup01 0:11cc2b7889af 609 ARM_UCS_EventHandler,
maygup01 0:11cc2b7889af 610 EVENT_ERROR);
maygup01 0:11cc2b7889af 611 }
maygup01 0:11cc2b7889af 612 }
maygup01 0:11cc2b7889af 613 #endif //ARM_UC_FEATURE_FW_SOURCE_COAP
maygup01 0:11cc2b7889af 614
maygup01 0:11cc2b7889af 615 /*****************************************************************************/
maygup01 0:11cc2b7889af 616 /* Capabilities not supported by this source */
maygup01 0:11cc2b7889af 617 /*****************************************************************************/
maygup01 0:11cc2b7889af 618
maygup01 0:11cc2b7889af 619 /**
maygup01 0:11cc2b7889af 620 * @brief Cost estimation for retrieving manifest from URL.
maygup01 0:11cc2b7889af 621 * @details The estimation can vary over time and should not be cached too long.
maygup01 0:11cc2b7889af 622 * 0x00000000 - The manifest is already downloaded.
maygup01 0:11cc2b7889af 623 * 0xFFFFFFFF - Cannot retrieve manifest from this Source.
maygup01 0:11cc2b7889af 624 *
maygup01 0:11cc2b7889af 625 * @param uri URI struct with manifest location.
maygup01 0:11cc2b7889af 626 * @param cost Pointer to variable for the return value.
maygup01 0:11cc2b7889af 627 * @return Error code.
maygup01 0:11cc2b7889af 628 */
maygup01 0:11cc2b7889af 629 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetManifestURLCost(arm_uc_uri_t *uri,
maygup01 0:11cc2b7889af 630 uint32_t *cost)
maygup01 0:11cc2b7889af 631 {
maygup01 0:11cc2b7889af 632 (void) uri;
maygup01 0:11cc2b7889af 633 (void) cost;
maygup01 0:11cc2b7889af 634
maygup01 0:11cc2b7889af 635 ARM_UC_INIT_ERROR(result, SRCE_ERR_INVALID_PARAMETER);
maygup01 0:11cc2b7889af 636
maygup01 0:11cc2b7889af 637 /* not supported - return default cost regardless of actual uri location */
maygup01 0:11cc2b7889af 638 if (cost) {
maygup01 0:11cc2b7889af 639 *cost = 0xFFFFFFFF;
maygup01 0:11cc2b7889af 640 ARM_UC_SET_ERROR(result, ERR_NONE);
maygup01 0:11cc2b7889af 641 }
maygup01 0:11cc2b7889af 642
maygup01 0:11cc2b7889af 643 if (ARM_UC_IS_ERROR(result)) {
maygup01 0:11cc2b7889af 644 ARM_UCS_LWM2M_SOURCE_SetError(result);
maygup01 0:11cc2b7889af 645 }
maygup01 0:11cc2b7889af 646 return result;
maygup01 0:11cc2b7889af 647 }
maygup01 0:11cc2b7889af 648
maygup01 0:11cc2b7889af 649 /**
maygup01 0:11cc2b7889af 650 * @brief Cost estimation for retrieving key table from URL.
maygup01 0:11cc2b7889af 651 * @details The estimation can vary over time and should not be cached too long.
maygup01 0:11cc2b7889af 652 * 0x00000000 - The firmware is already downloaded.
maygup01 0:11cc2b7889af 653 * 0xFFFFFFFF - Cannot retrieve firmware from this Source.
maygup01 0:11cc2b7889af 654 *
maygup01 0:11cc2b7889af 655 * @param uri URI struct with keytable location.
maygup01 0:11cc2b7889af 656 * @param cost Pointer to variable for the return value.
maygup01 0:11cc2b7889af 657 * @return Error code.
maygup01 0:11cc2b7889af 658 */
maygup01 0:11cc2b7889af 659 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetKeytableURLCost(arm_uc_uri_t *uri,
maygup01 0:11cc2b7889af 660 uint32_t *cost)
maygup01 0:11cc2b7889af 661 {
maygup01 0:11cc2b7889af 662 (void) uri;
maygup01 0:11cc2b7889af 663 (void) cost;
maygup01 0:11cc2b7889af 664
maygup01 0:11cc2b7889af 665 ARM_UC_INIT_ERROR(result, SRCE_ERR_INVALID_PARAMETER);
maygup01 0:11cc2b7889af 666
maygup01 0:11cc2b7889af 667 /* not supported - return default cost regardless of actual uri location */
maygup01 0:11cc2b7889af 668 if ((uri != 0) && (cost != 0)) {
maygup01 0:11cc2b7889af 669 *cost = 0xFFFFFFFF;
maygup01 0:11cc2b7889af 670 ARM_UC_SET_ERROR(result, ERR_NONE);
maygup01 0:11cc2b7889af 671 }
maygup01 0:11cc2b7889af 672
maygup01 0:11cc2b7889af 673 if (ARM_UC_IS_ERROR(result)) {
maygup01 0:11cc2b7889af 674 ARM_UCS_LWM2M_SOURCE_SetError(result);
maygup01 0:11cc2b7889af 675 }
maygup01 0:11cc2b7889af 676 return result;
maygup01 0:11cc2b7889af 677 }
maygup01 0:11cc2b7889af 678
maygup01 0:11cc2b7889af 679 /**
maygup01 0:11cc2b7889af 680 * @brief Retrieve manifest from URL.
maygup01 0:11cc2b7889af 681 * @details Manifest is stored in supplied buffer.
maygup01 0:11cc2b7889af 682 * Event is generated once manifest is in buffer.
maygup01 0:11cc2b7889af 683 *
maygup01 0:11cc2b7889af 684 * @param uri URI struct with manifest location.
maygup01 0:11cc2b7889af 685 * @param buffer Struct containing byte array, maximum size, and actual size.
maygup01 0:11cc2b7889af 686 *
maygup01 0:11cc2b7889af 687 * @return Error code.
maygup01 0:11cc2b7889af 688 */
maygup01 0:11cc2b7889af 689 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetManifestURL(arm_uc_uri_t *uri,
maygup01 0:11cc2b7889af 690 arm_uc_buffer_t *buffer,
maygup01 0:11cc2b7889af 691 uint32_t offset)
maygup01 0:11cc2b7889af 692 {
maygup01 0:11cc2b7889af 693 (void) uri;
maygup01 0:11cc2b7889af 694 (void) buffer;
maygup01 0:11cc2b7889af 695 (void) offset;
maygup01 0:11cc2b7889af 696
maygup01 0:11cc2b7889af 697 ARM_UC_INIT_ERROR(retval, SRCE_ERR_INVALID_PARAMETER);
maygup01 0:11cc2b7889af 698
maygup01 0:11cc2b7889af 699 if (ARM_UC_IS_ERROR(retval)) {
maygup01 0:11cc2b7889af 700 ARM_UCS_LWM2M_SOURCE_SetError(retval);
maygup01 0:11cc2b7889af 701 }
maygup01 0:11cc2b7889af 702 return retval;
maygup01 0:11cc2b7889af 703 }
maygup01 0:11cc2b7889af 704
maygup01 0:11cc2b7889af 705 /**
maygup01 0:11cc2b7889af 706 * @brief Retrieve a key table from a URL.
maygup01 0:11cc2b7889af 707 * @details Key table is stored in supplied buffer.
maygup01 0:11cc2b7889af 708 * Event is generated once fragment is in buffer.
maygup01 0:11cc2b7889af 709 *
maygup01 0:11cc2b7889af 710 * @param uri URI struct with keytable location.
maygup01 0:11cc2b7889af 711 * @param buffer Struct containing byte array, maximum size, and actual size.
maygup01 0:11cc2b7889af 712 * @return Error code.
maygup01 0:11cc2b7889af 713 */
maygup01 0:11cc2b7889af 714 arm_uc_error_t ARM_UCS_LWM2M_SOURCE_GetKeytableURL(arm_uc_uri_t *uri,
maygup01 0:11cc2b7889af 715 arm_uc_buffer_t *buffer)
maygup01 0:11cc2b7889af 716 {
maygup01 0:11cc2b7889af 717 (void) uri;
maygup01 0:11cc2b7889af 718 (void) buffer;
maygup01 0:11cc2b7889af 719
maygup01 0:11cc2b7889af 720 ARM_UC_INIT_ERROR(retval, SRCE_ERR_INVALID_PARAMETER);
maygup01 0:11cc2b7889af 721
maygup01 0:11cc2b7889af 722 if (ARM_UC_IS_ERROR(retval)) {
maygup01 0:11cc2b7889af 723 ARM_UCS_LWM2M_SOURCE_SetError(retval);
maygup01 0:11cc2b7889af 724 }
maygup01 0:11cc2b7889af 725 return retval;
maygup01 0:11cc2b7889af 726 }