A simple interface to mbed Device Connector, where you just declare variables to push them to the cloud.

Dependents:   Wifi_Get_Test_V1 simple-mbed-client-example simple-client-app-shield simple-sensor-client

Fork of simple-mbed-client by Jan Jongboom

TL;DR? See simple-mbed-client-example to get started immediately.

This library is a simpler interface to mbed Client, making it trivial to expose sensors, actuators and other variables to the cloud. It does not require you to change how you write your code. You can take any local variable, swap it out for a call to Simple Mbed Client, and the variable will automatically be synchronised with mbed Cloud.

For example, here's how you expose the value of a light sensor to the cloud:

SimpleMbedClient client;

SimpleResourceInt light_value = client.define_resource("light/0/value", 0);     // create the var

AnalogIn light(A1);

void read_light_sensor() {
    // light_value behaves just like a normal variable that you can read and write to!
    light_value = light.read_u16();
}

// update every second
Ticker t;
t.attach(&read_light_sensor, 1.0f);

Setting up

First import this library to your project. As Simple Mbed Client also needs a way to talk to the outside world, you'll need a NetworkInterface-object. The easiest way is by using the easy-connect library, so add that to your project as well. See the easy-connect docs on how to specify the connectivity method.

We also need a way of authenticating with mbed Cloud. For this we need a security certificate. Go to mbed Cloud, and select 'GET MY DEVICE SECURITY CREDENTIALS'. Save the certificate as security.h in your project folder.

Now we can initiate Simple Mbed Client and connect it to the internet.

#include "mbed.h"
#include "security.h"
#include "easy-connect.h"
#include "simple-mbed-client.h"

SimpleMbedClient client;

DigitalOut led(LED1, 0);

void registered() {
    led = 1;
}

int main() {
    NetworkInterface* network = connect_to_network(); // if connection failed, network will be NULL
    client.setup(network); // returns a bool, check if it's true

    client.on_registered(&registered);

    while (1) {
        wait_ms(25000);
        client.keep_alive();
    }
}

Defining variables

You can define a new variable by a call to client.define_resource. This function takes five arguments:

  1. path - The URL on which your variable is exposed in mbed Cloud. Needs to be three (3) segments, split by a slash (/) in the form of 'sensor/0/value'. The second segment always needs to be numeric.
  2. defaultValue - The default value of the variable. Needs to be either a string or an integer. Depending on the type that you pass in here the type of the variable is defined.
  3. operation - Some variables might be read-only or write-only (seen from the cloud). Use the operation to define these constraints. It's of type M2MBase::Operation. Default is GET_PUT_ALLOWED.
  4. observable - If set to false, cloud applications cannot subscribe to updates on this variable. Default is true.
  5. callback - Function pointer which is called whenever the value of the variable is changed from the cloud.

The type returned by the function is either SimpleResourceInt or SimpleResourceString. You can assign and read from these variables like any normal local variable.

void name_updated(string new_value) {
    printf("Value is now %s\n", new_value.c_str());
}

SimpleResourceString name = client.define_resource("device/0/name", "jan", M2MBase::GET_PUT_ALLOWED, true, &name_updated);

// we can read and write to this variable, e.g.:
stringstream ss;
ss << name;

// or
name = "pietje";

// are all valid

Defining functions

You can define functions, which do not have a value, but can just be invoked from the cloud, by a call to client.define_function. This function takes two arguments:

  1. path - The URL on which your variable is exposed in mbed Cloud. Needs to be three (3) segments, split by a slash (/) in the form of 'sensor/0/value'. The second segment always needs to be numeric.
  2. callback - Function pointer which is invoked when the function is called. Takes in a pointer, which contains the data being passed in from the cloud.

void play(void* data) {
    if (data) { // data can be NULL!
        // cast it to something useful
    }
}

client.define_function("music/0/play", &play);

Accessing the underlying M2MResource

If you need access to the underlying M2MResource you can do so by calling get_resource on a variable, or by calling client.get_resource if it's a function.

SimpleResourceInt led = client.define_resource("led/0/value", true);

client.define_function("led/0/toggle", &toggleLed);

// now to get the resource
M2MResource* ledResource = led.get_resource();
M2MResource* toggleResource = client.get_resource("led/0/toggle");

Printing variables

Unfortunately printf is kind of dumb, and does not automatically cast the variables. If you want to print any of the Simple Mbed Client variables you'll need to cast yourself.

SimpleResourceInt led = client.define_resource("led/0/value", true);

printf("Value is currently %d\n", static_cast<int>(led));

Event Queue

Simple Mbed Client uses an mbed-events EventQueue - running on a separate RTOS thread - to handle incoming events without blocking the main loop. Both the thread and event queue are created when initializing the library. You can override this behavior by providing your own event queue. In this case no thread is created.

EventQueue myQueue;
SimpleMbedClient client(&myQueue);

You can also use the queue to process your own events, which is very useful when dealing with ISRs. The queue is accessible through the eventQueue() function on the client object and returns a pointer to the queue.

SimpleMbedClient client;

InterruptIn btn(D2);

int main() {
  btn.fall(client.eventQueue()->event(&fall));
}
Committer:
Jan Jongboom
Date:
Tue Feb 07 11:23:22 2017 +0100
Revision:
17:200624714d15
Parent:
16:cb980bd39e32
Child:
18:7b2882874f87
Move mbedtls_mbed_client_config.h into simple-mbed-client, allow overriding of constructor and add ServerAddress macro to simple-mbed-client

