Committer:
leothedragon
Date:
Sun Apr 18 15:20:23 2021 +0000
Revision:
0:25fa8795676b
DS

Who changed what in which revision?

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