FRDM K64F Metronome

Revision:
0:a2cb7295a1f7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-client/test/mbedclient-smokeTest/main.cpp	Sun May 14 18:35:07 2017 +0000
@@ -0,0 +1,497 @@
+/*
+ * Copyright (c) 2015 ARM Limited. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "sockets/UDPSocket.h"
+#include "EthernetInterface.h"
+#include "test_env.h"
+#include "mbed-client/m2minterfacefactory.h"
+#include "mbed-client/m2minterfaceobserver.h"
+#include "mbed-client/m2mdevice.h"
+#include "mbed-client/m2mobjectinstance.h"
+#include "mbed-client/m2minterface.h"
+#include "testconfig.h"
+
+// TODO: Remove when yotta supports init.
+#include "lwipv4_init.h"
+
+// Minar for event scheduling
+#include "minar/minar.h"
+
+using namespace mbed::util;
+const String &MANUFACTURER = "ARM";
+const String &TYPE = "type";
+
+static bool test_result = false;
+
+// Dynamic resource variables
+const String &DYNAMIC_RESOURCE_NAME = "Dynamic";
+const String &DYNAMIC_RESOURCE_TYPE = "DynamicType";
+const String &STATIC_RESOURCE_NAME = "Static";
+const String &STATIC_RESOURCE_TYPE = "StaticType";
+const uint8_t STATIC_VALUE[] = "Static value";
+
+//TODO: should this be configured in .json conf file, and communicated via host test to here?
+int CALLBACK_TIMEOUT = 5;
+int MINAR_DELAY = 10000;
+
+#define SUITE_TEST_INFO(test_name, info)		printf("Suite-%s: %s\n", test_name, info)
+#define SUITE_TEST_RESULT(test_name, result)	printf("Suite-%s: result %s\n", test_name, result ? "PASSED" : "FAILED")
+#define SUITE_RESULT(result)					printf("Suite: result %s\n", result ? "success" : "failure")
+
+
+class MbedClient: public M2MInterfaceObserver {
+public:
+    MbedClient(TestConfig *test_config){
+        _interface = NULL;
+        _register_security = NULL;
+        _resource_object = NULL;
+        _bootstrapped = false;
+        _error = false;
+        _registered = false;
+        _unregistered = false;
+        _registration_updated = false;
+        _resource_value = 0;
+        _object = NULL;
+        _test_config = test_config;
+    }
+
+    virtual ~MbedClient() {
+        if(_interface) {
+            delete _interface;
+        }
+        if( _register_security){
+            delete _register_security;
+        }
+    }
+
+    bool create_interface() {
+        bool success = false;
+         // Creates M2MInterface using which endpoint can
+         // setup its name, resource type, life time, connection mode,
+         // Currently only LwIPv4 is supported.
+         _interface = M2MInterfaceFactory::create_interface( *this,
+                                                   _test_config->get_endpoint_name(),
+                                                   _test_config->get_endpoint_type(),
+                                                   _test_config->get_lifetime(),
+                                                   _test_config->get_port(),
+												   _test_config->get_domain(),
+                                                   M2MInterface::UDP,
+                                                   M2MInterface::LwIP_IPv4,
+                                                   "");
+         if (_interface) {
+             success = true;
+         }
+
+         return success;
+    }
+
+    bool bootstrap_successful() {
+        return _bootstrapped;
+    }
+
+    M2MSecurity* create_bootstrap_object() {
+        // Creates bootstrap server object with Bootstrap server address and other parameters
+        // required for client to connect to bootstrap server.
+        M2MSecurity *security = M2MInterfaceFactory::create_security(M2MSecurity::Bootstrap);
+        if(security) {
+            security->set_resource_value(M2MSecurity::M2MServerUri, _test_config->get_bootstrap_server());
+            security->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::NoSecurity);
+        }
+        return security;
+    }
+
+    void test_bootstrap(M2MSecurity *security) {
+        if(_interface) {
+             // Bootstrap function.
+            _interface->bootstrap(security);
+        }
+    }
+
+    bool register_successful() {
+        return _registered;
+    }
+
+    bool unregister_successful() {
+        return _unregistered;
+    }
+
+    bool update_register_successful() {
+        return _registration_updated;
+    }
+
+    void check_result(const char* result) {
+        if(_registered && _registration_updated && _unregistered) {
+            SUITE_TEST_RESULT(result, true);
+            test_result = true;
+        } else {
+           SUITE_TEST_RESULT(result, false);
+           test_result = false;
+        }
+        minar::Scheduler::stop();
+    }
+
+    M2MSecurity* create_register_object() {
+        // Creates server object with LWM2M server address and other parameters
+        // required for client to connect to LWM2M server.
+        M2MSecurity *security = M2MInterfaceFactory::create_security(M2MSecurity::M2MServer);
+        if(security) {
+            security->set_resource_value(M2MSecurity::M2MServerUri, _test_config->get_mds_server());
+            //security->set_resource_value(M2MSecurity::M2MServerUri, "ds-test.dev.mbed.com");
+            security->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::NoSecurity);
+        }
+        return security;
+    }
+
+    void test_register(M2MObjectList object_list){
+        if(_interface) {
+            // Register function
+            _interface->register_object(_register_security, object_list);
+        }
+    }
+
+    void test_update_register(const uint32_t lifetime)
+    {
+        if(_interface && _register_security) {
+            _interface->update_registration(_register_security,lifetime);
+        }        
+    }
+
+    void test_unregister(){
+        if(_interface) {
+            // Unregister function
+            _interface->unregister_object(NULL);
+        }
+    }
+
+    void set_register_object(M2MSecurity *&register_object){
+        if(_register_security) {
+            delete _register_security;
+            _register_security = NULL;
+        }
+        _register_security = register_object;
+    }
+
+    M2MDevice* create_device_object() {
+        M2MDevice *device = M2MInterfaceFactory::create_device();
+        if (device) {
+            device->create_resource(M2MDevice::Manufacturer, MANUFACTURER);
+            device->create_resource(M2MDevice::DeviceType, TYPE);
+        }
+        return device;
+    }
+
+    M2MObject* create_generic_object() {
+        _object = M2MInterfaceFactory::create_object("Test");
+        if(_object) {
+            M2MObjectInstance* inst = _object->create_object_instance();
+            if(inst) {
+                    M2MResource* res = inst->create_dynamic_resource("D","ResourceTest",
+                                                                     M2MResourceInstance::INTEGER,
+                                                                     true);
+                    char buffer[20];
+                    int size = sprintf(buffer,"%d",_resource_value);
+                    res->set_operation(M2MBase::GET_PUT_POST_ALLOWED);
+                    res->set_value((const uint8_t*)buffer,
+                                   (const uint32_t)size);
+                    _resource_value++;
+
+                    inst->create_static_resource("S",
+                                                 "ResourceTest",
+                                                 M2MResourceInstance::STRING,
+                                                 STATIC_VALUE,
+                                                 sizeof(STATIC_VALUE)-1);
+            }
+        }
+        return _object;
+    }
+
+    //Callback from mbed client stack when the bootstrap
+    // is successful, it returns the mbed Device Server object
+    // which will be used for registering the resources to
+    // mbed Device server.
+    void bootstrap_done(M2MSecurity *server_object){
+        if(server_object) {
+            _bootstrapped = true;
+            _error = false;
+        }
+    }
+
+    //Callback from mbed client stack when the registration
+    // is successful, it returns the mbed Device Server object
+    // to which the resources are registered and registered objects.
+    void object_registered(M2MSecurity */*security_object*/, const M2MServer &/*server_object*/){
+        _registered = true;
+    }
+
+    //Callback from mbed client stack when the registration update
+        // is successful, it returns the mbed Device Server object
+        // to which the resources are registered and registered objects.
+    void registration_updated(M2MSecurity */*security_object*/, const M2MServer &/*server_object*/){
+            _registration_updated = true;
+        }
+
+    //Callback from mbed client stack when the unregistration
+    // is successful, it returns the mbed Device Server object
+    // to which the resources were unregistered.
+    void object_unregistered(M2MSecurity */*server_object*/){
+        _unregistered = true;        
+    }
+
+    //Callback from mbed client stack if any value has changed
+    // during PUT operation. Object and its type is passed in
+    // the callback.
+    void value_updated(M2MBase *base, M2MBase::BaseType type) {
+        printf("\nValue updated of Object name %s and Type %d\n",
+               base->name().c_str(), type);
+    }
+
+    //Callback from mbed client stack if any error is encountered
+    // during any of the LWM2M operations. Error type is passed in
+    // the callback.
+    void error(M2MInterface::Error error){
+        _error = true;
+        printf("\nError occured %d\n", error);
+    }
+
+private:
+
+    M2MInterface    	*_interface;
+    M2MSecurity         *_register_security;
+    M2MObject			*_resource_object;
+    M2MObject           *_object;
+    volatile bool       _bootstrapped;
+    volatile bool       _error;
+    volatile bool       _registered;
+    volatile bool       _unregistered;
+    volatile bool       _registration_updated;
+    int                 _resource_value;
+    TestConfig			*_test_config;
+};
+
+#define WAIT_CALLBACK(X, TIMEOUT)                                  \
+{int _timer = 0;\
+while ( 1 )       \
+    { 													  \
+      _result &= (X);									  \
+      if (_result) {									  \
+          SUITE_TEST_INFO(_tn, "callback done");          \
+          break;										  \
+      }													  \
+      wait_ms(1000); _timer+=1;                           \
+      if (_timer >= TIMEOUT) {                            \
+          SUITE_TEST_INFO(_tn, "ERROR: callback timeout");\
+          break;                                          \
+      }                                                   \
+    }}
+
+bool test_bootStrap(TestConfig *test_config) {
+    bool _result = true;
+    const char* _tn = "TC1_bootStrap";
+
+    SUITE_TEST_INFO(_tn, "STARTED");
+
+    // Instantiate the class which implements
+    // mbed Client API
+    MbedClient *mbed_client = new MbedClient(test_config);
+
+    SUITE_TEST_INFO(_tn, "client done");
+
+    // Create LWM2M Client API interface to manage bootstrap,
+    // register and unregister
+    _result &= mbed_client->create_interface();
+
+    // Create LWM2M bootstrap object specifying bootstrap server
+    // information.
+    M2MSecurity* security_object = mbed_client->create_bootstrap_object();
+
+    // Issue bootstrap command.
+    mbed_client->test_bootstrap(security_object);
+    SUITE_TEST_INFO(_tn, "bootstrap done");
+
+    SUITE_TEST_INFO(_tn, "waiting bootstrap callback...");
+    // Wait till the bootstrap callback is called successfully.
+    // Callback comes in bootstrap_done()
+    WAIT_CALLBACK(mbed_client->bootstrap_successful(), CALLBACK_TIMEOUT);
+
+    // Delete security object created for bootstrapping
+    if(security_object) {
+        delete security_object;
+    }
+
+    if (mbed_client) {
+        delete mbed_client;
+    }
+
+    SUITE_TEST_RESULT(_tn, _result);
+    return _result;
+}
+
+void test_deviceObject(TestConfig *test_config) {
+    const char* _tn = "TC2_deviceObject";
+
+    SUITE_TEST_INFO(_tn, "STARTED");
+
+    // Instantiate the class which implements
+    // LWM2M Client API
+    MbedClient mbed_client(test_config);// = new MbedClient(test_config);
+
+    SUITE_TEST_INFO(_tn, "client done");
+
+    // Create LWM2M Client API interface for M2M server
+    mbed_client.create_interface();
+
+    M2MSecurity *register_object = mbed_client.create_register_object();
+
+    mbed_client.set_register_object(register_object);
+
+    // Create LWM2M device object specifying device resources
+    // as per OMA LWM2M specification.
+    M2MDevice* device_object = mbed_client.create_device_object();
+
+    // Add the device object that we want to register
+    // into the list and pass the list for register API.
+    M2MObjectList object_list;
+    object_list.push_back(device_object);
+
+    // Issue register command.
+
+    FunctionPointer1<void, M2MObjectList> tr(&mbed_client, &MbedClient::test_register);
+    minar::Scheduler::postCallback(tr.bind(object_list));
+
+    // Issue update register command.
+
+    uint32_t lifetime = 2222;
+
+    FunctionPointer1<void, uint32_t> ur(&mbed_client, &MbedClient::test_update_register);
+    minar::Scheduler::postCallback(ur.bind(lifetime)).delay(MINAR_DELAY);
+
+    // Issue unregister command.
+
+    FunctionPointer0<void> tur(&mbed_client, &MbedClient::test_unregister);
+    minar::Scheduler::postCallback(tur.bind()).delay(MINAR_DELAY*2);
+
+    FunctionPointer1<void, const char*> cus(&mbed_client, &MbedClient::check_result);
+    minar::Scheduler::postCallback(cus.bind(_tn)).delay(MINAR_DELAY*3);
+
+    minar::Scheduler::start();
+
+    // Delete device object created for registering device
+    // resources.
+
+    if(device_object) {
+        M2MDevice::delete_instance();
+    }
+}
+
+bool test_resource(TestConfig *test_config) {
+    bool _result = true;
+    const char* _tn = "TC3_resource";
+    SUITE_TEST_INFO(_tn, "STARTED");
+
+    // Instantiate the class which implements LWM2M Client API
+    MbedClient mbed_client(test_config);
+    SUITE_TEST_INFO(_tn, "client done");
+
+    // Create LWM2M Client API interface for M2M server
+    _result &= mbed_client.create_interface();
+
+    M2MSecurity *register_object = mbed_client.create_register_object();
+
+    mbed_client.set_register_object(register_object);
+
+    // Create LWM2M device object specifying device resources
+    // as per OMA LWM2M specification.
+    M2MDevice* device_object = mbed_client.create_device_object();
+
+    // Create LWM2M generic object for resource
+    M2MObject* resource_object = mbed_client.create_generic_object();
+
+    // Add the device object that we want to register
+    // into the list and pass the list for register API.
+    M2MObjectList object_list;
+    object_list.push_back(device_object);
+    object_list.push_back(resource_object);
+
+    // Issue register command.
+
+    FunctionPointer1<void, M2MObjectList> tr(&mbed_client, &MbedClient::test_register);
+    minar::Scheduler::postCallback(tr.bind(object_list));
+
+    // Issue update register command.
+
+    uint32_t lifetime = 2222;
+
+    FunctionPointer1<void, uint32_t> ur(&mbed_client, &MbedClient::test_update_register);
+    minar::Scheduler::postCallback(ur.bind(lifetime)).delay(MINAR_DELAY);
+
+    // Issue unregister command.
+
+    FunctionPointer0<void> tur(&mbed_client, &MbedClient::test_unregister);
+    minar::Scheduler::postCallback(tur.bind()).delay(MINAR_DELAY*2);
+
+    FunctionPointer1<void, const char*> cus(&mbed_client, &MbedClient::check_result);
+    minar::Scheduler::postCallback(cus.bind(_tn)).delay(MINAR_DELAY*3);
+
+    minar::Scheduler::start();
+
+    // Delete device object created for registering device resources.
+    if(device_object) {
+        M2MDevice::delete_instance();
+    }
+
+    // Delete resource object for registering resources.
+    if(resource_object) {
+        delete resource_object;
+    }
+}
+
+
+
+void app_start(int /*argc*/, char* /*argv*/[]) {
+    DigitalOut _led = DigitalOut(LED3);
+    _led = 1;
+
+    MBED_HOSTTEST_TIMEOUT(40);
+    MBED_HOSTTEST_SELECT(mbed_client_auto);
+    MBED_HOSTTEST_DESCRIPTION(LWM2MClient Smoke Test);
+    MBED_HOSTTEST_START("LWM2MClientSmokeTest");
+
+    // This sets up the network interface configuration which will be used
+    // by LWM2M Client API to communicate with mbed Device server.
+    EthernetInterface eth;
+    eth.init(); //Use DHCP
+    eth.connect();
+
+    lwipv4_socket_init();
+
+    // Create test config object, and setup with unique MAC address
+    TestConfig test_config;
+    test_config.setup();
+
+    _led = 0;
+
+    // Bootstrap test is uncommented, until it will be supported.
+    //result &= test_bootStrap(&test_config);
+    test_deviceObject(&test_config);
+    test_resource(&test_config);
+
+    _led = 1;
+
+    // Disconnect and teardown the network interface
+    eth.disconnect();
+
+    SUITE_RESULT(test_result);
+}
+