Who changed what in which revision?

UserRevisionLine numberNew contents of line
janjongboom 0:9fa3f3028773 1 /*
janjongboom 0:9fa3f3028773 2 * Copyright (c) 2015 ARM Limited. All rights reserved.
janjongboom 0:9fa3f3028773 3 * SPDX-License-Identifier: Apache-2.0
janjongboom 0:9fa3f3028773 4 * Licensed under the Apache License, Version 2.0 (the License); you may
janjongboom 0:9fa3f3028773 5 * not use this file except in compliance with the License.
janjongboom 0:9fa3f3028773 6 * You may obtain a copy of the License at
janjongboom 0:9fa3f3028773 7 *
janjongboom 0:9fa3f3028773 8 * http://www.apache.org/licenses/LICENSE-2.0
janjongboom 0:9fa3f3028773 9 *
janjongboom 0:9fa3f3028773 10 * Unless required by applicable law or agreed to in writing, software
janjongboom 0:9fa3f3028773 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
janjongboom 0:9fa3f3028773 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
janjongboom 0:9fa3f3028773 13 * See the License for the specific language governing permissions and
janjongboom 0:9fa3f3028773 14 * limitations under the License.
janjongboom 0:9fa3f3028773 15 */
janjongboom 0:9fa3f3028773 16
janjongboom 0:9fa3f3028773 17 #ifndef __SIMPLE_MBED_CLIENT_H__
janjongboom 0:9fa3f3028773 18 #define __SIMPLE_MBED_CLIENT_H__
janjongboom 0:9fa3f3028773 19
Jan Jongboom 3:ce2322965a27 20 #define debug_msg(...) if (debug) output.printf(__VA_ARGS__)
Jan Jongboom 3:ce2322965a27 21
janjongboom 0:9fa3f3028773 22 #include <map>
janjongboom 0:9fa3f3028773 23 #include <string>
janjongboom 0:9fa3f3028773 24 #include <vector>
janjongboom 0:9fa3f3028773 25 #include "mbed-client-wrapper.h"
janjongboom 0:9fa3f3028773 26
janjongboom 0:9fa3f3028773 27 using namespace std;
janjongboom 0:9fa3f3028773 28
Jan Jongboom 3:ce2322965a27 29 class SimpleResourceBase {
Jan Jongboom 3:ce2322965a27 30 public:
janjongboom 10:3fecd642d506 31 virtual void update(string v) {}
Jan Jongboom 3:ce2322965a27 32 };
Jan Jongboom 3:ce2322965a27 33
janjongboom 0:9fa3f3028773 34 class SimpleMbedClientBase {
janjongboom 0:9fa3f3028773 35 public:
Jan Jongboom 17:200624714d15 36
Jan Jongboom 3:ce2322965a27 37 SimpleMbedClientBase(bool aDebug = true)
Jan Jongboom 3:ce2322965a27 38 : output(USBTX, USBRX), debug(aDebug)
Jan Jongboom 3:ce2322965a27 39 {
Jan Jongboom 3:ce2322965a27 40
janjongboom 0:9fa3f3028773 41 }
Jan Jongboom 3:ce2322965a27 42
janjongboom 0:9fa3f3028773 43 ~SimpleMbedClientBase() {}
janjongboom 0:9fa3f3028773 44
janjongboom 0:9fa3f3028773 45 struct MbedClientOptions get_default_options() {
janjongboom 0:9fa3f3028773 46 struct MbedClientOptions options;
janjongboom 0:9fa3f3028773 47 options.Manufacturer = "Manufacturer_String";
janjongboom 0:9fa3f3028773 48 options.Type = "Type_String";
janjongboom 0:9fa3f3028773 49 options.ModelNumber = "ModelNumber_String";
janjongboom 0:9fa3f3028773 50 options.SerialNumber = "SerialNumber_String";
janjongboom 0:9fa3f3028773 51 options.DeviceType = "test";
Jan Jongboom 14:680c2a46cc8a 52 options.SocketMode = M2MInterface::TCP;
Jan Jongboom 17:200624714d15 53 #ifdef MBED_SERVER_ADDRESS
Jan Jongboom 17:200624714d15 54 options.ServerAddress = MBED_SERVER_ADDRESS;
Jan Jongboom 17:200624714d15 55 #else
janjongboom 0:9fa3f3028773 56 options.ServerAddress = "coap://api.connector.mbed.com:5684";
Jan Jongboom 17:200624714d15 57 #endif
Jan Jongboom 3:ce2322965a27 58
janjongboom 0:9fa3f3028773 59 return options;
janjongboom 0:9fa3f3028773 60 }
janjongboom 0:9fa3f3028773 61
Jan Jongboom 4:0f9eae5739dd 62 bool init(NetworkInterface* iface) {
Jan Jongboom 3:ce2322965a27 63 debug_msg("[SMC] Device name %s\r\n", MBED_ENDPOINT_NAME);
Jan Jongboom 3:ce2322965a27 64
janjongboom 0:9fa3f3028773 65 // Create endpoint interface to manage register and unregister
Jan Jongboom 3:ce2322965a27 66 client->create_interface(iface);
Jan Jongboom 3:ce2322965a27 67
janjongboom 0:9fa3f3028773 68 // Create Objects of varying types, see simpleclient.h for more details on implementation.
janjongboom 0:9fa3f3028773 69 M2MSecurity* register_object = client->create_register_object(); // server object specifying connector info
janjongboom 0:9fa3f3028773 70 M2MDevice* device_object = client->create_device_object(); // device resources object
Jan Jongboom 3:ce2322965a27 71
janjongboom 0:9fa3f3028773 72 // Create list of Objects to register
janjongboom 0:9fa3f3028773 73 M2MObjectList object_list;
Jan Jongboom 3:ce2322965a27 74
janjongboom 0:9fa3f3028773 75 // Add objects to list
janjongboom 0:9fa3f3028773 76 object_list.push_back(device_object);
Jan Jongboom 3:ce2322965a27 77
janjongboom 0:9fa3f3028773 78 map<string, M2MObject*>::iterator it;
janjongboom 0:9fa3f3028773 79 for (it = objects.begin(); it != objects.end(); it++)
janjongboom 0:9fa3f3028773 80 {
janjongboom 0:9fa3f3028773 81 object_list.push_back(it->second);
janjongboom 0:9fa3f3028773 82 }
Jan Jongboom 3:ce2322965a27 83
janjongboom 0:9fa3f3028773 84 // Set endpoint registration object
janjongboom 0:9fa3f3028773 85 client->set_register_object(register_object);
Jan Jongboom 3:ce2322965a27 86
janjongboom 0:9fa3f3028773 87 // Issue register command.
janjongboom 0:9fa3f3028773 88 client->test_register(register_object, object_list);
Jan Jongboom 3:ce2322965a27 89
janjongboom 0:9fa3f3028773 90 return true;
janjongboom 0:9fa3f3028773 91 }
janjongboom 0:9fa3f3028773 92
Jan Jongboom 4:0f9eae5739dd 93 bool setup(NetworkInterface* iface) {
Jan Jongboom 3:ce2322965a27 94 debug_msg("[SMC] In mbed_client_setup\r\n");
janjongboom 0:9fa3f3028773 95 if (client) {
Jan Jongboom 3:ce2322965a27 96 debug_msg("[SMC] [ERROR] mbed_client_setup called, but mbed_client is already instantiated\r\n");
janjongboom 0:9fa3f3028773 97 return false;
janjongboom 0:9fa3f3028773 98 }
Jan Jongboom 3:ce2322965a27 99
janjongboom 0:9fa3f3028773 100 struct MbedClientOptions options = get_default_options();
Jan Jongboom 3:ce2322965a27 101
Jan Jongboom 12:26810c6b58e1 102 Callback<void(string)> updateFp(this, &SimpleMbedClientBase::resource_updated);
Jan Jongboom 3:ce2322965a27 103 client = new MbedClient(options, updateFp, debug);
Jan Jongboom 3:ce2322965a27 104
janjongboom 0:9fa3f3028773 105 return init(iface);
janjongboom 0:9fa3f3028773 106 }
janjongboom 0:9fa3f3028773 107
Jan Jongboom 4:0f9eae5739dd 108 bool setup(MbedClientOptions options, NetworkInterface* iface) {
janjongboom 0:9fa3f3028773 109 if (client) {
Jan Jongboom 3:ce2322965a27 110 debug_msg("[SMC] [ERROR] mbed_client_setup called, but mbed_client is already instantiated\r\n");
janjongboom 0:9fa3f3028773 111 return false;
janjongboom 0:9fa3f3028773 112 }
Jan Jongboom 3:ce2322965a27 113
Jan Jongboom 12:26810c6b58e1 114 Callback<void(string)> updateFp(this, &SimpleMbedClientBase::resource_updated);
Jan Jongboom 3:ce2322965a27 115 client = new MbedClient(options, updateFp, debug);
Jan Jongboom 3:ce2322965a27 116
janjongboom 0:9fa3f3028773 117 return init(iface);
janjongboom 0:9fa3f3028773 118 }
janjongboom 0:9fa3f3028773 119
janjongboom 0:9fa3f3028773 120 void on_registered(void(*fn)(void)) {
Jan Jongboom 12:26810c6b58e1 121 Callback<void()> fp(fn);
janjongboom 0:9fa3f3028773 122 client->set_registered_function(fp);
janjongboom 0:9fa3f3028773 123 }
janjongboom 0:9fa3f3028773 124
Jan Jongboom 15:b7360c7e0f7f 125 void on_registered(Callback<void()> fp) {
Jan Jongboom 15:b7360c7e0f7f 126 client->set_registered_function(fp);
Jan Jongboom 15:b7360c7e0f7f 127 }
Jan Jongboom 15:b7360c7e0f7f 128
janjongboom 0:9fa3f3028773 129 template<typename T>
Jan Jongboom 3:ce2322965a27 130 void on_registered(T *object, void (T::*member)(void)) {
Jan Jongboom 12:26810c6b58e1 131 Callback<void()> fp(object, member);
janjongboom 0:9fa3f3028773 132 client->set_registered_function(fp);
janjongboom 0:9fa3f3028773 133 }
janjongboom 0:9fa3f3028773 134
janjongboom 0:9fa3f3028773 135 void on_unregistered(void(*fn)(void)) {
Jan Jongboom 12:26810c6b58e1 136 Callback<void()> fp(fn);
janjongboom 0:9fa3f3028773 137 client->set_unregistered_function(fp);
janjongboom 0:9fa3f3028773 138 }
janjongboom 0:9fa3f3028773 139
Jan Jongboom 15:b7360c7e0f7f 140 void on_unregistered(Callback<void()> fp) {
Jan Jongboom 15:b7360c7e0f7f 141 client->set_unregistered_function(fp);
Jan Jongboom 15:b7360c7e0f7f 142 }
Jan Jongboom 15:b7360c7e0f7f 143
janjongboom 0:9fa3f3028773 144 template<typename T>
Jan Jongboom 3:ce2322965a27 145 void on_unregistered(T *object, void (T::*member)(void)) {
Jan Jongboom 12:26810c6b58e1 146 Callback<void()> fp(object, member);
janjongboom 0:9fa3f3028773 147 client->set_unregistered_function(fp);
janjongboom 0:9fa3f3028773 148 }
janjongboom 0:9fa3f3028773 149
janjongboom 0:9fa3f3028773 150 bool define_function(const char* route, void(*fn)(void*)) {
janjongboom 0:9fa3f3028773 151 if (!define_resource_internal(route, string(), M2MBase::POST_ALLOWED, false)) {
janjongboom 0:9fa3f3028773 152 return false;
janjongboom 0:9fa3f3028773 153 }
Jan Jongboom 3:ce2322965a27 154
janjongboom 0:9fa3f3028773 155 string route_str(route);
janjongboom 0:9fa3f3028773 156 if (!resources.count(route_str)) {
Jan Jongboom 3:ce2322965a27 157 debug_msg("[SMC] [ERROR] Should be created, but no such route (%s)\r\n", route);
janjongboom 0:9fa3f3028773 158 return false;
janjongboom 0:9fa3f3028773 159 }
Jan Jongboom 3:ce2322965a27 160
Jan Jongboom 3:ce2322965a27 161 resources[route_str]->set_execute_function(execute_callback_2(fn));
janjongboom 0:9fa3f3028773 162 return true;
janjongboom 0:9fa3f3028773 163 }
janjongboom 0:9fa3f3028773 164
janjongboom 0:9fa3f3028773 165 bool define_function(const char* route, execute_callback fn) {
janjongboom 0:9fa3f3028773 166 if (!define_resource_internal(route, string(), M2MBase::POST_ALLOWED, false)) {
janjongboom 0:9fa3f3028773 167 return false;
janjongboom 0:9fa3f3028773 168 }
Jan Jongboom 3:ce2322965a27 169
janjongboom 0:9fa3f3028773 170 string route_str(route);
janjongboom 0:9fa3f3028773 171 if (!resources.count(route_str)) {
Jan Jongboom 3:ce2322965a27 172 debug_msg("[SMC] [ERROR] Should be created, but no such route (%s)\r\n", route);
janjongboom 0:9fa3f3028773 173 return false;
janjongboom 0:9fa3f3028773 174 }
janjongboom 0:9fa3f3028773 175 // No clue why this is not working?! It works with class member, but not with static function...
janjongboom 0:9fa3f3028773 176 resources[route_str]->set_execute_function(fn);
janjongboom 0:9fa3f3028773 177 return true;
janjongboom 0:9fa3f3028773 178 }
Jan Jongboom 3:ce2322965a27 179
janjongboom 0:9fa3f3028773 180 string get(string route_str) {
janjongboom 0:9fa3f3028773 181 if (!resources.count(route_str)) {
Jan Jongboom 3:ce2322965a27 182 debug_msg("[SMC] [ERROR] No such route (%s)\r\n", route_str.c_str());
janjongboom 0:9fa3f3028773 183 return string();
janjongboom 0:9fa3f3028773 184 }
Jan Jongboom 3:ce2322965a27 185
janjongboom 2:0a015df677a4 186 // otherwise ask mbed Client...
janjongboom 2:0a015df677a4 187 uint8_t* buffIn = NULL;
janjongboom 0:9fa3f3028773 188 uint32_t sizeIn;
janjongboom 0:9fa3f3028773 189 resources[route_str]->get_value(buffIn, sizeIn);
Jan Jongboom 3:ce2322965a27 190
janjongboom 2:0a015df677a4 191 string s((char*)buffIn, sizeIn);
janjongboom 0:9fa3f3028773 192 return s;
janjongboom 0:9fa3f3028773 193 }
janjongboom 0:9fa3f3028773 194
janjongboom 0:9fa3f3028773 195 bool set(string route_str, string v) {
janjongboom 2:0a015df677a4 196 // Potentially set() happens in InterruptContext. That's not good.
janjongboom 0:9fa3f3028773 197 if (!resources.count(route_str)) {
Jan Jongboom 3:ce2322965a27 198 debug_msg("[SMC] [ERROR] No such route (%s)\r\n", route_str.c_str());
janjongboom 0:9fa3f3028773 199 return false;
janjongboom 0:9fa3f3028773 200 }
Jan Jongboom 3:ce2322965a27 201
Jan Jongboom 4:0f9eae5739dd 202 if (v.length() == 0) {
Jan Jongboom 4:0f9eae5739dd 203 resources[route_str]->clear_value();
Jan Jongboom 4:0f9eae5739dd 204 }
Jan Jongboom 4:0f9eae5739dd 205 else {
Jan Jongboom 4:0f9eae5739dd 206 resources[route_str]->set_value((uint8_t*)v.c_str(), v.length());
Jan Jongboom 4:0f9eae5739dd 207 }
janjongboom 2:0a015df677a4 208
janjongboom 0:9fa3f3028773 209 return true;
janjongboom 0:9fa3f3028773 210 }
janjongboom 0:9fa3f3028773 211
janjongboom 0:9fa3f3028773 212 bool set(string route, const int& v) {
Jan Jongboom 16:cb980bd39e32 213 char str[13];
Jan Jongboom 16:cb980bd39e32 214 sprintf(str, "%d", v);
Jan Jongboom 3:ce2322965a27 215
Jan Jongboom 16:cb980bd39e32 216 return set(route, string(str));
janjongboom 0:9fa3f3028773 217 }
janjongboom 0:9fa3f3028773 218
Jan Jongboom 16:cb980bd39e32 219 bool define_resource_internal(const char* route, string v, M2MBase::Operation opr, bool observable) {
janjongboom 0:9fa3f3028773 220 if (client) {
Jan Jongboom 3:ce2322965a27 221 debug_msg("[SMC] [ERROR] mbed_client_define_resource, Can only define resources before mbed_client_setup is called!\r\n");
janjongboom 0:9fa3f3028773 222 return false;
janjongboom 0:9fa3f3028773 223 }
Jan Jongboom 3:ce2322965a27 224
janjongboom 0:9fa3f3028773 225 vector<string> segments = parse_route(route);
janjongboom 0:9fa3f3028773 226 if (segments.size() != 3) {
Jan Jongboom 3:ce2322965a27 227 debug_msg("[SMC] [ERROR] mbed_client_define_resource, Route needs to have three segments, split by '/' (%s)\r\n", route);
janjongboom 0:9fa3f3028773 228 return false;
janjongboom 0:9fa3f3028773 229 }
janjongboom 0:9fa3f3028773 230
Jan Jongboom 3:ce2322965a27 231 // segments[1] should be one digit and numeric
janjongboom 10:3fecd642d506 232 char n = segments.at(1).c_str()[0];
janjongboom 10:3fecd642d506 233 if (n < '0' || n > '9') {
Jan Jongboom 3:ce2322965a27 234 debug_msg("[SMC] [ERROR] mbed_client_define_resource, second route segment should be numeric, but was not (%s)\r\n", route);
Jan Jongboom 3:ce2322965a27 235 return false;
Jan Jongboom 3:ce2322965a27 236 }
Jan Jongboom 3:ce2322965a27 237
Jan Jongboom 3:ce2322965a27 238 int inst_id = atoi(segments.at(1).c_str());
Jan Jongboom 3:ce2322965a27 239
janjongboom 0:9fa3f3028773 240 M2MObjectInstance* inst;
janjongboom 0:9fa3f3028773 241 if (objectInstances.count(segments.at(0))) {
janjongboom 0:9fa3f3028773 242 inst = objectInstances[segments.at(0)];
janjongboom 0:9fa3f3028773 243 }
janjongboom 0:9fa3f3028773 244 else {
janjongboom 0:9fa3f3028773 245 M2MObject* obj = M2MInterfaceFactory::create_object(segments.at(0).c_str());
janjongboom 0:9fa3f3028773 246 inst = obj->create_object_instance(inst_id);
janjongboom 0:9fa3f3028773 247 objects.insert(std::pair<string, M2MObject*>(segments.at(0), obj));
janjongboom 0:9fa3f3028773 248 objectInstances.insert(std::pair<string, M2MObjectInstance*>(segments.at(0), inst));
janjongboom 0:9fa3f3028773 249 }
Jan Jongboom 3:ce2322965a27 250
janjongboom 0:9fa3f3028773 251 // @todo check if the resource exists yet
janjongboom 0:9fa3f3028773 252 M2MResource* res = inst->create_dynamic_resource(segments.at(2).c_str(), "",
janjongboom 0:9fa3f3028773 253 M2MResourceInstance::STRING, observable);
janjongboom 0:9fa3f3028773 254 res->set_operation(opr);
janjongboom 0:9fa3f3028773 255 res->set_value((uint8_t*)v.c_str(), v.length());
Jan Jongboom 3:ce2322965a27 256
janjongboom 0:9fa3f3028773 257 string route_str(route);
janjongboom 2:0a015df677a4 258 resources.insert(pair<string, M2MResource*>(route_str, res));
Jan Jongboom 3:ce2322965a27 259
janjongboom 0:9fa3f3028773 260 return true;
janjongboom 0:9fa3f3028773 261 }
Jan Jongboom 3:ce2322965a27 262
janjongboom 2:0a015df677a4 263 void keep_alive() {
janjongboom 2:0a015df677a4 264 client->test_update_register();
janjongboom 2:0a015df677a4 265 }
Jan Jongboom 3:ce2322965a27 266
Jan Jongboom 3:ce2322965a27 267 void register_update_callback(string route, SimpleResourceBase* simpleResource) {
Jan Jongboom 3:ce2322965a27 268 updateValues[route] = simpleResource;
Jan Jongboom 3:ce2322965a27 269 }
Jan Jongboom 3:ce2322965a27 270
Jan Jongboom 6:a1a766d45957 271 M2MResource* get_resource(string route) {
Jan Jongboom 6:a1a766d45957 272 if (!resources.count(route)) {
Jan Jongboom 6:a1a766d45957 273 debug_msg("[SMC] [ERROR] No such route (%s)\r\n", route.c_str());
Jan Jongboom 6:a1a766d45957 274 return NULL;
Jan Jongboom 6:a1a766d45957 275 }
Jan Jongboom 6:a1a766d45957 276
Jan Jongboom 6:a1a766d45957 277 return resources[route];
Jan Jongboom 6:a1a766d45957 278 }
Jan Jongboom 6:a1a766d45957 279
janjongboom 0:9fa3f3028773 280 private:
janjongboom 0:9fa3f3028773 281 vector<string> parse_route(const char* route) {
Jan Jongboom 16:cb980bd39e32 282 const string s(route);
janjongboom 0:9fa3f3028773 283 vector<string> v;
Jan Jongboom 16:cb980bd39e32 284
Jan Jongboom 16:cb980bd39e32 285 split(s, '/', v);
Jan Jongboom 16:cb980bd39e32 286
Jan Jongboom 16:cb980bd39e32 287 return v;
Jan Jongboom 16:cb980bd39e32 288 }
Jan Jongboom 16:cb980bd39e32 289
Jan Jongboom 16:cb980bd39e32 290 void split(const string& s, char delim, vector<string>& v) {
Jan Jongboom 16:cb980bd39e32 291 size_t i = 0;
Jan Jongboom 16:cb980bd39e32 292 size_t pos = s.find(delim);
Jan Jongboom 16:cb980bd39e32 293 while (pos != string::npos) {
Jan Jongboom 16:cb980bd39e32 294 v.push_back(s.substr(i, pos - i));
Jan Jongboom 16:cb980bd39e32 295 i = ++pos;
Jan Jongboom 16:cb980bd39e32 296 pos = s.find(delim, pos);
Jan Jongboom 16:cb980bd39e32 297
Jan Jongboom 16:cb980bd39e32 298 if (pos == string::npos) {
Jan Jongboom 16:cb980bd39e32 299 v.push_back(s.substr(i, s.length()));
Jan Jongboom 16:cb980bd39e32 300 }
janjongboom 0:9fa3f3028773 301 }
janjongboom 0:9fa3f3028773 302 }
janjongboom 0:9fa3f3028773 303
Jan Jongboom 3:ce2322965a27 304 void resource_updated(string uri) {
Jan Jongboom 3:ce2322965a27 305 if (updateValues.count(uri) == 0) return;
Jan Jongboom 3:ce2322965a27 306
Jan Jongboom 3:ce2322965a27 307 string v = get(uri);
Jan Jongboom 3:ce2322965a27 308 if (v.empty()) return;
Jan Jongboom 3:ce2322965a27 309
Jan Jongboom 3:ce2322965a27 310 updateValues[uri]->update(v);
Jan Jongboom 3:ce2322965a27 311 }
Jan Jongboom 3:ce2322965a27 312
janjongboom 0:9fa3f3028773 313 Serial output;
Jan Jongboom 3:ce2322965a27 314
janjongboom 0:9fa3f3028773 315 MbedClient* client;
janjongboom 0:9fa3f3028773 316 map<string, M2MObject*> objects;
janjongboom 0:9fa3f3028773 317 map<string, M2MObjectInstance*> objectInstances;
janjongboom 0:9fa3f3028773 318 map<string, M2MResource*> resources;
janjongboom 2:0a015df677a4 319
Jan Jongboom 3:ce2322965a27 320 bool debug;
Jan Jongboom 3:ce2322965a27 321
Jan Jongboom 3:ce2322965a27 322 map<string, SimpleResourceBase*> updateValues;
janjongboom 0:9fa3f3028773 323 };
janjongboom 0:9fa3f3028773 324
Jan Jongboom 3:ce2322965a27 325 class SimpleResourceString : public SimpleResourceBase {
janjongboom 0:9fa3f3028773 326 public:
Jan Jongboom 12:26810c6b58e1 327 SimpleResourceString(SimpleMbedClientBase* aSimpleClient, string aRoute, Callback<void(string)> aOnUpdate) :
Jan Jongboom 3:ce2322965a27 328 simpleClient(aSimpleClient), route(aRoute), onUpdate(aOnUpdate) {}
janjongboom 0:9fa3f3028773 329
janjongboom 0:9fa3f3028773 330 string operator=(const string& newValue) {
janjongboom 0:9fa3f3028773 331 simpleClient->set(route, newValue);
janjongboom 0:9fa3f3028773 332 return newValue;
janjongboom 0:9fa3f3028773 333 };
janjongboom 0:9fa3f3028773 334 operator string() const {
janjongboom 0:9fa3f3028773 335 return simpleClient->get(route);
janjongboom 0:9fa3f3028773 336 };
janjongboom 0:9fa3f3028773 337
Jan Jongboom 3:ce2322965a27 338 virtual void update(string v) {
Jan Jongboom 3:ce2322965a27 339 if (onUpdate) onUpdate(v);
Jan Jongboom 3:ce2322965a27 340 }
Jan Jongboom 3:ce2322965a27 341
Jan Jongboom 6:a1a766d45957 342 M2MResource* get_resource() {
Jan Jongboom 6:a1a766d45957 343 return simpleClient->get_resource(route);
Jan Jongboom 6:a1a766d45957 344 }
Jan Jongboom 6:a1a766d45957 345
janjongboom 0:9fa3f3028773 346 private:
janjongboom 0:9fa3f3028773 347 SimpleMbedClientBase* simpleClient;
janjongboom 0:9fa3f3028773 348 string route;
Jan Jongboom 12:26810c6b58e1 349 Callback<void(string)> onUpdate;
janjongboom 0:9fa3f3028773 350 };
janjongboom 0:9fa3f3028773 351
Jan Jongboom 3:ce2322965a27 352 class SimpleResourceInt : public SimpleResourceBase {
janjongboom 0:9fa3f3028773 353 public:
Jan Jongboom 12:26810c6b58e1 354 SimpleResourceInt(SimpleMbedClientBase* aSimpleClient, string aRoute, Callback<void(int)> aOnUpdate) :
Jan Jongboom 3:ce2322965a27 355 simpleClient(aSimpleClient), route(aRoute), onUpdate(aOnUpdate) {}
janjongboom 0:9fa3f3028773 356
janjongboom 0:9fa3f3028773 357 int operator=(int newValue) {
janjongboom 0:9fa3f3028773 358 simpleClient->set(route, newValue);
janjongboom 0:9fa3f3028773 359 return newValue;
janjongboom 0:9fa3f3028773 360 };
janjongboom 0:9fa3f3028773 361 operator int() const {
janjongboom 0:9fa3f3028773 362 string v = simpleClient->get(route);
janjongboom 0:9fa3f3028773 363 if (v.empty()) return 0;
Jan Jongboom 3:ce2322965a27 364
janjongboom 0:9fa3f3028773 365 return atoi((const char*)v.c_str());
janjongboom 0:9fa3f3028773 366 };
janjongboom 0:9fa3f3028773 367
Jan Jongboom 3:ce2322965a27 368 virtual void update(string v) {
Jan Jongboom 3:ce2322965a27 369 if (!onUpdate) return;
Jan Jongboom 3:ce2322965a27 370
Jan Jongboom 3:ce2322965a27 371 onUpdate(atoi((const char*)v.c_str()));
Jan Jongboom 3:ce2322965a27 372 }
Jan Jongboom 3:ce2322965a27 373
Jan Jongboom 6:a1a766d45957 374 M2MResource* get_resource() {
Jan Jongboom 6:a1a766d45957 375 return simpleClient->get_resource(route);
Jan Jongboom 6:a1a766d45957 376 }
Jan Jongboom 6:a1a766d45957 377
janjongboom 0:9fa3f3028773 378 private:
janjongboom 0:9fa3f3028773 379 SimpleMbedClientBase* simpleClient;
janjongboom 0:9fa3f3028773 380 string route;
Jan Jongboom 12:26810c6b58e1 381 Callback<void(int)> onUpdate;
janjongboom 0:9fa3f3028773 382 };
janjongboom 0:9fa3f3028773 383
janjongboom 0:9fa3f3028773 384 class SimpleMbedClient : public SimpleMbedClientBase {
janjongboom 0:9fa3f3028773 385 public:
janjongboom 1:75015f627e89 386
Jan Jongboom 17:200624714d15 387 SimpleMbedClient(bool aDebug = true)
Jan Jongboom 17:200624714d15 388 : SimpleMbedClientBase(aDebug)
Jan Jongboom 17:200624714d15 389 {
Jan Jongboom 17:200624714d15 390
Jan Jongboom 17:200624714d15 391 }
Jan Jongboom 17:200624714d15 392
janjongboom 1:75015f627e89 393 // @todo: macro this up
janjongboom 1:75015f627e89 394
janjongboom 1:75015f627e89 395 SimpleResourceString define_resource(
Jan Jongboom 3:ce2322965a27 396 const char* route,
Jan Jongboom 3:ce2322965a27 397 string v,
Jan Jongboom 3:ce2322965a27 398 M2MBase::Operation opr = M2MBase::GET_PUT_ALLOWED,
janjongboom 1:75015f627e89 399 bool observable = true,
Jan Jongboom 12:26810c6b58e1 400 Callback<void(string)> onUpdate = NULL)
janjongboom 1:75015f627e89 401 {
Jan Jongboom 3:ce2322965a27 402 SimpleResourceString* simpleResource = new SimpleResourceString(this, route, onUpdate);
janjongboom 0:9fa3f3028773 403 bool res = define_resource_internal(route, v, opr, observable);
Jan Jongboom 3:ce2322965a27 404 if (!res) {
Jan Jongboom 3:ce2322965a27 405 printf("Error while creating %s\n", route);
Jan Jongboom 3:ce2322965a27 406 }
Jan Jongboom 3:ce2322965a27 407 else {
Jan Jongboom 3:ce2322965a27 408 register_update_callback(route, simpleResource);
Jan Jongboom 3:ce2322965a27 409 }
Jan Jongboom 3:ce2322965a27 410 return *simpleResource;
janjongboom 0:9fa3f3028773 411 }
janjongboom 1:75015f627e89 412
janjongboom 1:75015f627e89 413 SimpleResourceString define_resource(
Jan Jongboom 3:ce2322965a27 414 const char* route,
Jan Jongboom 3:ce2322965a27 415 string v,
Jan Jongboom 3:ce2322965a27 416 M2MBase::Operation opr,
janjongboom 1:75015f627e89 417 bool observable,
Jan Jongboom 3:ce2322965a27 418 void(*onUpdate)(string))
janjongboom 1:75015f627e89 419 {
Jan Jongboom 12:26810c6b58e1 420 Callback<void(string)> fp;
janjongboom 1:75015f627e89 421 fp.attach(onUpdate);
janjongboom 1:75015f627e89 422 return define_resource(route, v, opr, observable, fp);
janjongboom 1:75015f627e89 423 }
Jan Jongboom 3:ce2322965a27 424
janjongboom 1:75015f627e89 425 SimpleResourceString define_resource(
Jan Jongboom 3:ce2322965a27 426 const char* route,
janjongboom 1:75015f627e89 427 string v,
Jan Jongboom 12:26810c6b58e1 428 Callback<void(string)> onUpdate)
janjongboom 1:75015f627e89 429 {
janjongboom 1:75015f627e89 430 return define_resource(route, v, M2MBase::GET_PUT_ALLOWED, true, onUpdate);
janjongboom 1:75015f627e89 431 }
janjongboom 1:75015f627e89 432
janjongboom 1:75015f627e89 433 SimpleResourceString define_resource(
Jan Jongboom 3:ce2322965a27 434 const char* route,
janjongboom 1:75015f627e89 435 string v,
Jan Jongboom 3:ce2322965a27 436 void(*onUpdate)(string))
janjongboom 1:75015f627e89 437 {
Jan Jongboom 12:26810c6b58e1 438 Callback<void(string)> fp;
janjongboom 1:75015f627e89 439 fp.attach(onUpdate);
janjongboom 1:75015f627e89 440 return define_resource(route, v, M2MBase::GET_PUT_ALLOWED, true, fp);
janjongboom 1:75015f627e89 441 }
Jan Jongboom 3:ce2322965a27 442
janjongboom 1:75015f627e89 443 SimpleResourceInt define_resource(
Jan Jongboom 3:ce2322965a27 444 const char* route,
Jan Jongboom 3:ce2322965a27 445 int v,
Jan Jongboom 3:ce2322965a27 446 M2MBase::Operation opr = M2MBase::GET_PUT_ALLOWED,
janjongboom 1:75015f627e89 447 bool observable = true,
Jan Jongboom 12:26810c6b58e1 448 Callback<void(int)> onUpdate = NULL)
janjongboom 1:75015f627e89 449 {
Jan Jongboom 3:ce2322965a27 450 SimpleResourceInt* simpleResource = new SimpleResourceInt(this, route, onUpdate);
Jan Jongboom 3:ce2322965a27 451
Jan Jongboom 16:cb980bd39e32 452 char str[13];
Jan Jongboom 16:cb980bd39e32 453 sprintf(str, "%d", v);
Jan Jongboom 16:cb980bd39e32 454
Jan Jongboom 16:cb980bd39e32 455 bool res = define_resource_internal(route, string(str), opr, observable);
Jan Jongboom 3:ce2322965a27 456 if (!res) {
Jan Jongboom 3:ce2322965a27 457 printf("Error while creating %s\n", route);
Jan Jongboom 3:ce2322965a27 458 }
Jan Jongboom 3:ce2322965a27 459 else {
Jan Jongboom 3:ce2322965a27 460 register_update_callback(route, simpleResource);
Jan Jongboom 3:ce2322965a27 461 }
Jan Jongboom 3:ce2322965a27 462 return *simpleResource;
janjongboom 0:9fa3f3028773 463 }
Jan Jongboom 3:ce2322965a27 464
janjongboom 1:75015f627e89 465 SimpleResourceInt define_resource(
Jan Jongboom 3:ce2322965a27 466 const char* route,
Jan Jongboom 3:ce2322965a27 467 int v,
Jan Jongboom 3:ce2322965a27 468 M2MBase::Operation opr,
janjongboom 1:75015f627e89 469 bool observable,
Jan Jongboom 3:ce2322965a27 470 void(*onUpdate)(int))
janjongboom 1:75015f627e89 471 {
Jan Jongboom 12:26810c6b58e1 472 Callback<void(int)> fp;
janjongboom 1:75015f627e89 473 fp.attach(onUpdate);
janjongboom 1:75015f627e89 474 return define_resource(route, v, opr, observable, fp);
janjongboom 1:75015f627e89 475 }
Jan Jongboom 3:ce2322965a27 476
janjongboom 1:75015f627e89 477 SimpleResourceInt define_resource(
Jan Jongboom 3:ce2322965a27 478 const char* route,
janjongboom 1:75015f627e89 479 int v,
Jan Jongboom 12:26810c6b58e1 480 Callback<void(int)> onUpdate)
janjongboom 1:75015f627e89 481 {
janjongboom 1:75015f627e89 482 return define_resource(route, v, M2MBase::GET_PUT_ALLOWED, true, onUpdate);
janjongboom 1:75015f627e89 483 }
janjongboom 1:75015f627e89 484
janjongboom 1:75015f627e89 485 SimpleResourceInt define_resource(
Jan Jongboom 3:ce2322965a27 486 const char* route,
janjongboom 1:75015f627e89 487 int v,
Jan Jongboom 3:ce2322965a27 488 void(*onUpdate)(int))
janjongboom 1:75015f627e89 489 {
Jan Jongboom 12:26810c6b58e1 490 Callback<void(int)> fp;
janjongboom 1:75015f627e89 491 fp.attach(onUpdate);
janjongboom 1:75015f627e89 492 return define_resource(route, v, M2MBase::GET_PUT_ALLOWED, true, fp);
janjongboom 1:75015f627e89 493 }
janjongboom 0:9fa3f3028773 494 };
janjongboom 0:9fa3f3028773 495
Jan Jongboom 3:ce2322965a27 496 #endif // __SIMPLE_MBED_CLIENT_H__