Embed client working with Cell network.

Dependencies:   C027Interface

Fork of U_Blox_DeviceConnector by Sarah Marsh

Revision:
21:b88cdeb5b302
Parent:
19:91eb6f58fd77
Child:
39:4a161de53cde
--- a/main.cpp	Wed Oct 05 05:15:22 2016 +0100
+++ b/main.cpp	Fri Oct 21 09:30:10 2016 +0100
@@ -1,383 +1,475 @@
-/*
- * 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 "simpleclient.h"
-#include <string>
-#include <sstream>
-#include <vector>
-#include "mbed-trace/mbed_trace.h"
-#include "mbedtls/entropy_poll.h"
-
-#include "security.h"
-
-#include "mbed.h"
-#include "rtos.h"
-
-#define ETHERNET        1
-#define WIFI            2
-#define MESH_LOWPAN_ND  3
-#define MESH_THREAD     4
-
-#define STRINGIFY(s) #s
-
-#if MBED_CONF_APP_NETWORK_INTERFACE == WIFI
-#include "ESP8266Interface.h"
-ESP8266Interface esp(MBED_CONF_APP_WIFI_TX, MBED_CONF_APP_WIFI_RX);
-#elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET
-#include "EthernetInterface.h"
-EthernetInterface eth;
-#elif MBED_CONF_APP_NETWORK_INTERFACE == MESH_LOWPAN_ND
-#define MESH
-#include "NanostackInterface.h"
-LoWPANNDInterface mesh;
-#elif MBED_CONF_APP_NETWORK_INTERFACE == MESH_THREAD
-#define MESH
-#include "NanostackInterface.h"
-ThreadInterface mesh;
-#endif
-
-#ifndef MESH
-// This is address to mbed Device Connector
-#define MBED_SERVER_ADDRESS "coap://api.connector.mbed.com:5684"
-#else
-// This is address to mbed Device Connector
-#define MBED_SERVER_ADDRESS "coaps://[2607:f0d0:2601:52::20]:5684"
-#endif
-
-Serial output(USBTX, USBRX);
-
-// These are example resource values for the Device Object
-struct MbedClientDevice device = {
-    "Manufacturer_String",      // Manufacturer
-    "Type_String",              // Type
-    "ModelNumber_String",       // ModelNumber
-    "SerialNumber_String"       // SerialNumber
-};
-
-// Instantiate the class which implements LWM2M Client API (from simpleclient.h)
-MbedClient mbed_client(device);
-
-
-// In case of K64F board , there is button resource available
-// to change resource value and unregister
-#ifdef TARGET_K64F
-// Set up Hardware interrupt button.
-InterruptIn obs_button(SW2);
-InterruptIn unreg_button(SW3);
-#else
-//In non K64F boards , set up a timer to simulate updating resource,
-// there is no functionality to unregister.
-Ticker timer;
-#endif
-
-// LED Output
-DigitalOut led1(LED1);
-
-/*
- * The Led contains one property (pattern) and a function (blink).
- * When the function blink is executed, the pattern is read, and the LED
- * will blink based on the pattern.
- */
-class LedResource {
-public:
-    LedResource() {
-        // create ObjectID with metadata tag of '3201', which is 'digital output'
-        led_object = M2MInterfaceFactory::create_object("3201");
-        M2MObjectInstance* led_inst = led_object->create_object_instance();
-
-        // 5853 = Multi-state output
-        M2MResource* pattern_res = led_inst->create_dynamic_resource("5853", "Pattern",
-            M2MResourceInstance::STRING, false);
-        // read and write
-        pattern_res->set_operation(M2MBase::GET_PUT_ALLOWED);
-        // set initial pattern (toggle every 200ms. 7 toggles in total)
-        pattern_res->set_value((const uint8_t*)"500:500:500:500:500:500:500", 27);
-
-        // there's not really an execute LWM2M ID that matches... hmm...
-        M2MResource* led_res = led_inst->create_dynamic_resource("5850", "Blink",
-            M2MResourceInstance::OPAQUE, false);
-        // we allow executing a function here...
-        led_res->set_operation(M2MBase::POST_ALLOWED);
-        // when a POST comes in, we want to execute the led_execute_callback
-        led_res->set_execute_function(execute_callback(this, &LedResource::blink));
-    }
-
-    M2MObject* get_object() {
-        return led_object;
-    }
-
-    void blink(void *) {
-        // read the value of 'Pattern'
-        M2MObjectInstance* inst = led_object->object_instance();
-        M2MResource* res = inst->resource("5853");
-
-        // values in mbed Client are all buffers, and we need a vector of int's
-        uint8_t* buffIn = NULL;
-        uint32_t sizeIn;
-        res->get_value(buffIn, sizeIn);
-
-        // turn the buffer into a string, and initialize a vector<int> on the heap
-        std::string s((char*)buffIn, sizeIn);
-        std::vector<uint32_t>* v = new std::vector<uint32_t>;
-
-        output.printf("led_execute_callback pattern=%s\r\n", s.c_str());
-
-        // our pattern is something like 500:200:500, so parse that
-        std::size_t found = s.find_first_of(":");
-        while (found!=std::string::npos) {
-
-            v->push_back(atoi((const char*)s.substr(0,found).c_str()));
-            s = s.substr(found+1);
-            found=s.find_first_of(":");
-            if(found == std::string::npos) {
-                v->push_back(atoi((const char*)s.c_str()));
-            }
-        }
-
-
-        // do_blink is called with the vector, and starting at -1
-        do_blink(v, 0);
-    }
-
-private:
-    M2MObject* led_object;
-
-    void do_blink(std::vector<uint32_t>* pattern, uint16_t position) {
-        // blink the LED
-        led1 = !led1;
-
-        // up the position, if we reached the end of the vector
-        if (position >= pattern->size()) {
-            // free memory, and exit this function
-            delete pattern;
-            return;
-        }
-
-        // how long do we need to wait before the next blink?
-        uint32_t delay_ms = pattern->at(position);
-
-        // Invoke same function after `delay_ms` (upping position)
-        Thread::wait(delay_ms);
-        do_blink(pattern, ++position);
-    }
-};
-
-/*
- * The button contains one property (click count).
- * When `handle_button_click` is executed, the counter updates.
- */
-class ButtonResource {
-public:
-    ButtonResource(): counter(0) {
-        // create ObjectID with metadata tag of '3200', which is 'digital input'
-        btn_object = M2MInterfaceFactory::create_object("3200");
-        M2MObjectInstance* btn_inst = btn_object->create_object_instance();
-        // create resource with ID '5501', which is digital input counter
-        M2MResource* btn_res = btn_inst->create_dynamic_resource("5501", "Button",
-            M2MResourceInstance::INTEGER, true /* observable */);
-        // we can read this value
-        btn_res->set_operation(M2MBase::GET_ALLOWED);
-        // set initial value (all values in mbed Client are buffers)
-        // to be able to read this data easily in the Connector console, we'll use a string
-        btn_res->set_value((uint8_t*)"0", 1);        
-    }
-
-    ~ButtonResource() {
-    }
-
-    M2MObject* get_object() {
-        return btn_object;
-    }
-
-    /*
-     * When you press the button, we read the current value of the click counter
-     * from mbed Device Connector, then up the value with one.
-     */
-    void handle_button_click() {
-        M2MObjectInstance* inst = btn_object->object_instance();
-        M2MResource* res = inst->resource("5501");
-
-        // up counter
-        counter++;
-#ifdef TARGET_K64F
-        printf("handle_button_click, new value of counter is %d\r\n", counter);
-#else
-        printf("simulate button_click, new value of counter is %d\r\n", counter);
-#endif
-        // serialize the value of counter as a string, and tell connector
-        char buffer[20];
-        int size = sprintf(buffer,"%d",counter);
-        res->set_value((uint8_t*)buffer, size);
-    }
-
-private:
-    M2MObject* btn_object;
-    uint16_t counter;
-};
-
-// Network interaction must be performed outside of interrupt context
-Semaphore updates(0);
-volatile bool registered = false;
-volatile bool clicked = false;
-osThreadId mainThread;
-
-void unregister() {
-    registered = false;
-    updates.release();
-}
-
-void button_clicked() {
-    clicked = true;
-    updates.release();
-}
-
-// debug printf function
-void trace_printer(const char* str) {
-    printf("%s\r\n", str);
-}
-
-// Status indication
-Ticker status_ticker;
-DigitalOut status_led(LED1);
-void blinky() { status_led = !status_led; }
-
-
-// Entry point to the program
-int main() {
-
-    unsigned int seed;
-    size_t len;
-
-#ifdef MBEDTLS_ENTROPY_HARDWARE_ALT
-    // Used to randomize source port
-    mbedtls_hardware_poll(NULL, (unsigned char *) &seed, sizeof seed, &len);
-
-#elif defined MBEDTLS_TEST_NULL_ENTROPY
-
-#warning "mbedTLS security feature is disabled. Connection will not be secure !! Implement proper hardware entropy for your selected hardware."
-    // Used to randomize source port
-    mbedtls_null_entropy_poll( NULL,(unsigned char *) &seed, sizeof seed, &len);
-
-#else
-
-#error "This hardware does not have entropy, endpoint will not register to Connector.\
-You need to enable NULL ENTROPY for your application, but if this configuration change is made then no security is offered by mbed TLS.\
-Add MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES and MBEDTLS_TEST_NULL_ENTROPY in mbed_app.json macros to register your endpoint."
-
-#endif
-
-    srand(seed);
-
-    status_ticker.attach_us(blinky, 250000);
-
-    // Keep track of the main thread
-    mainThread = osThreadGetId();
-
-    // Sets the console baud-rate
-    output.baud(115200);
-
-    output.printf("Starting mbed Client example...\r\n");
-
-    mbed_trace_init();
-    mbed_trace_print_function_set(trace_printer);
-
-    NetworkInterface *network_interface = 0;
-    int connect_success = -1;
-#if MBED_CONF_APP_NETWORK_INTERFACE == WIFI
-    output.printf("\n\rUsing WiFi \r\n");
-    output.printf("\n\rConnecting to WiFi..\r\n");
-    connect_success = esp.connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD);
-    network_interface = &esp;
-#elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET
-    output.printf("Using Ethernet\r\n");
-    connect_success = eth.connect();
-    network_interface = &eth;
-#endif
-#ifdef MESH
-    output.printf("Using Mesh\r\n");
-    output.printf("\n\rConnecting to Mesh..\r\n");
-    connect_success = mesh.connect();
-    network_interface = &mesh;
-#endif
-    if(connect_success == 0) {
-    output.printf("\n\rConnected to Network successfully\r\n");
-    } else {
-        output.printf("\n\rConnection to Network Failed %d! Exiting application....\r\n", connect_success);
-        return 0;
-    }
-    const char *ip_addr = network_interface->get_ip_address();
-    if (ip_addr) {
-        output.printf("IP address %s\r\n", ip_addr);
-    } else {
-        output.printf("No IP address\r\n");
-    }
-
-    // we create our button and LED resources
-    ButtonResource button_resource;
-    LedResource led_resource;
-
-#ifdef TARGET_K64F
-    // On press of SW3 button on K64F board, example application
-    // will call unregister API towards mbed Device Connector
-    //unreg_button.fall(&mbed_client,&MbedClient::test_unregister);
-    unreg_button.fall(&unregister);
-
-    // Observation Button (SW2) press will send update of endpoint resource values to connector
-    obs_button.fall(&button_clicked);
-#else
-    // Send update of endpoint resource values to connector every 15 seconds periodically
-    timer.attach(&button_clicked, 15.0);
-#endif
-
-    // Create endpoint interface to manage register and unregister
-    mbed_client.create_interface(MBED_SERVER_ADDRESS, network_interface);
-
-    // Create Objects of varying types, see simpleclient.h for more details on implementation.
-    M2MSecurity* register_object = mbed_client.create_register_object(); // server object specifying connector info
-    M2MDevice*   device_object   = mbed_client.create_device_object();   // device resources object
-
-    // Create list of Objects to register
-    M2MObjectList object_list;
-
-    // Add objects to list
-    object_list.push_back(device_object);
-    object_list.push_back(button_resource.get_object());
-    object_list.push_back(led_resource.get_object());
-
-    // Set endpoint registration object
-    mbed_client.set_register_object(register_object);
-
-    // Register with mbed Device Connector
-    mbed_client.test_register(register_object, object_list);
-    registered = true;
-
-    while (true) {
-        updates.wait(25000);
-        if(registered) {
-            if(!clicked) {
-                mbed_client.test_update_register();
-            }
-        }else {
-            break;
-        }
-        if(clicked) {
-           clicked = false;
-            button_resource.handle_button_click();
-        }
-    }
-
-    mbed_client.test_unregister();
-    status_ticker.detach();
-}
+/*
+ * 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 "simpleclient.h"
+#include <string>
+#include <sstream>
+#include <vector>
+#include "mbed-trace/mbed_trace.h"
+#include "mbedtls/entropy_poll.h"
+
+#include "security.h"
+
+#include "mbed.h"
+#include "rtos.h"
+
+#if MBED_CONF_APP_NETWORK_INTERFACE == WIFI
+#include "ESP8266Interface.h"
+ESP8266Interface esp(MBED_CONF_APP_WIFI_TX, MBED_CONF_APP_WIFI_RX);
+#elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET
+#include "EthernetInterface.h"
+EthernetInterface eth;
+#elif MBED_CONF_APP_NETWORK_INTERFACE == MESH_LOWPAN_ND
+#define MESH
+#include "NanostackInterface.h"
+LoWPANNDInterface mesh;
+#elif MBED_CONF_APP_NETWORK_INTERFACE == MESH_THREAD
+#define MESH
+#include "NanostackInterface.h"
+ThreadInterface mesh;
+#endif
+
+#if defined(MESH)
+#if MBED_CONF_APP_MESH_RADIO_TYPE == ATMEL
+#include "NanostackRfPhyAtmel.h"
+NanostackRfPhyAtmel rf_phy(ATMEL_SPI_MOSI, ATMEL_SPI_MISO, ATMEL_SPI_SCLK, ATMEL_SPI_CS,
+                           ATMEL_SPI_RST, ATMEL_SPI_SLP, ATMEL_SPI_IRQ, ATMEL_I2C_SDA, ATMEL_I2C_SCL);
+#elif MBED_CONF_APP_MESH_RADIO_TYPE == MCR20
+#include "NanostackRfPhyMcr20a.h"
+NanostackRfPhyMcr20a rf_phy(MCR20A_SPI_MOSI, MCR20A_SPI_MISO, MCR20A_SPI_SCLK, MCR20A_SPI_CS, MCR20A_SPI_RST, MCR20A_SPI_IRQ);
+#endif //MBED_CONF_APP_RADIO_TYPE
+#endif //MESH
+
+#ifndef MESH
+// This is address to mbed Device Connector
+#define MBED_SERVER_ADDRESS "coap://api.connector.mbed.com:5684"
+#else
+// This is address to mbed Device Connector
+#define MBED_SERVER_ADDRESS "coaps://[2607:f0d0:2601:52::20]:5684"
+#endif
+
+Serial output(USBTX, USBRX);
+
+// Status indication
+DigitalOut red_led(LED1);
+DigitalOut green_led(LED2);
+DigitalOut blue_led(LED3);
+Ticker status_ticker;
+void blinky() {
+    green_led = !green_led;
+
+}
+
+// These are example resource values for the Device Object
+struct MbedClientDevice device = {
+    "Manufacturer_String",      // Manufacturer
+    "Type_String",              // Type
+    "ModelNumber_String",       // ModelNumber
+    "SerialNumber_String"       // SerialNumber
+};
+
+// Instantiate the class which implements LWM2M Client API (from simpleclient.h)
+MbedClient mbed_client(device);
+
+
+// In case of K64F board , there is button resource available
+// to change resource value and unregister
+#ifdef TARGET_K64F
+// Set up Hardware interrupt button.
+InterruptIn obs_button(SW2);
+InterruptIn unreg_button(SW3);
+#else
+//In non K64F boards , set up a timer to simulate updating resource,
+// there is no functionality to unregister.
+Ticker timer;
+#endif
+
+/*
+ * Arguments for running "blink" in it's own thread.
+ */
+class BlinkArgs {
+public:
+    BlinkArgs() {
+        clear();
+    }
+    void clear() {
+        position = 0;
+        blink_pattern.clear();
+    }
+    uint16_t position;
+    std::vector<uint32_t> blink_pattern;
+};
+
+/*
+ * The Led contains one property (pattern) and a function (blink).
+ * When the function blink is executed, the pattern is read, and the LED
+ * will blink based on the pattern.
+ */
+class LedResource {
+public:
+    LedResource() {
+        // create ObjectID with metadata tag of '3201', which is 'digital output'
+        led_object = M2MInterfaceFactory::create_object("3201");
+        M2MObjectInstance* led_inst = led_object->create_object_instance();
+
+        // 5853 = Multi-state output
+        M2MResource* pattern_res = led_inst->create_dynamic_resource("5853", "Pattern",
+            M2MResourceInstance::STRING, false);
+        // read and write
+        pattern_res->set_operation(M2MBase::GET_PUT_ALLOWED);
+        // set initial pattern (toggle every 200ms. 7 toggles in total)
+        pattern_res->set_value((const uint8_t*)"500:500:500:500:500:500:500", 27);
+
+        // there's not really an execute LWM2M ID that matches... hmm...
+        M2MResource* led_res = led_inst->create_dynamic_resource("5850", "Blink",
+            M2MResourceInstance::OPAQUE, false);
+        // we allow executing a function here...
+        led_res->set_operation(M2MBase::POST_ALLOWED);
+        // when a POST comes in, we want to execute the led_execute_callback
+        led_res->set_execute_function(execute_callback(this, &LedResource::blink));
+        // Completion of execute function can take a time, that's why delayed response is used
+        led_res->set_delayed_response(true);
+        blink_args = new BlinkArgs();
+    }
+
+    ~LedResource() {
+        delete blink_args;
+    }
+
+    M2MObject* get_object() {
+        return led_object;
+    }
+
+    void blink(void *argument) {
+        // read the value of 'Pattern'
+        status_ticker.detach();
+        green_led = 1;
+
+        M2MObjectInstance* inst = led_object->object_instance();
+        M2MResource* res = inst->resource("5853");
+        // Clear previous blink data
+        blink_args->clear();
+
+        // values in mbed Client are all buffers, and we need a vector of int's
+        uint8_t* buffIn = NULL;
+        uint32_t sizeIn;
+        res->get_value(buffIn, sizeIn);
+
+        // turn the buffer into a string, and initialize a vector<int> on the heap
+        std::string s((char*)buffIn, sizeIn);
+        free(buffIn);
+        output.printf("led_execute_callback pattern=%s\r\n", s.c_str());
+
+        // our pattern is something like 500:200:500, so parse that
+        std::size_t found = s.find_first_of(":");
+        while (found!=std::string::npos) {
+            blink_args->blink_pattern.push_back(atoi((const char*)s.substr(0,found).c_str()));
+            s = s.substr(found+1);
+            found=s.find_first_of(":");
+            if(found == std::string::npos) {
+                blink_args->blink_pattern.push_back(atoi((const char*)s.c_str()));
+            }
+        }
+        // check if POST contains payload
+        if (argument) {
+            M2MResource::M2MExecuteParameter* param = (M2MResource::M2MExecuteParameter*)argument;
+            String object_name = param->get_argument_object_name();
+            uint16_t object_instance_id = param->get_argument_object_instance_id();
+            String resource_name = param->get_argument_resource_name();
+            int payload_length = param->get_argument_value_length();
+            uint8_t* payload = param->get_argument_value();
+            output.printf("Resource: %s/%d/%s executed\r\n", object_name.c_str(), object_instance_id, resource_name.c_str());
+            output.printf("Payload: %.*s\r\n", payload_length, payload);
+        }
+        // do_blink is called with the vector, and starting at -1
+        blinky_thread.start(this, &LedResource::do_blink);
+    }
+
+private:
+    M2MObject* led_object;
+    Thread blinky_thread;
+    BlinkArgs *blink_args;
+    void do_blink() {
+        // blink the LED
+        red_led = !red_led;
+        // up the position, if we reached the end of the vector
+        if (blink_args->position >= blink_args->blink_pattern.size()) {
+            // send delayed response after blink is done
+            M2MObjectInstance* inst = led_object->object_instance();
+            M2MResource* led_res = inst->resource("5850");
+            led_res->send_delayed_post_response();
+            red_led = 1;
+            status_ticker.attach_us(blinky, 250000);
+            return;
+        }
+        // Invoke same function after `delay_ms` (upping position)
+        Thread::wait(blink_args->blink_pattern.at(blink_args->position));
+        blink_args->position++;
+        do_blink();
+    }
+};
+
+/*
+ * The button contains one property (click count).
+ * When `handle_button_click` is executed, the counter updates.
+ */
+class ButtonResource {
+public:
+    ButtonResource(): counter(0) {
+        // create ObjectID with metadata tag of '3200', which is 'digital input'
+        btn_object = M2MInterfaceFactory::create_object("3200");
+        M2MObjectInstance* btn_inst = btn_object->create_object_instance();
+        // create resource with ID '5501', which is digital input counter
+        M2MResource* btn_res = btn_inst->create_dynamic_resource("5501", "Button",
+            M2MResourceInstance::INTEGER, true /* observable */);
+        // we can read this value
+        btn_res->set_operation(M2MBase::GET_ALLOWED);
+        // set initial value (all values in mbed Client are buffers)
+        // to be able to read this data easily in the Connector console, we'll use a string
+        btn_res->set_value((uint8_t*)"0", 1);
+    }
+
+    ~ButtonResource() {
+    }
+
+    M2MObject* get_object() {
+        return btn_object;
+    }
+
+    /*
+     * When you press the button, we read the current value of the click counter
+     * from mbed Device Connector, then up the value with one.
+     */
+    void handle_button_click() {
+        M2MObjectInstance* inst = btn_object->object_instance();
+        M2MResource* res = inst->resource("5501");
+
+        // up counter
+        counter++;
+#ifdef TARGET_K64F
+        printf("handle_button_click, new value of counter is %d\r\n", counter);
+#else
+        printf("simulate button_click, new value of counter is %d\r\n", counter);
+#endif
+        // serialize the value of counter as a string, and tell connector
+        char buffer[20];
+        int size = sprintf(buffer,"%d",counter);
+        res->set_value((uint8_t*)buffer, size);
+    }
+
+private:
+    M2MObject* btn_object;
+    uint16_t counter;
+};
+
+class BigPayloadResource {
+public:
+    BigPayloadResource() {
+        big_payload = M2MInterfaceFactory::create_object("1000");
+        M2MObjectInstance* payload_inst = big_payload->create_object_instance();
+        M2MResource* payload_res = payload_inst->create_dynamic_resource("1", "BigData",
+            M2MResourceInstance::STRING, true /* observable */);
+        payload_res->set_operation(M2MBase::GET_PUT_ALLOWED);
+        payload_res->set_value((uint8_t*)"0", 1);
+        payload_res->set_incoming_block_message_callback(
+                    incoming_block_message_callback(this, &BigPayloadResource::block_message_received));
+        payload_res->set_outgoing_block_message_callback(
+                    outgoing_block_message_callback(this, &BigPayloadResource::block_message_requested));
+    }
+
+    M2MObject* get_object() {
+        return big_payload;
+    }
+
+    void block_message_received(M2MBlockMessage *argument) {
+        if (argument) {
+            if (M2MBlockMessage::ErrorNone == argument->error_code()) {
+                if (argument->is_last_block()) {
+                    output.printf("Last block received\r\n");
+                }
+                output.printf("Block number: %d\r\n", argument->block_number());
+                // First block received
+                if (argument->block_number() == 0) {
+                    // Store block
+                // More blocks coming
+                } else {
+                    // Store blocks
+                }
+            } else {
+                output.printf("Error when receiving block message!  - EntityTooLarge\r\n");
+            }
+            output.printf("Total message size: %d\r\n", argument->total_message_size());
+        }
+    }
+
+    void block_message_requested(const String& resource, uint8_t *&/*data*/, uint32_t &/*len*/) {
+        output.printf("GET request received for resource: %s\r\n", resource.c_str());
+        // Copy data and length to coap response
+    }
+
+private:
+    M2MObject*  big_payload;
+};
+
+// Network interaction must be performed outside of interrupt context
+Semaphore updates(0);
+volatile bool registered = false;
+volatile bool clicked = false;
+osThreadId mainThread;
+
+void unregister() {
+    registered = false;
+    updates.release();
+}
+
+void button_clicked() {
+    clicked = true;
+    updates.release();
+}
+
+// debug printf function
+void trace_printer(const char* str) {
+    printf("%s\r\n", str);
+}
+
+// Entry point to the program
+int main() {
+
+    unsigned int seed;
+    size_t len;
+
+#ifdef MBEDTLS_ENTROPY_HARDWARE_ALT
+    // Used to randomize source port
+    mbedtls_hardware_poll(NULL, (unsigned char *) &seed, sizeof seed, &len);
+
+#elif defined MBEDTLS_TEST_NULL_ENTROPY
+
+#warning "mbedTLS security feature is disabled. Connection will not be secure !! Implement proper hardware entropy for your selected hardware."
+    // Used to randomize source port
+    mbedtls_null_entropy_poll( NULL,(unsigned char *) &seed, sizeof seed, &len);
+
+#else
+
+#error "This hardware does not have entropy, endpoint will not register to Connector.\
+You need to enable NULL ENTROPY for your application, but if this configuration change is made then no security is offered by mbed TLS.\
+Add MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES and MBEDTLS_TEST_NULL_ENTROPY in mbed_app.json macros to register your endpoint."
+
+#endif
+
+    srand(seed);
+    red_led = 1;
+    blue_led = 1;
+    status_ticker.attach_us(blinky, 250000);
+    // Keep track of the main thread
+    mainThread = osThreadGetId();
+
+    // Sets the console baud-rate
+    output.baud(115200);
+
+    output.printf("Starting mbed Client example...\r\n");
+
+    mbed_trace_init();
+    mbed_trace_print_function_set(trace_printer);
+    NetworkInterface *network_interface = 0;
+    int connect_success = -1;
+#if MBED_CONF_APP_NETWORK_INTERFACE == WIFI
+    output.printf("\n\rUsing WiFi \r\n");
+    output.printf("\n\rConnecting to WiFi..\r\n");
+    connect_success = esp.connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD);
+    network_interface = &esp;
+#elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET
+    output.printf("Using Ethernet\r\n");
+    connect_success = eth.connect();
+    network_interface = &eth;
+#endif
+#ifdef MESH
+    output.printf("Using Mesh\r\n");
+    output.printf("\n\rConnecting to Mesh..\r\n");
+    mesh.initialize(&rf_phy);
+    connect_success = mesh.connect();
+    network_interface = &mesh;
+#endif
+    if(connect_success == 0) {
+    output.printf("\n\rConnected to Network successfully\r\n");
+    } else {
+        output.printf("\n\rConnection to Network Failed %d! Exiting application....\r\n", connect_success);
+        return 0;
+    }
+    const char *ip_addr = network_interface->get_ip_address();
+    if (ip_addr) {
+        output.printf("IP address %s\r\n", ip_addr);
+    } else {
+        output.printf("No IP address\r\n");
+    }
+
+    // we create our button and LED resources
+    ButtonResource button_resource;
+    LedResource led_resource;
+    BigPayloadResource big_payload_resource;
+
+#ifdef TARGET_K64F
+    // On press of SW3 button on K64F board, example application
+    // will call unregister API towards mbed Device Connector
+    //unreg_button.fall(&mbed_client,&MbedClient::test_unregister);
+    unreg_button.fall(&unregister);
+
+    // Observation Button (SW2) press will send update of endpoint resource values to connector
+    obs_button.fall(&button_clicked);
+#else
+    // Send update of endpoint resource values to connector every 15 seconds periodically
+    timer.attach(&button_clicked, 15.0);
+#endif
+
+    // Create endpoint interface to manage register and unregister
+    mbed_client.create_interface(MBED_SERVER_ADDRESS, network_interface);
+
+    // Create Objects of varying types, see simpleclient.h for more details on implementation.
+    M2MSecurity* register_object = mbed_client.create_register_object(); // server object specifying connector info
+    M2MDevice*   device_object   = mbed_client.create_device_object();   // device resources object
+
+    // Create list of Objects to register
+    M2MObjectList object_list;
+
+    // Add objects to list
+    object_list.push_back(device_object);
+    object_list.push_back(button_resource.get_object());
+    object_list.push_back(led_resource.get_object());
+    object_list.push_back(big_payload_resource.get_object());
+
+    // Set endpoint registration object
+    mbed_client.set_register_object(register_object);
+
+    // Register with mbed Device Connector
+    mbed_client.test_register(register_object, object_list);
+    registered = true;
+
+    while (true) {
+        updates.wait(25000);
+        if(registered) {
+            if(!clicked) {
+                mbed_client.test_update_register();
+            }
+        }else {
+            break;
+        }
+        if(clicked) {
+           clicked = false;
+            button_resource.handle_button_click();
+        }
+    }
+
+    mbed_client.test_unregister();
+    status_ticker.detach();
+}