Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
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