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.
FirmwareUpdateResource.cpp
00001 // ---------------------------------------------------------------------------- 00002 // Copyright 2016-2017 ARM Ltd. 00003 // 00004 // SPDX-License-Identifier: Apache-2.0 00005 // 00006 // Licensed under the Apache License, Version 2.0 (the "License"); 00007 // you may not use this file except in compliance with the License. 00008 // You may obtain a copy of the License at 00009 // 00010 // http://www.apache.org/licenses/LICENSE-2.0 00011 // 00012 // Unless required by applicable law or agreed to in writing, software 00013 // distributed under the License is distributed on an "AS IS" BASIS, 00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 // See the License for the specific language governing permissions and 00016 // limitations under the License. 00017 // ---------------------------------------------------------------------------- 00018 00019 #include "update-client-lwm2m/FirmwareUpdateResource.h" 00020 00021 #include "update-client-common/arm_uc_common.h" 00022 00023 #include <stdio.h> 00024 00025 #define ARM_UCS_LWM2M_INTERNAL_ERROR (-1) 00026 #define ARM_UCS_LWM2M_INTERNAL_SUCCESS (0) 00027 00028 namespace FirmwareUpdateResource { 00029 00030 /* send delayed response */ 00031 enum { 00032 ResourcePackage, 00033 ResourcePackageURI, 00034 ResourceUpdate 00035 }; 00036 00037 static void packageCallback(void* _parameters); 00038 static void packageURICallback(void* _parameters); 00039 static void updateCallback(void*); 00040 static void notificationCallback(void); 00041 static void sendDelayedResponseTask(uint32_t parameter); 00042 00043 /* LWM2M Firmware Update Object */ 00044 static M2MObject* updateObject; 00045 00046 /* LWM2M Firmware Update Object resources */ 00047 static M2MResource* resourcePackage = NULL; 00048 static M2MResource* resourcePackageURI = NULL; 00049 static M2MResource* resourceUpdate = NULL; 00050 static M2MResource* resourceState = NULL; 00051 static M2MResource* resourceResult = NULL; 00052 static M2MResource* resourceName = NULL; 00053 static M2MResource* resourceVersion = NULL; 00054 00055 /* function pointers to callback functions */ 00056 static void (*externalPackageCallback)(const uint8_t* buffer, uint16_t length) = NULL; 00057 static void (*externalPackageURICallback)(const uint8_t* buffer, uint16_t length) = NULL; 00058 static void (*externalUpdateCallback)(void) = NULL; 00059 static void (*externalNotificationCallback)(void) = NULL; 00060 00061 /* Callback structs for delayed response. 00062 * 00063 * There needs to be one per callback type to avoid collisions between different operations. 00064 */ 00065 static arm_uc_callback_t callbackNodePackage = { NULL, 0, NULL, 0 }; 00066 static arm_uc_callback_t callbackNodePackageURI = { NULL, 0, NULL, 0 }; 00067 static arm_uc_callback_t callbackNodeResourceUpdate = { NULL, 0, NULL, 0 }; 00068 } 00069 00070 /** 00071 * @brief Initialize LWM2M Firmware Update Object 00072 * @details Sets up LWM2M object with accompanying resources. 00073 */ 00074 void FirmwareUpdateResource::Initialize(void) 00075 { 00076 static bool initialized = false; 00077 00078 if (!initialized) 00079 { 00080 initialized = true; 00081 00082 /* The LWM2M Firmware Update Object is at /5 */ 00083 updateObject = M2MInterfaceFactory::create_object("5"); 00084 00085 if (updateObject) 00086 { 00087 /* Create first (and only) instance /5/0 */ 00088 M2MObjectInstance* updateInstance = updateObject->create_object_instance(); 00089 00090 if (updateInstance) 00091 { 00092 /* Set observable so the Portal can read it */ 00093 updateInstance->set_observable(true); 00094 00095 /* Default values are non-standard, but the standard has no 00096 values for indicating that the device is initializing. 00097 */ 00098 uint8_t defaultValue[] = {"-1"}; 00099 uint8_t defaultVersion[] = {"-1"}; 00100 00101 /* Create Package resource /5/0/0 */ 00102 resourcePackage = updateInstance->create_dynamic_resource( 00103 "0", "Package", M2MResourceInstance::OPAQUE, false); 00104 if (resourcePackage) 00105 { 00106 /* This should be PUT according to the standard but 00107 Connector client doesn't support callbacks for PUT. 00108 */ 00109 resourcePackage->set_operation(M2MBase::POST_ALLOWED); 00110 resourcePackage->set_execute_function(packageCallback); 00111 00112 /* The delayed response if for processing heavier loads */ 00113 resourcePackage->set_delayed_response(true); 00114 } 00115 00116 /* Create Package URI resource /5/0/1 */ 00117 resourcePackageURI = updateInstance->create_dynamic_resource( 00118 "1", "PackageURI", M2MResourceInstance::STRING, false); 00119 if (resourcePackageURI) 00120 { 00121 resourcePackageURI->set_operation(M2MBase::POST_ALLOWED); 00122 resourcePackageURI->set_execute_function(packageURICallback); 00123 resourcePackageURI->set_delayed_response(true); 00124 } 00125 00126 /* Create Update resource /5/0/2 */ 00127 resourceUpdate = updateInstance->create_dynamic_resource( 00128 "2", "Update", M2MResourceInstance::BOOLEAN, false); 00129 if (resourceUpdate) 00130 { 00131 resourceUpdate->set_operation(M2MBase::POST_ALLOWED); 00132 resourceUpdate->set_execute_function(updateCallback); 00133 resourceUpdate->set_delayed_response(true); 00134 } 00135 00136 /* Create State resource /5/0/3 */ 00137 resourceState = updateInstance->create_dynamic_resource( 00138 "3", "State", M2MResourceInstance::INTEGER, true); 00139 if (resourceState) 00140 { 00141 resourceState->set_operation(M2MBase::GET_ALLOWED); 00142 resourceState->set_notification_sent_callback(notificationCallback); 00143 resourceState->set_value(defaultValue, sizeof(defaultValue) - 1); 00144 } 00145 00146 /* Create Update Result resource /5/0/5 */ 00147 resourceResult = updateInstance->create_dynamic_resource( 00148 "5", "UpdateResult", M2MResourceInstance::INTEGER, true); 00149 if (resourceResult) 00150 { 00151 resourceResult->set_operation(M2MBase::GET_ALLOWED); 00152 resourceResult->set_notification_sent_callback(notificationCallback); 00153 resourceResult->set_value(defaultValue, sizeof(defaultValue) - 1); 00154 } 00155 00156 /* Create PkgName resource /5/0/6 */ 00157 resourceName = updateInstance->create_dynamic_resource( 00158 "6", "PkgName", M2MResourceInstance::STRING, true); 00159 if (resourceName) 00160 { 00161 resourceName->set_operation(M2MBase::GET_ALLOWED); 00162 resourceName->set_value(defaultVersion, sizeof(defaultVersion) - 1); 00163 } 00164 00165 /* Create PkgVersion resource /5/0/7 */ 00166 resourceVersion = updateInstance->create_dynamic_resource( 00167 "7", "PkgVersion", M2MResourceInstance::STRING, true); 00168 if (resourceVersion) 00169 { 00170 resourceVersion->set_operation(M2MBase::GET_ALLOWED); 00171 resourceVersion->set_value(defaultVersion, sizeof(defaultVersion) - 1); 00172 } 00173 } 00174 } 00175 } 00176 } 00177 00178 M2MObject* FirmwareUpdateResource::getObject() 00179 { 00180 Initialize(); 00181 00182 return updateObject; 00183 } 00184 00185 void FirmwareUpdateResource::packageCallback(void* _parameters) 00186 { 00187 UC_SRCE_TRACE("FirmwareUpdateResource::packageCallback"); 00188 00189 if (_parameters && externalPackageCallback) 00190 { 00191 /* recast parameter */ 00192 M2MResource::M2MExecuteParameter* parameters = 00193 static_cast<M2MResource::M2MExecuteParameter*>(_parameters); 00194 00195 /* read payload */ 00196 const uint8_t* buffer = parameters->get_argument_value(); 00197 uint16_t length = parameters->get_argument_value_length(); 00198 00199 /* invoke external callback function */ 00200 externalPackageCallback(buffer, length); 00201 00202 /* schedule delayed response */ 00203 ARM_UC_PostCallback(&callbackNodePackage, 00204 FirmwareUpdateResource::sendDelayedResponseTask, 00205 FirmwareUpdateResource::ResourcePackage); 00206 } 00207 } 00208 00209 void FirmwareUpdateResource::packageURICallback(void* _parameters) 00210 { 00211 UC_SRCE_TRACE("FirmwareUpdateResource::packageURICallback"); 00212 00213 if (_parameters && externalPackageURICallback) 00214 { 00215 /* recast parameter */ 00216 M2MResource::M2MExecuteParameter* parameters = 00217 static_cast<M2MResource::M2MExecuteParameter*>(_parameters); 00218 00219 /* read payload */ 00220 const uint8_t* buffer = parameters->get_argument_value(); 00221 uint16_t length = parameters->get_argument_value_length(); 00222 00223 /* invoke external callback function */ 00224 externalPackageURICallback(buffer, length); 00225 00226 /* schedule delayed response */ 00227 ARM_UC_PostCallback(&callbackNodePackageURI, 00228 FirmwareUpdateResource::sendDelayedResponseTask, 00229 FirmwareUpdateResource::ResourcePackageURI); 00230 } 00231 } 00232 00233 void FirmwareUpdateResource::updateCallback(void* _parameters) 00234 { 00235 UC_SRCE_TRACE("FirmwareUpdateResource::updateCallback"); 00236 00237 (void) _parameters; 00238 00239 if (externalUpdateCallback) 00240 { 00241 /* invoke external callback function */ 00242 externalUpdateCallback(); 00243 00244 /* schedule delayed response */ 00245 ARM_UC_PostCallback(&callbackNodeResourceUpdate, 00246 FirmwareUpdateResource::sendDelayedResponseTask, 00247 FirmwareUpdateResource::ResourceUpdate); 00248 } 00249 } 00250 00251 void FirmwareUpdateResource::notificationCallback(void) 00252 { 00253 UC_SRCE_TRACE("FirmwareUpdateResource::notificationCallback"); 00254 00255 if (externalNotificationCallback) 00256 { 00257 externalNotificationCallback(); 00258 } 00259 } 00260 00261 void FirmwareUpdateResource::sendDelayedResponseTask(uint32_t parameter) 00262 { 00263 UC_SRCE_TRACE("FirmwareUpdateResource::sendDelayedResponseTask"); 00264 00265 switch (parameter) 00266 { 00267 case FirmwareUpdateResource::ResourcePackage: 00268 UC_SRCE_TRACE("resourcePackage->send_delayed_post_response"); 00269 resourcePackage->send_delayed_post_response(); 00270 break; 00271 case FirmwareUpdateResource::ResourcePackageURI: 00272 UC_SRCE_TRACE("resourcePackageURI->send_delayed_post_response"); 00273 resourcePackageURI->send_delayed_post_response(); 00274 break; 00275 case FirmwareUpdateResource::ResourceUpdate: 00276 UC_SRCE_TRACE("resourceUpdate->send_delayed_post_response"); 00277 resourceUpdate->send_delayed_post_response(); 00278 break; 00279 default: 00280 UC_SRCE_ERR_MSG("unsupported resource"); 00281 break; 00282 } 00283 } 00284 00285 /*****************************************************************************/ 00286 /* Update Client Source */ 00287 /*****************************************************************************/ 00288 00289 /* Add callback for resource /5/0/0, Package */ 00290 int32_t FirmwareUpdateResource::addPackageCallback(void (*cb)(const uint8_t* buffer, uint16_t length)) 00291 { 00292 UC_SRCE_TRACE("FirmwareUpdateResource::addPackageCallback: %p", cb); 00293 00294 externalPackageCallback = cb; 00295 00296 return ARM_UCS_LWM2M_INTERNAL_SUCCESS; 00297 } 00298 00299 /* Add callback for resource /5/0/1, Package URI */ 00300 int32_t FirmwareUpdateResource::addPackageURICallback(void (*cb)(const uint8_t* buffer, uint16_t length)) 00301 { 00302 UC_SRCE_TRACE("FirmwareUpdateResource::addPackageURICallback: %p", cb); 00303 00304 externalPackageURICallback = cb; 00305 00306 return ARM_UCS_LWM2M_INTERNAL_SUCCESS; 00307 } 00308 00309 /* Add callback for resource /5/0/2, Update */ 00310 int32_t FirmwareUpdateResource::addUpdateCallback(void (*cb)(void)) 00311 { 00312 UC_SRCE_TRACE("FirmwareUpdateResource::addUpdateCallback: %p", cb); 00313 00314 externalUpdateCallback = cb; 00315 00316 return ARM_UCS_LWM2M_INTERNAL_SUCCESS; 00317 } 00318 00319 /* Add callback for when send{State, UpdateResult} is done */ 00320 int32_t FirmwareUpdateResource::addNotificationCallback(void (*cb)(void)) 00321 { 00322 UC_SRCE_TRACE("FirmwareUpdateResource::addNotificationCallback: %p", cb); 00323 00324 externalNotificationCallback = cb; 00325 00326 return ARM_UCS_LWM2M_INTERNAL_SUCCESS; 00327 } 00328 00329 /*****************************************************************************/ 00330 /* Update Client Status */ 00331 /*****************************************************************************/ 00332 00333 /* Send state for resource /5/0/3, State */ 00334 int32_t FirmwareUpdateResource::sendState(arm_ucs_lwm2m_state_t state) 00335 { 00336 UC_SRCE_TRACE("FirmwareUpdateResource::sendState"); 00337 00338 int32_t result = ARM_UCS_LWM2M_INTERNAL_ERROR; 00339 00340 if (state <= ARM_UCS_LWM2M_STATE_LAST) 00341 { 00342 /* valid states: 0-3 */ 00343 uint8_t value[2]; 00344 snprintf((char*)value, 2, "%d", state); 00345 resourceState->set_value(value, 1); 00346 00347 result = ARM_UCS_LWM2M_INTERNAL_SUCCESS; 00348 } 00349 00350 return result; 00351 } 00352 00353 /* Send result for resource /5/0/5, Update Result */ 00354 int32_t FirmwareUpdateResource::sendUpdateResult(arm_ucs_lwm2m_result_t updateResult) 00355 { 00356 UC_SRCE_TRACE("FirmwareUpdateResource::sendUpdateResult"); 00357 00358 int32_t result = ARM_UCS_LWM2M_INTERNAL_ERROR; 00359 00360 if (updateResult <= ARM_UCS_LWM2M_RESULT_LAST) 00361 { 00362 /* valid results: 0-8 */ 00363 uint8_t value[2]; 00364 snprintf((char*)value, 2, "%d", updateResult); 00365 resourceResult->set_value(value, 1); 00366 00367 result = ARM_UCS_LWM2M_INTERNAL_SUCCESS; 00368 } 00369 00370 return result; 00371 } 00372 00373 /* Send name for resource /5/0/6 PkgName */ 00374 int32_t FirmwareUpdateResource::sendPkgName(const uint8_t* name, uint16_t length) 00375 { 00376 UC_SRCE_TRACE("FirmwareUpdateResource::sendPkgName"); 00377 00378 int32_t result = ARM_UCS_LWM2M_INTERNAL_ERROR; 00379 00380 /* the maximum length is defined in the OMA LWM2M standard. */ 00381 if ((name != NULL) && (length <= 255)) 00382 { 00383 uint8_t value[64] = { 0 }; 00384 uint8_t index = 0; 00385 00386 /* convert to printable characters using lookup table */ 00387 for ( ; (index < 32) && (index < length); index++) 00388 { 00389 value[2 * index ] = arm_uc_hex_table[name[index] >> 4]; 00390 value[2 * index + 1] = arm_uc_hex_table[name[index] & 0x0F]; 00391 } 00392 00393 resourceName->set_value(value, 2 * index); 00394 00395 result = ARM_UCS_LWM2M_INTERNAL_SUCCESS; 00396 } 00397 00398 return result; 00399 } 00400 00401 /* Send version for resource /5/0/7, PkgVersion */ 00402 int32_t FirmwareUpdateResource::sendPkgVersion(uint64_t version) 00403 { 00404 UC_SRCE_TRACE("FirmwareUpdateResource::sendPkgVersion"); 00405 00406 uint8_t value[21] = { 0 }; 00407 uint8_t length = snprintf((char*) value, 21, "%llu" , version); 00408 resourceVersion->set_value(value, length); 00409 00410 return ARM_UCS_LWM2M_INTERNAL_SUCCESS; 00411 } 00412 00413 void FirmwareUpdateResource::Uninitialize(void) 00414 { 00415 UC_SRCE_TRACE("FirmwareUpdateResource::Uninitialize"); 00416 delete updateObject; 00417 updateObject = NULL; 00418 }
Generated on Tue Jul 12 2022 19:01:34 by
1.7.2