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.
main.cpp
00001 /* 00002 * Copyright (c) 2015 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "sockets/UDPSocket.h" 00017 #include "EthernetInterface.h" 00018 #include "test_env.h" 00019 #include "mbed-client/m2minterfacefactory.h" 00020 #include "mbed-client/m2minterfaceobserver.h" 00021 #include "mbed-client/m2mdevice.h" 00022 #include "mbed-client/m2mobjectinstance.h" 00023 #include "mbed-client/m2minterface.h" 00024 #include "testconfig.h" 00025 00026 // TODO: Remove when yotta supports init. 00027 #include "lwipv4_init.h" 00028 00029 // Minar for event scheduling 00030 #include "minar/minar.h" 00031 00032 using namespace mbed::util; 00033 const String &MANUFACTURER = "ARM"; 00034 const String &TYPE = "type"; 00035 00036 static bool test_result = false; 00037 00038 // Dynamic resource variables 00039 const String &DYNAMIC_RESOURCE_NAME = "Dynamic"; 00040 const String &DYNAMIC_RESOURCE_TYPE = "DynamicType"; 00041 const String &STATIC_RESOURCE_NAME = "Static"; 00042 const String &STATIC_RESOURCE_TYPE = "StaticType"; 00043 const uint8_t STATIC_VALUE[] = "Static value"; 00044 00045 //TODO: should this be configured in .json conf file, and communicated via host test to here? 00046 int CALLBACK_TIMEOUT = 5; 00047 int MINAR_DELAY = 10000; 00048 00049 #define SUITE_TEST_INFO(test_name, info) printf("Suite-%s: %s\n", test_name, info) 00050 #define SUITE_TEST_RESULT(test_name, result) printf("Suite-%s: result %s\n", test_name, result ? "PASSED" : "FAILED") 00051 #define SUITE_RESULT(result) printf("Suite: result %s\n", result ? "success" : "failure") 00052 00053 00054 class MbedClient: public M2MInterfaceObserver { 00055 public: 00056 MbedClient(TestConfig *test_config){ 00057 _interface = NULL; 00058 _register_security = NULL; 00059 _resource_object = NULL; 00060 _bootstrapped = false; 00061 _error = false; 00062 _registered = false; 00063 _unregistered = false; 00064 _registration_updated = false; 00065 _resource_value = 0; 00066 _object = NULL; 00067 _test_config = test_config; 00068 } 00069 00070 virtual ~MbedClient() { 00071 if(_interface) { 00072 delete _interface; 00073 } 00074 if( _register_security){ 00075 delete _register_security; 00076 } 00077 } 00078 00079 bool create_interface() { 00080 bool success = false; 00081 // Creates M2MInterface using which endpoint can 00082 // setup its name, resource type, life time, connection mode, 00083 // Currently only LwIPv4 is supported. 00084 _interface = M2MInterfaceFactory::create_interface( *this, 00085 _test_config->get_endpoint_name(), 00086 _test_config->get_endpoint_type(), 00087 _test_config->get_lifetime(), 00088 _test_config->get_port(), 00089 _test_config->get_domain(), 00090 M2MInterface::UDP, 00091 M2MInterface::LwIP_IPv4, 00092 ""); 00093 if (_interface) { 00094 success = true; 00095 } 00096 00097 return success; 00098 } 00099 00100 bool bootstrap_successful() { 00101 return _bootstrapped; 00102 } 00103 00104 M2MSecurity* create_bootstrap_object() { 00105 // Creates bootstrap server object with Bootstrap server address and other parameters 00106 // required for client to connect to bootstrap server. 00107 M2MSecurity *security = M2MInterfaceFactory::create_security(M2MSecurity::Bootstrap); 00108 if(security) { 00109 security->set_resource_value(M2MSecurity::M2MServerUri, _test_config->get_bootstrap_server()); 00110 security->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::NoSecurity); 00111 } 00112 return security; 00113 } 00114 00115 void test_bootstrap(M2MSecurity *security) { 00116 if(_interface) { 00117 // Bootstrap function. 00118 _interface->bootstrap(security); 00119 } 00120 } 00121 00122 bool register_successful() { 00123 return _registered; 00124 } 00125 00126 bool unregister_successful() { 00127 return _unregistered; 00128 } 00129 00130 bool update_register_successful() { 00131 return _registration_updated; 00132 } 00133 00134 void check_result(const char* result) { 00135 if(_registered && _registration_updated && _unregistered) { 00136 SUITE_TEST_RESULT(result, true); 00137 test_result = true; 00138 } else { 00139 SUITE_TEST_RESULT(result, false); 00140 test_result = false; 00141 } 00142 minar::Scheduler::stop(); 00143 } 00144 00145 M2MSecurity* create_register_object() { 00146 // Creates server object with LWM2M server address and other parameters 00147 // required for client to connect to LWM2M server. 00148 M2MSecurity *security = M2MInterfaceFactory::create_security(M2MSecurity::M2MServer); 00149 if(security) { 00150 security->set_resource_value(M2MSecurity::M2MServerUri, _test_config->get_mds_server()); 00151 //security->set_resource_value(M2MSecurity::M2MServerUri, "ds-test.dev.mbed.com"); 00152 security->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::NoSecurity); 00153 } 00154 return security; 00155 } 00156 00157 void test_register(M2MObjectList object_list){ 00158 if(_interface) { 00159 // Register function 00160 _interface->register_object(_register_security, object_list); 00161 } 00162 } 00163 00164 void test_update_register(const uint32_t lifetime) 00165 { 00166 if(_interface && _register_security) { 00167 _interface->update_registration(_register_security,lifetime); 00168 } 00169 } 00170 00171 void test_unregister(){ 00172 if(_interface) { 00173 // Unregister function 00174 _interface->unregister_object(NULL); 00175 } 00176 } 00177 00178 void set_register_object(M2MSecurity *®ister_object){ 00179 if(_register_security) { 00180 delete _register_security; 00181 _register_security = NULL; 00182 } 00183 _register_security = register_object; 00184 } 00185 00186 M2MDevice* create_device_object() { 00187 M2MDevice *device = M2MInterfaceFactory::create_device(); 00188 if (device) { 00189 device->create_resource(M2MDevice::Manufacturer, MANUFACTURER); 00190 device->create_resource(M2MDevice::DeviceType, TYPE); 00191 } 00192 return device; 00193 } 00194 00195 M2MObject* create_generic_object() { 00196 _object = M2MInterfaceFactory::create_object("Test"); 00197 if(_object) { 00198 M2MObjectInstance* inst = _object->create_object_instance(); 00199 if(inst) { 00200 M2MResource* res = inst->create_dynamic_resource("D","ResourceTest", 00201 M2MResourceInstance::INTEGER, 00202 true); 00203 char buffer[20]; 00204 int size = sprintf(buffer,"%d",_resource_value); 00205 res->set_operation(M2MBase::GET_PUT_POST_ALLOWED); 00206 res->set_value((const uint8_t*)buffer, 00207 (const uint32_t)size); 00208 _resource_value++; 00209 00210 inst->create_static_resource("S", 00211 "ResourceTest", 00212 M2MResourceInstance::STRING, 00213 STATIC_VALUE, 00214 sizeof(STATIC_VALUE)-1); 00215 } 00216 } 00217 return _object; 00218 } 00219 00220 //Callback from mbed client stack when the bootstrap 00221 // is successful, it returns the mbed Device Server object 00222 // which will be used for registering the resources to 00223 // mbed Device server. 00224 void bootstrap_done(M2MSecurity *server_object){ 00225 if(server_object) { 00226 _bootstrapped = true; 00227 _error = false; 00228 } 00229 } 00230 00231 //Callback from mbed client stack when the registration 00232 // is successful, it returns the mbed Device Server object 00233 // to which the resources are registered and registered objects. 00234 void object_registered(M2MSecurity */*security_object*/, const M2MServer &/*server_object*/){ 00235 _registered = true; 00236 } 00237 00238 //Callback from mbed client stack when the registration update 00239 // is successful, it returns the mbed Device Server object 00240 // to which the resources are registered and registered objects. 00241 void registration_updated(M2MSecurity */*security_object*/, const M2MServer &/*server_object*/){ 00242 _registration_updated = true; 00243 } 00244 00245 //Callback from mbed client stack when the unregistration 00246 // is successful, it returns the mbed Device Server object 00247 // to which the resources were unregistered. 00248 void object_unregistered(M2MSecurity */*server_object*/){ 00249 _unregistered = true; 00250 } 00251 00252 //Callback from mbed client stack if any value has changed 00253 // during PUT operation. Object and its type is passed in 00254 // the callback. 00255 void value_updated(M2MBase *base, M2MBase::BaseType type) { 00256 printf("\nValue updated of Object name %s and Type %d\n", 00257 base->name().c_str(), type); 00258 } 00259 00260 //Callback from mbed client stack if any error is encountered 00261 // during any of the LWM2M operations. Error type is passed in 00262 // the callback. 00263 void error(M2MInterface::Error error){ 00264 _error = true; 00265 printf("\nError occured %d\n", error); 00266 } 00267 00268 private: 00269 00270 M2MInterface *_interface; 00271 M2MSecurity *_register_security; 00272 M2MObject *_resource_object; 00273 M2MObject *_object; 00274 volatile bool _bootstrapped; 00275 volatile bool _error; 00276 volatile bool _registered; 00277 volatile bool _unregistered; 00278 volatile bool _registration_updated; 00279 int _resource_value; 00280 TestConfig *_test_config; 00281 }; 00282 00283 #define WAIT_CALLBACK(X, TIMEOUT) \ 00284 {int _timer = 0;\ 00285 while ( 1 ) \ 00286 { \ 00287 _result &= (X); \ 00288 if (_result) { \ 00289 SUITE_TEST_INFO(_tn, "callback done"); \ 00290 break; \ 00291 } \ 00292 wait_ms(1000); _timer+=1; \ 00293 if (_timer >= TIMEOUT) { \ 00294 SUITE_TEST_INFO(_tn, "ERROR: callback timeout");\ 00295 break; \ 00296 } \ 00297 }} 00298 00299 bool test_bootStrap(TestConfig *test_config) { 00300 bool _result = true; 00301 const char* _tn = "TC1_bootStrap"; 00302 00303 SUITE_TEST_INFO(_tn, "STARTED"); 00304 00305 // Instantiate the class which implements 00306 // mbed Client API 00307 MbedClient *mbed_client = new MbedClient(test_config); 00308 00309 SUITE_TEST_INFO(_tn, "client done"); 00310 00311 // Create LWM2M Client API interface to manage bootstrap, 00312 // register and unregister 00313 _result &= mbed_client->create_interface(); 00314 00315 // Create LWM2M bootstrap object specifying bootstrap server 00316 // information. 00317 M2MSecurity* security_object = mbed_client->create_bootstrap_object(); 00318 00319 // Issue bootstrap command. 00320 mbed_client->test_bootstrap(security_object); 00321 SUITE_TEST_INFO(_tn, "bootstrap done"); 00322 00323 SUITE_TEST_INFO(_tn, "waiting bootstrap callback..."); 00324 // Wait till the bootstrap callback is called successfully. 00325 // Callback comes in bootstrap_done() 00326 WAIT_CALLBACK(mbed_client->bootstrap_successful(), CALLBACK_TIMEOUT); 00327 00328 // Delete security object created for bootstrapping 00329 if(security_object) { 00330 delete security_object; 00331 } 00332 00333 if (mbed_client) { 00334 delete mbed_client; 00335 } 00336 00337 SUITE_TEST_RESULT(_tn, _result); 00338 return _result; 00339 } 00340 00341 void test_deviceObject(TestConfig *test_config) { 00342 const char* _tn = "TC2_deviceObject"; 00343 00344 SUITE_TEST_INFO(_tn, "STARTED"); 00345 00346 // Instantiate the class which implements 00347 // LWM2M Client API 00348 MbedClient mbed_client(test_config);// = new MbedClient(test_config); 00349 00350 SUITE_TEST_INFO(_tn, "client done"); 00351 00352 // Create LWM2M Client API interface for M2M server 00353 mbed_client.create_interface(); 00354 00355 M2MSecurity *register_object = mbed_client.create_register_object(); 00356 00357 mbed_client.set_register_object(register_object); 00358 00359 // Create LWM2M device object specifying device resources 00360 // as per OMA LWM2M specification. 00361 M2MDevice* device_object = mbed_client.create_device_object(); 00362 00363 // Add the device object that we want to register 00364 // into the list and pass the list for register API. 00365 M2MObjectList object_list; 00366 object_list.push_back(device_object); 00367 00368 // Issue register command. 00369 00370 FunctionPointer1<void, M2MObjectList> tr(&mbed_client, &MbedClient::test_register); 00371 minar::Scheduler::postCallback(tr.bind(object_list)); 00372 00373 // Issue update register command. 00374 00375 uint32_t lifetime = 2222; 00376 00377 FunctionPointer1<void, uint32_t> ur(&mbed_client, &MbedClient::test_update_register); 00378 minar::Scheduler::postCallback(ur.bind(lifetime)).delay(MINAR_DELAY); 00379 00380 // Issue unregister command. 00381 00382 FunctionPointer0<void> tur(&mbed_client, &MbedClient::test_unregister); 00383 minar::Scheduler::postCallback(tur.bind()).delay(MINAR_DELAY*2); 00384 00385 FunctionPointer1<void, const char*> cus(&mbed_client, &MbedClient::check_result); 00386 minar::Scheduler::postCallback(cus.bind(_tn)).delay(MINAR_DELAY*3); 00387 00388 minar::Scheduler::start(); 00389 00390 // Delete device object created for registering device 00391 // resources. 00392 00393 if(device_object) { 00394 M2MDevice::delete_instance(); 00395 } 00396 } 00397 00398 bool test_resource(TestConfig *test_config) { 00399 bool _result = true; 00400 const char* _tn = "TC3_resource"; 00401 SUITE_TEST_INFO(_tn, "STARTED"); 00402 00403 // Instantiate the class which implements LWM2M Client API 00404 MbedClient mbed_client(test_config); 00405 SUITE_TEST_INFO(_tn, "client done"); 00406 00407 // Create LWM2M Client API interface for M2M server 00408 _result &= mbed_client.create_interface(); 00409 00410 M2MSecurity *register_object = mbed_client.create_register_object(); 00411 00412 mbed_client.set_register_object(register_object); 00413 00414 // Create LWM2M device object specifying device resources 00415 // as per OMA LWM2M specification. 00416 M2MDevice* device_object = mbed_client.create_device_object(); 00417 00418 // Create LWM2M generic object for resource 00419 M2MObject* resource_object = mbed_client.create_generic_object(); 00420 00421 // Add the device object that we want to register 00422 // into the list and pass the list for register API. 00423 M2MObjectList object_list; 00424 object_list.push_back(device_object); 00425 object_list.push_back(resource_object); 00426 00427 // Issue register command. 00428 00429 FunctionPointer1<void, M2MObjectList> tr(&mbed_client, &MbedClient::test_register); 00430 minar::Scheduler::postCallback(tr.bind(object_list)); 00431 00432 // Issue update register command. 00433 00434 uint32_t lifetime = 2222; 00435 00436 FunctionPointer1<void, uint32_t> ur(&mbed_client, &MbedClient::test_update_register); 00437 minar::Scheduler::postCallback(ur.bind(lifetime)).delay(MINAR_DELAY); 00438 00439 // Issue unregister command. 00440 00441 FunctionPointer0<void> tur(&mbed_client, &MbedClient::test_unregister); 00442 minar::Scheduler::postCallback(tur.bind()).delay(MINAR_DELAY*2); 00443 00444 FunctionPointer1<void, const char*> cus(&mbed_client, &MbedClient::check_result); 00445 minar::Scheduler::postCallback(cus.bind(_tn)).delay(MINAR_DELAY*3); 00446 00447 minar::Scheduler::start(); 00448 00449 // Delete device object created for registering device resources. 00450 if(device_object) { 00451 M2MDevice::delete_instance(); 00452 } 00453 00454 // Delete resource object for registering resources. 00455 if(resource_object) { 00456 delete resource_object; 00457 } 00458 } 00459 00460 00461 00462 void app_start(int /*argc*/, char* /*argv*/[]) { 00463 DigitalOut _led = DigitalOut(LED3); 00464 _led = 1; 00465 00466 MBED_HOSTTEST_TIMEOUT(40); 00467 MBED_HOSTTEST_SELECT(mbed_client_auto); 00468 MBED_HOSTTEST_DESCRIPTION(LWM2MClient Smoke Test); 00469 MBED_HOSTTEST_START("LWM2MClientSmokeTest"); 00470 00471 // This sets up the network interface configuration which will be used 00472 // by LWM2M Client API to communicate with mbed Device server. 00473 EthernetInterface eth; 00474 eth.init(); //Use DHCP 00475 eth.connect(); 00476 00477 lwipv4_socket_init(); 00478 00479 // Create test config object, and setup with unique MAC address 00480 TestConfig test_config; 00481 test_config.setup(); 00482 00483 _led = 0; 00484 00485 // Bootstrap test is uncommented, until it will be supported. 00486 //result &= test_bootStrap(&test_config); 00487 test_deviceObject(&test_config); 00488 test_resource(&test_config); 00489 00490 _led = 1; 00491 00492 // Disconnect and teardown the network interface 00493 eth.disconnect(); 00494 00495 SUITE_RESULT(test_result); 00496 } 00497
Generated on Tue Jul 12 2022 21:20:28 by
 1.7.2
 1.7.2