Example program running mbedClient over UbloxATCellularInterface or OnboardCellularInterface for the C030 platform.

Dependencies:   ublox-cellular-base ublox-at-cellular-interface ublox-ppp-cellular-interface ublox-at-cellular-interface-n2xx ublox-cellular-base-n2xx

Files at this revision

API Documentation at this revision

Comitter:
rob.meades@u-blox.com
Date:
Fri Jun 09 15:28:40 2017 +0100
Parent:
0:1811122ec272
Child:
2:49b5c377d2ca
Commit message:
Flesh out example.

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-client.lib Show annotated file Show diff for this revision Revisions of this file
mbed_client_config.h Show annotated file Show diff for this revision Revisions of this file
mbedtls_mbed_client_config.h Show annotated file Show diff for this revision Revisions of this file
pal.lib Show annotated file Show diff for this revision Revisions of this file
security.h Show annotated file Show diff for this revision Revisions of this file
simpleclient.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Jun 09 15:28:40 2017 +0100
@@ -0,0 +1,225 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2017 u-blox
+ *
+ * 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.
+ */
+
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+#include <string>
+#include <sstream>
+#include <vector>
+
+#include "mbed.h"
+#include "mbedtls/entropy_poll.h"
+#include "UbloxATCellularInterface.h"
+#include "simpleclient.h"
+#include "security.h"
+#include "mbed_trace.h"
+#include "mbed.h"
+
+// The credentials of the SIM in the board.  If PIN checking is enabled
+// for your SIM card you must set this to the required PIN.
+#define PIN "0000"
+
+// Network credentials.  You should set this according to your
+// network/SIM card.  For C030 boards, leave the parameters as NULL
+// otherwise, if you do not know the APN for your network, you may
+// either try the fairly common "internet" for the APN (and leave the
+// username and password NULL), or you may leave all three as NULL and then
+// a lookup will be attempted for a small number of known networks
+// (see APN_db.h in mbed-os/features/netsocket/cellular/utils).
+#define APN         NULL
+#define USERNAME    NULL
+#define PASSWORD    NULL
+
+// LEDs
+DigitalOut ledRed(LED1, 1);
+DigitalOut ledGreen(LED2, 1);
+DigitalOut ledBlue(LED3, 1);
+
+// The user button
+volatile bool buttonPressed = false;
+
+static void good() {
+    ledGreen = 0;
+    ledBlue = 1;
+    ledRed = 1;
+}
+
+static void bad() {
+    ledRed = 0;
+    ledGreen = 1;
+    ledBlue = 1;
+}
+
+static void event() {
+    ledBlue = 0;
+    ledRed = 1;
+    ledGreen = 1;
+}
+
+static void pulseEvent() {
+    event();
+    wait_ms(500);
+    good();
+}
+
+static void ledOff() {
+    ledBlue = 1;
+    ledRed = 1;
+    ledGreen = 1;
+}
+
+// Resource values for the Device Object
+struct MbedClientDevice device = {
+        "Manufacturer", // Manufacturer
+        "Type",         // Type
+        "ModelNumber",  // ModelNumber
+        "SerialNumber"  // SerialNumber
+        };
+
+class LedResource {
+public:
+    LedResource() {
+        ledObject = M2MInterfaceFactory::create_object("3311");
+        M2MObjectInstance *inst = ledObject->create_object_instance();
+
+        // An observable resource
+        M2MResource *onResource = inst->create_dynamic_resource("5850", "On/Off", M2MResourceInstance::BOOLEAN, true);
+        onResource->set_operation(M2MBase::GET_PUT_ALLOWED);
+        onResource->set_value(false);
+
+        // An multi-valued resource
+        M2MResource *dimmerResource = inst->create_dynamic_resource("5851", "Dimmer", M2MResourceInstance::BOOLEAN, false);
+        dimmerResource->set_operation(M2MBase::GET_PUT_ALLOWED);
+        dimmerResource->set_value(false);
+    }
+
+    ~LedResource() {
+    }
+
+    M2MObject *get_object() {
+        return ledObject;
+    }
+
+private:
+    M2MObject *ledObject;
+};
+
+static void cbButton()
+{
+    buttonPressed = true;
+    pulseEvent();
+}
+
+/* This example program for the u-blox C030 and C027 boards instantiates
+ * the mbedClient and runs it over a UbloxATCellularInterface connection to
+ * the mbed connector.
+ * Progress may be monitored with a serial terminal running at 9600 baud.
+ * The LED on the C030 board will turn green when this program is
+ * operating correctly, pulse blue when an mbedClient operation is completed
+ * and turn red if there is a failure.
+ *
+ * IMPORTANT to use this example you must first register with the mbed Connector:
+ *
+ * https://connector.mbed.com/
+ *
+ * ...using your mbed developer credentials and generate your own copy of the file
+ * security.h, replacing the empty one in this directory with yours and
+ * recompiling/downloading the code to your board.
+ */
+
+int main()
+{
+    UbloxATCellularInterface *interface = new UbloxATCellularInterface();
+    MbedClient *mbedClient = new MbedClient(device);
+    M2MObjectList objectList;
+    M2MSecurity *registerObject;
+    M2MDevice *deviceObject;
+    LedResource ledResource;
+    unsigned int seed;
+    size_t len;
+    InterruptIn userButton(SW0);
+
+    // Attach a function to the user button
+    userButton.rise(&cbButton);
+    
+    mbed_trace_init();
+    srand(seed);
+
+    // Randomize source port
+#ifdef TARGET_UBLOX_C030
+    mbedtls_hardware_poll(NULL, (unsigned char *) &seed, sizeof(seed), &len);
+#else
+    // NULL entropy, since C027 does not have a true random number generator
+    mbedtls_null_entropy_poll(NULL, (unsigned char *) &seed, sizeof(seed), &len);
+#endif
+
+    good();
+    printf("Starting up, please wait up to 180 seconds for network registration to complete...\n");
+    if (interface->init(PIN)) {
+        pulseEvent();
+        printf("Registered with network.\n");
+        
+        // Create endpoint interface to manage register and unregister
+        mbedClient->create_interface("coap://api.connector.mbed.com:5684", interface);
+
+        // Create objects of varying types, see simpleclient.h for more details on implementation.
+        registerObject = mbedClient->create_register_object(); // Server object specifying connector info
+        deviceObject = mbedClient->create_device_object();     // Device resources object
+
+        // Add objects to list
+        objectList.push_back(deviceObject);
+        objectList.push_back(ledResource.get_object());
+
+        // Set endpoint registration object
+        mbedClient->set_register_object(registerObject);
+
+        printf("Updating object registration in a loop (with a 30 second refresh period) until the user button is presed...\n");
+        interface->set_credentials(APN, USERNAME, PASSWORD);
+        while (!buttonPressed) {
+            // Make sure cellular is connected
+            if (interface->connect() == 0) {
+                pulseEvent();
+                printf("[Still] connected to packet network.\n");
+                if (mbedClient->register_successful()) {
+                    printf("Updating registration (follow progress at https://connector.mbed.com/#home)...\n");
+                    mbedClient->test_update_register();
+                } else {
+                    printf("Registering with connector (follow progress at https://connector.mbed.com/#home)...\n");
+                    mbedClient->test_register(registerObject, objectList);
+                }
+            } else {
+                bad();
+                printf("Failed to connect, will retry (have you checked that an antenna is plugged in and your APN is correct?)...\n");
+            }
+            Thread::wait(30000);
+            printf("[Checking if user button has been pressed]\n");
+        }
+        
+        pulseEvent();
+        printf("User button was pressed, stopping...\n");
+        mbedClient->test_unregister();
+        interface->disconnect();
+        interface->deinit();
+        ledOff();
+        printf("Stopped.\n");
+        M2MDevice::delete_instance();
+    } else {
+        bad();
+        printf("Unable to initialise the interface.\n");
+    }
+}
+
+// End Of File
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-client.lib	Fri Jun 09 15:28:40 2017 +0100
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mbed-client/#31e5ce203cc0f3e5c5e3fe5e01b396d7fe2ee8f9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_client_config.h	Fri Jun 09 15:28:40 2017 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 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.
+ */
+#ifndef MBED_CLIENT_CONFIG_H
+#define MBED_CLIENT_CONFIG_H
+
+
+// Defines the number of times client should try re-connection towards
+// Server in case of connectivity loss , also defines the number of CoAP
+// re-transmission attempts.Default value is 3
+#define M2M_CLIENT_RECONNECTION_COUNT		3
+
+// Defines the interval (in seconds) in which client should try re-connection towards
+// Server in case of connectivity loss , also use the same interval for CoAP
+// re-transmission attempts. Default value is 5 seconds
+#define M2M_CLIENT_RECONNECTION_INTERVAL	5
+
+// Defines the keep-alive interval (in seconds) in which client should send keep alive
+// pings to server while connected through TCP mode. Default value is 300 seconds
+#define M2M_CLIENT_TCP_KEEPALIVE_TIME 		300
+
+// Defines the maximum CoAP messages that client can hold, maximum value is 6
+#define SN_COAP_DUPLICATION_MAX_MSGS_COUNT  2
+
+// Defines the size of blockwise CoAP messages that client can handle.
+// The values that can be defined uust be 2^x and x is at least 4.
+// Suitable values: 0, 16, 32, 64, 128, 256, 512 and 1024
+#define SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE  1024
+
+// Many pure LWM2M servers doen't accept 'obs' text in registration message.
+// While using Client against such servers, this flag can be set to define to
+// disable client sending 'obs' text for observable resources.
+#undef COAP_DISABLE_OBS_FEATURE
+
+// Disable Bootstrap functionality in client in order to reduce code size, if bootstrap
+// functionality is not required.
+#undef M2M_CLIENT_DISABLE_BOOTSTRAP_FEATURE
+
+#endif // MBED_CLIENT_CONFIG_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbedtls_mbed_client_config.h	Fri Jun 09 15:28:40 2017 +0100
@@ -0,0 +1,111 @@
+/**
+ *  Minimal configuration for using mbedtls as part of mbed-client
+ *
+ *  NOTE! This is an optimized, minimal configuration for mbed Client.
+ *  We know it works with mbed Client but if you want to add more
+ *  services/communications to the application yourself - please ensure
+ *  you update this configuration accordingly. The default configuration
+ *  can be found from mbedTLS Github:
+ *
+ *  https://github.com/ARMmbed/mbedtls/blob/development/include/mbedtls/config.h
+ *
+ *
+ *  Copyright (C) 2006-2016, 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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+
+#ifndef MBEDTLS_CUSTOM_CONFIG_H
+#define MBEDTLS_CUSTOM_CONFIG_H
+
+/* System support */
+#define MBEDTLS_HAVE_ASM
+
+/* mbed TLS feature support */
+#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#define MBEDTLS_ECP_NIST_OPTIM
+#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+#define MBEDTLS_SSL_PROTO_TLS1_2
+#define MBEDTLS_SSL_PROTO_DTLS
+#define MBEDTLS_SSL_DTLS_ANTI_REPLAY
+#define MBEDTLS_SSL_DTLS_HELLO_VERIFY
+#define MBEDTLS_SSL_EXPORT_KEYS
+
+/* mbed TLS modules */
+#define MBEDTLS_AES_C
+#define MBEDTLS_ASN1_PARSE_C
+#define MBEDTLS_ASN1_WRITE_C
+#define MBEDTLS_BIGNUM_C
+#define MBEDTLS_CIPHER_C
+#define MBEDTLS_CTR_DRBG_C
+#define MBEDTLS_ECP_C
+#define MBEDTLS_ENTROPY_C
+#define MBEDTLS_MD_C
+#define MBEDTLS_OID_C
+#define MBEDTLS_PK_C
+#define MBEDTLS_PK_PARSE_C
+#define MBEDTLS_SHA256_C
+#define MBEDTLS_SSL_COOKIE_C
+#define MBEDTLS_SSL_CLI_C
+#define MBEDTLS_SSL_SRV_C
+#define MBEDTLS_SSL_TLS_C
+
+// XXX mbedclient needs these: mbedtls_x509_crt_free, mbedtls_x509_crt_init, mbedtls_x509_crt_parse
+#define MBEDTLS_X509_USE_C
+#define MBEDTLS_X509_CRT_PARSE_C
+
+// XXX: clean these up!!
+#define MBEDTLS_SHA512_C
+#define MBEDTLS_ECDH_C
+#define MBEDTLS_GCM_C
+
+#define MBEDTLS_ECDH_C
+#define MBEDTLS_ECDSA_C
+#define MBEDTLS_X509_CRT_PARSE_C
+
+// Remove RSA, save 20KB at total
+#undef MBEDTLS_RSA_C
+#undef MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+
+// Remove error messages, save 10KB of ROM
+#undef MBEDTLS_ERROR_C
+
+// Remove selftesting and save 11KB of ROM
+#undef MBEDTLS_SELF_TEST
+
+// Reduces ROM size by 30 kB
+#undef MBEDTLS_ERROR_STRERROR_DUMMY
+#undef MBEDTLS_VERSION_FEATURES
+#undef MBEDTLS_DEBUG_C
+
+// needed for parsing the certificates
+#define MBEDTLS_PEM_PARSE_C
+// dep of the previous
+#define MBEDTLS_BASE64_C
+
+// Reduce IO buffer to save RAM, default is 16KB
+#define MBEDTLS_SSL_MAX_CONTENT_LEN 2048
+
+// define to save 8KB RAM at the expense of ROM
+#undef MBEDTLS_AES_ROM_TABLES
+
+// Save ROM and a few bytes of RAM by specifying our own ciphersuite list
+#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+
+#include "mbedtls/check_config.h"
+
+#endif /* MBEDTLS_CUSTOM_CONFIG_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pal.lib	Fri Jun 09 15:28:40 2017 +0100
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/pal/#4e46c0ea870631bb5bec3e4aa9fd7eebf3db21f0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/security.h	Fri Jun 09 15:28:40 2017 +0100
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+ 
+ /* IMPORTANT: THIS IS A DUMMY FILE! To use this example you must first
+  * register with the mbed Connector here:
+  *
+  * https://connector.mbed.com/
+  *
+  * ...and generate your own copy of the file security.h, replacing this file
+  * with that one and recompiling/downloading the code to your board.
+  */
+
+#ifndef __SECURITY_H__
+#define __SECURITY_H__
+ 
+#include <inttypes.h>
+ 
+#error THIS IS A DUMMY FILE! Generate your own one by logging into https://connector.mbed.com/.
+ 
+#define MBED_DOMAIN ""
+#define MBED_ENDPOINT_NAME ""
+ 
+const uint8_t SERVER_CERT[] = "";
+ 
+const uint8_t CERT[] = "";
+ 
+const uint8_t KEY[] = "";
+ 
+#endif //__SECURITY_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/simpleclient.h	Fri Jun 09 15:28:40 2017 +0100
@@ -0,0 +1,361 @@
+/*
+ * 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.
+ */
+
+#ifndef __SIMPLECLIENT_H__
+#define __SIMPLECLIENT_H__
+
+#include "mbed-client/m2minterfacefactory.h"
+#include "mbed-client/m2mdevice.h"
+#include "mbed-client/m2minterfaceobserver.h"
+#include "mbed-client/m2minterface.h"
+#include "mbed-client/m2mobject.h"
+#include "mbed-client/m2mobjectinstance.h"
+#include "mbed-client/m2mresource.h"
+#include "mbed-client/m2mconfig.h"
+#include "mbed-client/m2mblockmessage.h"
+#include "security.h"
+#include "mbed.h"
+
+#define ETHERNET        1
+#define WIFI            2
+#define MESH_LOWPAN_ND  3
+#define MESH_THREAD     4
+#define ATMEL           5
+#define MCR20           6
+#define SPIRIT1         7
+#define CELL            8
+
+#define STRINGIFY(s) #s
+
+M2MInterface::NetworkStack NETWORK_STACK = M2MInterface::LwIP_IPv4;
+
+M2MInterface::BindingMode SOCKET_MODE = M2MInterface::UDP;
+
+struct MbedClientDevice {
+    const char* Manufacturer;
+    const char* Type;
+    const char* ModelNumber;
+    const char* SerialNumber;
+};
+
+/*
+* Wrapper for mbed client stack that handles all callbacks, error handling, and
+* other shenanigans to make the mbed client stack easier to use.
+*
+* The end user should only have to care about configuring the parameters at the
+* top of this file and making sure they add the security.h file correctly.
+* To add resources you can copy the _TODO__ function and add as many instances as
+* you want.
+*
+*/
+class MbedClient: public M2MInterfaceObserver {
+    
+public:
+
+    /*
+     * Constructor for MbedClient object, initialize private variables
+     */
+    MbedClient(struct MbedClientDevice device)
+    {
+        _interface = NULL;
+        _bootstrapped = false;
+        _error = false;
+        _registered = false;
+        _unregistered = false;
+        _register_security = NULL;
+        _value = 0;
+        _object = NULL;
+        _device = device;
+    }
+
+    /*
+     * Destructor for MbedClient object, you can ignore this
+     */
+    ~MbedClient()
+    {
+        if (_interface) {
+            delete _interface;
+        }
+        if (_register_security) {
+            delete _register_security;
+        }
+    }
+
+    /*
+     *  Creates M2MInterface using which endpoint can
+     *  setup its name, resource type, life time, connection mode,
+     *  Currently only LwIPv4 is supported.
+     */
+    void create_interface(const char *server_address, void *handler=NULL)
+    {
+        // Randomizing listening port for Certificate mode connectivity
+        _server_address = server_address;
+        uint16_t port = 0; // Network interface will randomize with port 0
+
+        // Create mDS interface object, this is the base object everything else attaches to
+        _interface = M2MInterfaceFactory::create_interface(*this,
+                                                          MBED_ENDPOINT_NAME,       // endpoint name string
+                                                          "test",                   // endpoint type string
+                                                          100,                      // lifetime
+                                                          port,                     // listen port
+                                                          MBED_DOMAIN,              // domain string
+                                                          SOCKET_MODE,              // binding mode
+                                                          NETWORK_STACK,            // network stack
+                                                          "");                      // context address string
+        const char *binding_mode = (SOCKET_MODE == M2MInterface::UDP) ? "UDP" : "TCP";
+        printf("SOCKET_MODE : %s\n", binding_mode);
+        printf("Connecting to %s\n", server_address);
+
+        if (_interface) {
+            _interface->set_platform_network_handler(handler);
+        }
+    }
+
+    /*
+     *  Check private variable to see if the registration was sucessful or not
+     */
+    bool register_successful()
+    {
+        return _registered;
+    }
+
+    /*
+     *  Check private variable to see if un-registration was sucessful or not
+     */
+    bool unregister_successful()
+    {
+        return _unregistered;
+    }
+
+    /*
+     *  Creates register server object with mbed device server address and other parameters
+     *  required for client to connect to mbed device server.
+     */
+    M2MSecurity* create_register_object()
+    {
+        // Create security object using the interface factory.
+        // this will generate a security ObjectID and ObjectInstance
+        M2MSecurity *security = M2MInterfaceFactory::create_security(M2MSecurity::M2MServer);
+
+        // Make sure security ObjectID/ObjectInstance was created successfully
+        if (security) {
+            // Add ResourceID's and values to the security ObjectID/ObjectInstance
+            security->set_resource_value(M2MSecurity::M2MServerUri, _server_address);
+            security->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::Certificate);
+            security->set_resource_value(M2MSecurity::ServerPublicKey, SERVER_CERT, sizeof(SERVER_CERT) - 1);
+            security->set_resource_value(M2MSecurity::PublicKey, CERT, sizeof(CERT) - 1);
+            security->set_resource_value(M2MSecurity::Secretkey, KEY, sizeof(KEY) - 1);
+        }
+        return security;
+    }
+
+    /*
+     * Creates device object which contains mandatory resources linked with
+     * device endpoint.
+     */
+    M2MDevice* create_device_object()
+    {
+        // Create device objectID/ObjectInstance
+        M2MDevice *device = M2MInterfaceFactory::create_device();
+        // Make sure device object was created successfully
+        if (device) {
+            // Add resourceID's to device objectID/ObjectInstance
+            device->create_resource(M2MDevice::Manufacturer, _device.Manufacturer);
+            device->create_resource(M2MDevice::DeviceType, _device.Type);
+            device->create_resource(M2MDevice::ModelNumber, _device.ModelNumber);
+            device->create_resource(M2MDevice::SerialNumber, _device.SerialNumber);
+        }
+        return device;
+    }
+
+    /*
+     * Register an object
+     */
+    void test_register(M2MSecurity *register_object, M2MObjectList object_list)
+    {
+        if (_interface) {
+            // Register function
+            _interface->register_object(register_object, object_list);
+        }
+    }
+
+    /*
+     * Unregister all objects
+     */
+    void test_unregister()
+    {
+        if (_interface) {
+            // Unregister function
+            _interface->unregister_object(NULL); // NULL will unregister all objects
+        }
+    }
+
+    /*
+     * 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;
+            printf("Bootstrapped\n");
+        }
+    }
+
+    /*
+     * 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;
+        _unregistered = false;
+        printf("Registered object successfully!\n");
+    }
+
+    /*
+     * 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*/)
+    {
+        printf("Unregistered object successfully\n");
+        _unregistered = true;
+        _registered = false;
+    }
+
+    /*
+     * Callback from mbed client stack when registration is updated
+     */
+    void registration_updated(M2MSecurity */*security_object*/, const M2MServer & /*server_object*/)
+    {
+        /* The registration is updated automatically and frequently by the
+        *  mbed client stack. This print statement is turned off because it
+        *  tends to happen a lot.
+        */
+        //printf("Registration updated\n");
+    }
+
+    /*
+     * 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;
+        switch (error){
+            case M2MInterface::AlreadyExists:
+                printf("[ERROR:] M2MInterface::AlreadyExist\n");
+                break;
+            case M2MInterface::BootstrapFailed:
+                printf("[ERROR:] M2MInterface::BootstrapFailed\n");
+                break;
+            case M2MInterface::InvalidParameters:
+                printf("[ERROR:] M2MInterface::InvalidParameters\n");
+                break;
+            case M2MInterface::NotRegistered:
+                printf("[ERROR:] M2MInterface::NotRegistered\n");
+                break;
+            case M2MInterface::Timeout:
+                printf("[ERROR:] M2MInterface::Timeout\n");
+                break;
+            case M2MInterface::NetworkError:
+                printf("[ERROR:] M2MInterface::NetworkError\n");
+                break;
+            case M2MInterface::ResponseParseFailed:
+                printf("[ERROR:] M2MInterface::ResponseParseFailed\n");
+                break;
+            case M2MInterface::UnknownError:
+                printf("[ERROR:] M2MInterface::UnknownError\n");
+                break;
+            case M2MInterface::MemoryFail:
+                printf("[ERROR:] M2MInterface::MemoryFail\n");
+                break;
+            case M2MInterface::NotAllowed:
+                printf("[ERROR:] M2MInterface::NotAllowed\n");
+                break;
+            case M2MInterface::SecureConnectionFailed:
+                printf("[ERROR:] M2MInterface::SecureConnectionFailed\n");
+                break;
+            case M2MInterface::DnsResolvingFailed:
+                printf("[ERROR:] M2MInterface::DnsResolvingFailed\n");
+                break;
+            default:
+                break;
+        }
+    }
+
+    /*
+     * Callback from mbed client stack if any value has changed
+     *  during PUT operation. Object and its type is passed in
+     *  the callback.
+     *  BaseType enum from m2mbase.h
+     *       Object = 0x0, Resource = 0x1, ObjectInstance = 0x2, ResourceInstance = 0x3
+     */
+    void value_updated(M2MBase *base, M2MBase::BaseType type)
+    {
+        printf("PUT request received!");
+        printf("Name :'%s', \nPath : '%s', \nType : '%d' (0 for Object, 1 for Resource), \nType : '%s'\n",
+               base->name(),
+               base->uri_path(),
+               type,
+               base->resource_type());
+    }
+
+    /*
+     * Update the registration period
+     */
+    void test_update_register()
+    {
+        if (_registered) {
+            _interface->update_registration(_register_security, 100);
+        }
+    }
+
+    /*
+     * Manually configure the security object private variable
+     */
+   void set_register_object(M2MSecurity *register_object)
+   {
+        if (_register_security == NULL) {
+            _register_security = register_object;
+        }
+    }
+
+private:
+
+    /*
+     *  Private variables used in class
+     */
+    M2MInterface             *_interface;
+    M2MSecurity              *_register_security;
+    M2MObject                *_object;
+    volatile bool            _bootstrapped;
+    volatile bool            _error;
+    volatile bool            _registered;
+    volatile bool            _unregistered;
+    int                      _value;
+    struct MbedClientDevice  _device;
+    String                   _server_address;
+};
+
+#endif // __SIMPLECLIENT_H__