Example program for simple-mbed-client, connecting a device to mbed Device Connector.
Dependencies: simple-mbed-client
Fork of simple-mbed-client-example by
This is an example on how to connect to mbed Device Connector using simple-mbed-client. It can connect over Ethernet, WiFi (using an ESP8266 module or an ODIN board), Thread and 6LoWPAN.
After cloning this repository update `mbed_app.json` to reflect your connectivity method. For docs on configuring connectivity, see easy-connect.
End to end example
For an end-to-end example of using Simple mbed Client to connect devices to mbed Device Connector see Building an internet connected lighting system.
Entropy (or lack thereof)
On all platforms except the K64F and K22F the library is compiled without TLS entropy sources. This means that your code is inherently unsafe and should not be deployed to any production systems. To enable entropy, remove the MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES and MBEDTLS_TEST_NULL_ENTROPY macros from mbed_app.json.
Revision 13:d4da5e6aa952, committed 2016-05-15
- Comitter:
- janjongboom
- Date:
- Sun May 15 20:28:52 2016 +0000
- Parent:
- 12:31e60c8bb7f6
- Child:
- 14:ddc258abaaac
- Commit message:
- Use simple-mbed-client to expose three resources to the cloud
Changed in this revision
--- a/main.cpp Mon Mar 07 22:11:37 2016 +0000
+++ b/main.cpp Sun May 15 20:28:52 2016 +0000
@@ -13,385 +13,85 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "EthernetInterface.h"
-#include "mbed-client/m2minterfacefactory.h"
-#include "mbed-client/m2mdevice.h"
-#include "mbed-client/m2minterfaceobserver.h"
-#include "mbed-client/m2minterface.h"
-#include "mbed-client/m2mobjectinstance.h"
-#include "mbed-client/m2mresource.h"
-#include "security.h"
-#include "ns_trace.h"
-
#include "mbed.h"
-#include "rtos.h"
-
-#include "LWIPInterface.h"
-#include "mbed-client-classic/m2mnetwork.h"
-
-
-Serial output(USBTX, USBRX);
-
-//Select binding mode: UDP or TCP
-M2MInterface::BindingMode SOCKET_MODE = M2MInterface::UDP;
-
-// This is address to mbed Device Connector
-const String &MBED_SERVER_ADDRESS = "coap://api.connector.mbed.com:5684";
-
-const String &MBED_USER_NAME_DOMAIN = MBED_DOMAIN;
-const String &ENDPOINT_NAME = MBED_ENDPOINT_NAME;
-
-const String &MANUFACTURER = "manufacturer";
-const String &TYPE = "type";
-const String &MODEL_NUMBER = "2015";
-const String &SERIAL_NUMBER = "12345";
-
-const uint8_t STATIC_VALUE[] = "Static value";
+#include "security.h" // security file from connector.mbed.com
+#include "LWIPInterface.h" // using Ethernet for connectivity
+#include "simple-mbed-client.h" // simple-mbed-client
-#if defined(TARGET_K64F)
-#define OBS_BUTTON SW2
-#define UNREG_BUTTON SW3
-#endif
-
-
-class MbedClient: public M2MInterfaceObserver {
-public:
- MbedClient(){
- _interface = NULL;
- _bootstrapped = false;
- _error = false;
- _registered = false;
- _unregistered = false;
- _register_security = NULL;
- _value = 0;
- _object = NULL;
- }
-
- ~MbedClient() {
- if(_interface) {
- delete _interface;
- }
- if(_register_security){
- delete _register_security;
- }
- }
-
- void trace_printer(const char* str) {
- output.printf("\r\n%s\r\n", str);
- }
-
- void create_interface() {
- // Creates M2MInterface using which endpoint can
- // setup its name, resource type, life time, connection mode,
- // Currently only LwIPv4 is supported.
+// So these lines are unique to connecting etc... but then it's just a normal program
- // Randomizing listening port for Certificate mode connectivity
- srand(time(NULL));
- uint16_t port = rand() % 65535 + 12345;
-
- _interface = M2MInterfaceFactory::create_interface(*this,
- ENDPOINT_NAME,
- "test",
- 3600,
- port,
- MBED_USER_NAME_DOMAIN,
- SOCKET_MODE,
- M2MInterface::LwIP_IPv4,
- "");
- }
-
- bool register_successful() {
- return _registered;
- }
-
- bool unregister_successful() {
- return _unregistered;
- }
-
- M2MSecurity* create_register_object() {
- // Creates register server object with mbed device server address and other parameters
- // required for client to connect to mbed device server.
- M2MSecurity *security = M2MInterfaceFactory::create_security(M2MSecurity::M2MServer);
- if(security) {
- security->set_resource_value(M2MSecurity::M2MServerUri, MBED_SERVER_ADDRESS);
- security->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::Certificate);
- security->set_resource_value(M2MSecurity::ServerPublicKey,SERVER_CERT,sizeof(SERVER_CERT));
- security->set_resource_value(M2MSecurity::PublicKey,CERT,sizeof(CERT));
- security->set_resource_value(M2MSecurity::Secretkey,KEY,sizeof(KEY));
- }
- return security;
- }
+Serial pc(USBTX, USBRX); // talk back to the computer
+LWIPInterface lwip; // define the Ethernet interface
+SimpleMbedClient client;
- M2MDevice* create_device_object() {
- // Creates device object which contains mandatory resources linked with
- // device endpoint.
- M2MDevice *device = M2MInterfaceFactory::create_device();
- if(device) {
- device->create_resource(M2MDevice::Manufacturer,MANUFACTURER);
- device->create_resource(M2MDevice::DeviceType,TYPE);
- device->create_resource(M2MDevice::ModelNumber,MODEL_NUMBER);
- device->create_resource(M2MDevice::SerialNumber,SERIAL_NUMBER);
- }
- 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",_value);
- res->set_operation(M2MBase::GET_PUT_ALLOWED);
- res->set_value((const uint8_t*)buffer,
- (const uint32_t)size);
- _value++;
-
- inst->create_static_resource("S",
- "ResourceTest",
- M2MResourceInstance::STRING,
- STATIC_VALUE,
- sizeof(STATIC_VALUE)-1);
- }
- }
- return _object;
- }
+// Declare some peripherals here
+DigitalOut led(LED_RED);
+DigitalOut registeredLed(LED_BLUE, 1);
+InterruptIn btn(SW3);
- void update_resource() {
- if(_object) {
- M2MObjectInstance* inst = _object->object_instance();
- if(inst) {
- M2MResource* res = inst->resource("D");
-
- char buffer[20];
- int size = sprintf(buffer,"%d",_value);
- res->set_value((const uint8_t*)buffer,
- (const uint32_t)size);
- _value++;
- }
- }
- }
-
- void test_register(M2MSecurity *register_object, M2MObjectList object_list){
- if(_interface) {
- // Register function
- _interface->register_object(register_object, object_list);
- }
- }
-
- void test_unregister() {
- if(_interface) {
- // Unregister function
- _interface->unregister_object(NULL);
- }
- }
+// play function, invoked thru mbed Client
+void play(void* args) {
+ pc.printf("I'm gonna play a song!\n");
+}
- //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;
- trace_printer("\nBootstrapped\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;
- trace_printer("\nRegistered\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*/){
- _unregistered = true;
- _registered = false;
- trace_printer("\nUnregistered\n");
- }
-
- void registration_updated(M2MSecurity */*security_object*/, const M2MServer & /*server_object*/){
- }
+// patternUpdated is called when the value of led/0/pattern changes
+void patternUpdated(string newPattern) {
+ pc.printf("Got a new pattern... %s\n", newPattern.c_str());
+}
- //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:
- trace_printer("[ERROR:] M2MInterface::AlreadyExists\n");
- break;
- case M2MInterface::BootstrapFailed:
- trace_printer("[ERROR:] M2MInterface::BootstrapFailed\n");
- break;
- case M2MInterface::InvalidParameters:
- trace_printer("[ERROR:] M2MInterface::InvalidParameters\n");
- break;
- case M2MInterface::NotRegistered:
- trace_printer("[ERROR:] M2MInterface::NotRegistered\n");
- break;
- case M2MInterface::Timeout:
- trace_printer("[ERROR:] M2MInterface::Timeout\n");
- break;
- case M2MInterface::NetworkError:
- trace_printer("[ERROR:] M2MInterface::NetworkError\n");
- break;
- case M2MInterface::ResponseParseFailed:
- trace_printer("[ERROR:] M2MInterface::ResponseParseFailed\n");
- break;
- case M2MInterface::UnknownError:
- trace_printer("[ERROR:] M2MInterface::UnknownError\n");
- break;
- case M2MInterface::MemoryFail:
- trace_printer("[ERROR:] M2MInterface::MemoryFail\n");
- break;
- case M2MInterface::NotAllowed:
- trace_printer("[ERROR:] M2MInterface::NotAllowed\n");
- break;
- default:
- break;
- }
- }
+// Here we define some mbed Client resources
+SimpleResourceInt btn_count = client.define_resource("button/0/clicks", 0, M2MBase::GET_ALLOWED, true);
+// need a callback when a PUT request comes in? Just pass in a callback
+SimpleResourceString pattern = client.define_resource("led/0/pattern", "500:500:500", &patternUpdated);
- //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) {
- output.printf("\nValue updated of Object name %s and Type %d\n",
- base->name().c_str(), type);
- }
-
- void test_update_register() {
- if (_registered) {
- _interface->update_registration(_register_security, 3600);
- }
- }
-
- void set_register_object(M2MSecurity *register_object) {
- if (_register_security == NULL) {
- _register_security = register_object;
- }
- }
-
-private:
-
- M2MInterface *_interface;
- M2MSecurity *_register_security;
- M2MObject *_object;
- volatile bool _bootstrapped;
- volatile bool _error;
- volatile bool _registered;
- volatile bool _unregistered;
- int _value;
-};
-
-// Instantiate the class which implements
-// LWM2M Client API
-MbedClient mbed_client;
-LWIPInterface lwip;
-M2MNetwork network(&lwip);
-
-// Set up Hardware interrupt button.
-InterruptIn obs_button(SW2);
-InterruptIn unreg_button(SW3);
-
-// Network interaction must be performed outside of interrupt context
-Semaphore updates(0);
-volatile bool registered = false;
-osThreadId mainThread;
-
-void unregister() {
- registered = false;
- updates.release();
+// Status callbacks if you're interested in that
+void registered() {
+ pc.printf("registered\n");
+ registeredLed = 0;
+}
+void unregistered() {
+ pc.printf("unregistered\n");
+ registeredLed = 1;
}
-void update() {
- updates.release();
+// btn_count now lives in the cloud, so just manipulate it...
+void fall() {
+ btn_count = btn_count + 1;
+}
+
+// normal function
+void toggleLed() {
+ led = !led;
}
-// Status indication
-Ticker status_ticker;
-DigitalOut status_led(LED1);
-void blinky() { status_led = !status_led; }
-
-
-// Entry point to the program
int main() {
- status_ticker.attach_us(blinky, 250000);
+ pc.baud(115200);
+
+ Ticker t;
+ t.attach(&toggleLed, 1.0f);
- // Keep track of the main thread
- mainThread = osThreadGetId();
-
- // Sets the console baud-rate
- output.baud(115200);
-
- // This sets up the network interface configuration which will be used
- // by LWM2M Client API to communicate with mbed Device server.
- lwip.connect();
-
- //lwipv4_socket_init();
- output.printf("IP address %s\r\n", lwip.getIPAddress());
-
- // On press of SW3 button on K64F board, example application
- // will call unregister API towards mbed Device Server
- //unreg_button.fall(&mbed_client,&MbedClient::test_unregister);
- unreg_button.fall(&unregister);
-
- // On press of SW2 button on K64F board, example application
- // will send observation towards mbed Device Server
- obs_button.fall(&update);
-
- // Create LWM2M Client API interface to manage register and unregister
- mbed_client.create_interface();
+ btn.fall(&fall);
+
+ // I want C++11 lambdas!
+ // here we define functions that should live in the cloud
+ client.define_function("music/0/play", &play);
- // Create LWM2M server object specifying mbed device server
- // information.
- M2MSecurity* register_object = mbed_client.create_register_object();
-
- // Create LWM2M device object specifying device resources
- // as per OMA LWM2M specification.
- M2MDevice* device_object = mbed_client.create_device_object();
-
- // Create Generic object specifying custom resources
- M2MObject* generic_object = mbed_client.create_generic_object();
-
- // Add all the objects that you would like 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(generic_object);
-
- mbed_client.set_register_object(register_object);
+ if (lwip.connect() != 0) { // connect to the internet
+ pc.printf("Connect to eth failed...\n");
+ return 1;
+ }
- // Register with mbed Device Connector
- mbed_client.test_register(register_object, object_list);
- registered = true;
-
- while (true) {
- int update = updates.wait(25000);
-
- if (!registered) {
- break;
- } else if (update) {
- mbed_client.update_resource();
- } else {
- mbed_client.test_update_register();
- }
+ //lwipv4_socket_init(); // do I need this?
+ pc.printf("IP address %s\r\n", lwip.getIPAddress());
+
+ bool setup = client.setup(&lwip); // start mbed client!
+ if (!setup) {
+ printf("Setting up mbed_client failed...\n");
+ return 1;
}
-
- mbed_client.test_unregister();
- status_ticker.detach();
+
+ client.on_registered(®istered);
+ client.on_unregistered(&unregistered);
+
+ while (1) {}
}
-
-
--- a/mbed-client-c.lib Mon Mar 07 22:11:37 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://developer.mbed.org/teams/sandbox/code/mbed-client-c/#a8b2ff761ade
--- a/mbed-client-classic.lib Mon Mar 07 22:11:37 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://developer.mbed.org/teams/sandbox/code/mbed-client-classic/#774e507fc261
--- a/mbed-client-mbedtls.lib Mon Mar 07 22:11:37 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://developer.mbed.org/teams/sandbox/code/mbed-client-mbedtls/#b2db21f25041
--- a/mbed-client.lib Mon Mar 07 22:11:37 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://developer.mbed.org/teams/sandbox/code/mbed-client/#d69b1929a3dc
--- a/mbedtls.lib Mon Mar 07 22:11:37 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://developer.mbed.org/teams/sandbox/code/mbedtls/#dee5972f341f
--- a/nanostack-libservice.lib Mon Mar 07 22:11:37 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://developer.mbed.org/teams/sandbox/code/nanostack-libservice/#a87c5afee2a6
--- a/security.h Mon Mar 07 22:11:37 2016 +0000 +++ b/security.h Sun May 15 20:28:52 2016 +0000 @@ -1,1 +1,1 @@ -#error "You need to get credentials from connector.mbed.com and paste them in this security.h file" \ No newline at end of file +#error "You need to get credentials from connector.mbed.com and paste them in this security.h file"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/simple-mbed-client.lib Sun May 15 20:28:52 2016 +0000 @@ -0,0 +1,1 @@ +https://developer.mbed.org/users/janjongboom/code/simple-mbed-client/#75015f627e89
