Simulated product dispenser
Fork of mbed-cloud-workshop-connect-HTS221 by
simple-mbed-cloud-client.cpp
00001 // ---------------------------------------------------------------------------- 00002 // Copyright 2016-2018 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 <stdio.h> 00020 #include "simple-mbed-cloud-client.h" 00021 #include "mbed-cloud-client/MbedCloudClient.h" 00022 #include "m2mdevice.h" 00023 #include "m2mresource.h" 00024 #include "mbed-client/m2minterface.h" 00025 #include "key_config_manager.h" 00026 #include "resource.h" 00027 #include "mbed-client/m2mvector.h" 00028 #include "mbed_cloud_client_resource.h" 00029 #include "factory_configurator_client.h" 00030 #include "update_client_hub.h" 00031 00032 #ifdef MBED_CLOUD_CLIENT_USER_CONFIG_FILE 00033 #include MBED_CLOUD_CLIENT_USER_CONFIG_FILE 00034 #endif 00035 00036 #ifdef MBED_CLOUD_CLIENT_SUPPORT_UPDATE 00037 #include "update_ui_example.h" 00038 #endif 00039 00040 #ifdef MBED_HEAP_STATS_ENABLED 00041 #include "memory_tests.h" 00042 #endif 00043 00044 #ifndef DEFAULT_FIRMWARE_PATH 00045 #define DEFAULT_FIRMWARE_PATH "/sd/firmware" 00046 #endif 00047 00048 BlockDevice *arm_uc_blockdevice; 00049 00050 SimpleMbedCloudClient::SimpleMbedCloudClient(NetworkInterface *net, BlockDevice *bd, FileSystem *fs) : 00051 _registered(false), 00052 _register_called(false), 00053 _register_and_connect_called(false), 00054 _registered_cb(NULL), 00055 _unregistered_cb(NULL), 00056 _net(net), 00057 _bd(bd), 00058 _fs(fs) 00059 { 00060 arm_uc_blockdevice = bd; 00061 } 00062 00063 SimpleMbedCloudClient::~SimpleMbedCloudClient() { 00064 for (unsigned int i = 0; _resources.size(); i++) { 00065 delete _resources[i]; 00066 } 00067 } 00068 00069 int SimpleMbedCloudClient::init() { 00070 // Requires DAPLink 245+ (https://github.com/ARMmbed/DAPLink/pull/364) 00071 // Older versions: workaround to prevent possible deletion of credentials: 00072 wait(1); 00073 00074 extern const uint8_t arm_uc_vendor_id[]; 00075 extern const uint16_t arm_uc_vendor_id_size; 00076 extern const uint8_t arm_uc_class_id[]; 00077 extern const uint16_t arm_uc_class_id_size; 00078 00079 ARM_UC_SetVendorId(arm_uc_vendor_id, arm_uc_vendor_id_size); 00080 ARM_UC_SetClassId(arm_uc_class_id, arm_uc_class_id_size); 00081 00082 // Initialize the FCC 00083 fcc_status_e fcc_status = fcc_init(); 00084 if(fcc_status != FCC_STATUS_SUCCESS) { 00085 printf("[Simple Cloud Client] Factory Client Configuration failed with status %d. \n", fcc_status); 00086 return 1; 00087 } 00088 00089 fcc_status = fcc_verify_device_configured_4mbed_cloud(); 00090 00091 if (fcc_status == FCC_STATUS_KCM_STORAGE_ERROR) { 00092 int mount_result = mount_storage(); 00093 if (mount_result != 0) { 00094 printf("[Simple Cloud Client] Failed to mount file system with status %d. \n", mount_result); 00095 #if !defined(MBED_CONF_APP_FORMAT_STORAGE_LAYER_ON_ERROR) || MBED_CONF_APP_FORMAT_STORAGE_LAYER_ON_ERROR == 0 00096 return 1; 00097 #endif 00098 } else { 00099 // Retry with mounted filesystem. 00100 fcc_status = fcc_verify_device_configured_4mbed_cloud(); 00101 } 00102 } 00103 00104 // This is designed to simplify user-experience by auto-formatting the 00105 // primary storage if no valid certificates exist. 00106 // This should never be used for any kind of production devices. 00107 #if defined(MBED_CONF_APP_FORMAT_STORAGE_LAYER_ON_ERROR) && MBED_CONF_APP_FORMAT_STORAGE_LAYER_ON_ERROR == 1 00108 if (fcc_status != FCC_STATUS_SUCCESS) { 00109 if (reformat_storage() != 0) { 00110 return 1; 00111 } 00112 00113 reset_storage(); 00114 } 00115 #else 00116 if (fcc_status != FCC_STATUS_SUCCESS) { 00117 printf("[Simple Cloud Client] Device not configured for mbed Cloud - try re-formatting your storage device or set MBED_CONF_APP_FORMAT_STORAGE_LAYER_ON_ERROR to 1\n"); 00118 return 1; 00119 } 00120 #endif 00121 00122 // Resets storage to an empty state. 00123 // Use this function when you want to clear storage from all the factory-tool generated data and user data. 00124 // After this operation device must be injected again by using factory tool or developer certificate. 00125 #ifdef RESET_STORAGE 00126 reset_storage(); 00127 #endif 00128 00129 // Deletes existing firmware images from storage. 00130 // This deletes any existing firmware images during application startup. 00131 // This compilation flag is currently implemented only for mbed OS. 00132 #ifdef RESET_FIRMWARE 00133 palStatus_t status = PAL_SUCCESS; 00134 status = pal_fsRmFiles(DEFAULT_FIRMWARE_PATH); 00135 if(status == PAL_SUCCESS) { 00136 printf("[Simple Cloud Client] Firmware storage erased.\n"); 00137 } else if (status == PAL_ERR_FS_NO_PATH) { 00138 printf("[Simple Cloud Client] Firmware path not found/does not exist.\n"); 00139 } else { 00140 printf("[Simple Cloud Client] Firmware storage erasing failed with %" PRId32, status); 00141 return 1; 00142 } 00143 #endif 00144 00145 #if MBED_CONF_APP_DEVELOPER_MODE == 1 00146 printf("[Simple Cloud Client] Starting developer flow\n"); 00147 fcc_status = fcc_developer_flow(); 00148 if (fcc_status == FCC_STATUS_KCM_FILE_EXIST_ERROR) { 00149 printf("[Simple Cloud Client] Developer credentials already exist\n"); 00150 } else if (fcc_status != FCC_STATUS_SUCCESS) { 00151 printf("[Simple Cloud Client] Failed to load developer credentials - is the storage device active and accessible?\n"); 00152 return 1; 00153 } 00154 #endif 00155 00156 return 0; 00157 } 00158 00159 bool SimpleMbedCloudClient::call_register() { 00160 // need to unregister first before calling this function again 00161 if (_register_called) return false; 00162 00163 _cloud_client.on_registered(this, &SimpleMbedCloudClient::client_registered); 00164 _cloud_client.on_unregistered(this, &SimpleMbedCloudClient::client_unregistered); 00165 _cloud_client.on_error(this, &SimpleMbedCloudClient::error); 00166 00167 bool setup = _cloud_client.setup(_net); 00168 _register_called = true; 00169 if (!setup) { 00170 printf("[Simple Cloud Client] Client setup failed\n"); 00171 return false; 00172 } 00173 00174 #ifdef MBED_CLOUD_CLIENT_SUPPORT_UPDATE 00175 /* Set callback functions for authorizing updates and monitoring progress. 00176 Code is implemented in update_ui_example.cpp 00177 Both callbacks are completely optional. If no authorization callback 00178 is set, the update process will procede immediately in each step. 00179 */ 00180 update_ui_set_cloud_client(&_cloud_client); 00181 _cloud_client.set_update_authorize_handler(update_authorize); 00182 _cloud_client.set_update_progress_handler(update_progress); 00183 #endif 00184 return true; 00185 } 00186 00187 void SimpleMbedCloudClient::close() { 00188 _cloud_client.close(); 00189 } 00190 00191 void SimpleMbedCloudClient::register_update() { 00192 _cloud_client.register_update(); 00193 } 00194 00195 void SimpleMbedCloudClient::client_registered() { 00196 _registered = true; 00197 static const ConnectorClientEndpointInfo* endpoint = NULL; 00198 if (endpoint == NULL) { 00199 endpoint = _cloud_client.endpoint_info(); 00200 if (endpoint && _registered_cb) { 00201 _registered_cb(endpoint); 00202 } 00203 } 00204 #ifdef MBED_HEAP_STATS_ENABLED 00205 heap_stats(); 00206 #endif 00207 } 00208 00209 void SimpleMbedCloudClient::client_unregistered() { 00210 _registered = false; 00211 _register_called = false; 00212 00213 if (_unregistered_cb) { 00214 _unregistered_cb(); 00215 } 00216 00217 #ifdef MBED_HEAP_STATS_ENABLED 00218 heap_stats(); 00219 #endif 00220 } 00221 00222 void SimpleMbedCloudClient::error(int error_code) { 00223 const char *error; 00224 switch(error_code) { 00225 case MbedCloudClient::ConnectErrorNone: 00226 error = "MbedCloudClient::ConnectErrorNone"; 00227 break; 00228 case MbedCloudClient::ConnectAlreadyExists: 00229 error = "MbedCloudClient::ConnectAlreadyExists"; 00230 break; 00231 case MbedCloudClient::ConnectBootstrapFailed: 00232 error = "MbedCloudClient::ConnectBootstrapFailed"; 00233 break; 00234 case MbedCloudClient::ConnectInvalidParameters: 00235 error = "MbedCloudClient::ConnectInvalidParameters"; 00236 break; 00237 case MbedCloudClient::ConnectNotRegistered: 00238 error = "MbedCloudClient::ConnectNotRegistered"; 00239 break; 00240 case MbedCloudClient::ConnectTimeout: 00241 error = "MbedCloudClient::ConnectTimeout"; 00242 break; 00243 case MbedCloudClient::ConnectNetworkError: 00244 error = "MbedCloudClient::ConnectNetworkError"; 00245 break; 00246 case MbedCloudClient::ConnectResponseParseFailed: 00247 error = "MbedCloudClient::ConnectResponseParseFailed"; 00248 break; 00249 case MbedCloudClient::ConnectUnknownError: 00250 error = "MbedCloudClient::ConnectUnknownError"; 00251 break; 00252 case MbedCloudClient::ConnectMemoryConnectFail: 00253 error = "MbedCloudClient::ConnectMemoryConnectFail"; 00254 break; 00255 case MbedCloudClient::ConnectNotAllowed: 00256 error = "MbedCloudClient::ConnectNotAllowed"; 00257 break; 00258 case MbedCloudClient::ConnectSecureConnectionFailed: 00259 error = "MbedCloudClient::ConnectSecureConnectionFailed"; 00260 break; 00261 case MbedCloudClient::ConnectDnsResolvingFailed: 00262 error = "MbedCloudClient::ConnectDnsResolvingFailed"; 00263 break; 00264 #ifdef MBED_CLOUD_CLIENT_SUPPORT_UPDATE 00265 case MbedCloudClient::UpdateWarningCertificateNotFound: 00266 error = "MbedCloudClient::UpdateWarningCertificateNotFound"; 00267 break; 00268 case MbedCloudClient::UpdateWarningIdentityNotFound: 00269 error = "MbedCloudClient::UpdateWarningIdentityNotFound"; 00270 break; 00271 case MbedCloudClient::UpdateWarningCertificateInvalid: 00272 error = "MbedCloudClient::UpdateWarningCertificateInvalid"; 00273 break; 00274 case MbedCloudClient::UpdateWarningSignatureInvalid: 00275 error = "MbedCloudClient::UpdateWarningSignatureInvalid"; 00276 break; 00277 case MbedCloudClient::UpdateWarningVendorMismatch: 00278 error = "MbedCloudClient::UpdateWarningVendorMismatch"; 00279 break; 00280 case MbedCloudClient::UpdateWarningClassMismatch: 00281 error = "MbedCloudClient::UpdateWarningClassMismatch"; 00282 break; 00283 case MbedCloudClient::UpdateWarningDeviceMismatch: 00284 error = "MbedCloudClient::UpdateWarningDeviceMismatch"; 00285 break; 00286 case MbedCloudClient::UpdateWarningURINotFound: 00287 error = "MbedCloudClient::UpdateWarningURINotFound"; 00288 break; 00289 case MbedCloudClient::UpdateWarningRollbackProtection: 00290 error = "MbedCloudClient::UpdateWarningRollbackProtection"; 00291 break; 00292 case MbedCloudClient::UpdateWarningUnknown: 00293 error = "MbedCloudClient::UpdateWarningUnknown"; 00294 break; 00295 case MbedCloudClient::UpdateErrorWriteToStorage: 00296 error = "MbedCloudClient::UpdateErrorWriteToStorage"; 00297 break; 00298 case MbedCloudClient::UpdateErrorInvalidHash: 00299 error = "MbedCloudClient::UpdateErrorInvalidHash"; 00300 break; 00301 #endif 00302 default: 00303 error = "UNKNOWN"; 00304 } 00305 00306 // @todo: move this into user space 00307 printf("\n[Simple Cloud Client] Error occurred : %s\n", error); 00308 printf("[Simple Cloud Client] Error code : %d\n", error_code); 00309 printf("[Simple Cloud Client] Error details : %s\n",_cloud_client.error_description()); 00310 } 00311 00312 bool SimpleMbedCloudClient::is_client_registered() { 00313 return _registered; 00314 } 00315 00316 bool SimpleMbedCloudClient::is_register_called() { 00317 return _register_called; 00318 } 00319 00320 bool SimpleMbedCloudClient::register_and_connect() { 00321 if (_register_and_connect_called) return false; 00322 00323 mcc_resource_def resourceDef; 00324 00325 for (int i = 0; i < _resources.size(); i++) { 00326 _resources[i]->get_data(&resourceDef); 00327 M2MResource *res = add_resource(&_obj_list, resourceDef.object_id, resourceDef.instance_id, 00328 resourceDef.resource_id, resourceDef.name.c_str(), M2MResourceInstance::STRING, 00329 (M2MBase::Operation)resourceDef.method_mask, resourceDef.value.c_str(), resourceDef.observable, 00330 resourceDef.put_callback, resourceDef.post_callback, resourceDef.notification_callback); 00331 _resources[i]->set_m2m_resource(res); 00332 } 00333 _cloud_client.add_objects(_obj_list); 00334 00335 _register_and_connect_called = true; 00336 00337 // Start registering to the cloud. 00338 bool retval = call_register(); 00339 00340 // Print memory statistics if the MBED_HEAP_STATS_ENABLED is defined. 00341 #ifdef MBED_HEAP_STATS_ENABLED 00342 printf("[Simple Cloud Client] Register being called\r\n"); 00343 heap_stats(); 00344 #endif 00345 00346 return retval; 00347 } 00348 00349 void SimpleMbedCloudClient::on_registered(Callback<void(const ConnectorClientEndpointInfo*)> cb) { 00350 _registered_cb = cb; 00351 } 00352 00353 void SimpleMbedCloudClient::on_unregistered(Callback<void()> cb) { 00354 _unregistered_cb = cb; 00355 } 00356 00357 MbedCloudClient& SimpleMbedCloudClient::get_cloud_client() { 00358 return _cloud_client; 00359 } 00360 00361 MbedCloudClientResource* SimpleMbedCloudClient::create_resource(const char *path, const char *name) { 00362 MbedCloudClientResource *resource = new MbedCloudClientResource(this, path, name); 00363 _resources.push_back(resource); 00364 return resource; 00365 } 00366 00367 int SimpleMbedCloudClient::reformat_storage() 00368 { 00369 int reformat_result = -1; 00370 printf("[Simple Cloud Client] Autoformatting the storage.\n"); 00371 if (_bd) { 00372 reformat_result = _fs->reformat(_bd); 00373 if (reformat_result != 0) { 00374 printf("[Simple Cloud Client] Autoformatting failed with error %d\n", reformat_result); 00375 } 00376 } 00377 return reformat_result; 00378 } 00379 00380 void SimpleMbedCloudClient::reset_storage() 00381 { 00382 printf("[Simple Cloud Client] Reset storage to an empty state.\n"); 00383 fcc_status_e delete_status = fcc_storage_delete(); 00384 if (delete_status != FCC_STATUS_SUCCESS) { 00385 printf("[Simple Cloud Client] Failed to delete storage - %d\n", delete_status); 00386 } 00387 } 00388 00389 int SimpleMbedCloudClient::mount_storage() 00390 { 00391 int mount_result = -1; 00392 printf("[Simple Cloud Client] Initializing storage.\n"); 00393 if (_bd) { 00394 mount_result = _fs->mount(_bd); 00395 } 00396 return mount_result; 00397 }
Generated on Tue Jul 12 2022 19:12:15 by 1.7.2