This is a simple mbed client example demonstrating, registration of a device with mbed Device Connector and reading and writing values as well as deregistering on different Network Interfaces including Ethernet, WiFi, 6LoWPAN ND and Thread respectively.
Fork of mbed-os-example-client by
Diff: main.cpp
- 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 = ð -#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 = ð +#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(); +}