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 Mar 21 13:03:49 2017 +0100
Revision:
23:c89df15e88d2
Parent:
22:17b4681e3353
Update mbed-client, works with mbed OS 5.4.1

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 18:7b2882874f87 20 #define smc_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 18:7b2882874f87 32 virtual void clear_pending_value() {}
Jan Jongboom 3:ce2322965a27 33 };
Jan Jongboom 3:ce2322965a27 34
janjongboom 0:9fa3f3028773 35 class SimpleMbedClientBase {
janjongboom 0:9fa3f3028773 36 public:
Jan Jongboom 17:200624714d15 37
Jan Jongboom 3:ce2322965a27 38 SimpleMbedClientBase(bool aDebug = true)
Jan Jongboom 18:7b2882874f87 39 : output(USBTX, USBRX), evQueue(new EventQueue()), evThread(new Thread()), debug(aDebug)
Jan Jongboom 18:7b2882874f87 40 {
Jan Jongboom 18:7b2882874f87 41 evThread->start(callback(evQueue, &EventQueue::dispatch_forever));
Jan Jongboom 18:7b2882874f87 42 }
Jan Jongboom 18:7b2882874f87 43
Jan Jongboom 18:7b2882874f87 44 SimpleMbedClientBase(EventQueue* aQueue, bool aDebug = true)
Jan Jongboom 18:7b2882874f87 45 : output(USBTX, USBRX), evQueue(aQueue), debug(aDebug)
Jan Jongboom 3:ce2322965a27 46 {
Jan Jongboom 3:ce2322965a27 47
janjongboom 0:9fa3f3028773 48 }
Jan Jongboom 3:ce2322965a27 49
Jan Jongboom 18:7b2882874f87 50 ~SimpleMbedClientBase() {
Jan Jongboom 18:7b2882874f87 51 if (evThread) {
Jan Jongboom 18:7b2882874f87 52 delete evQueue;
Jan Jongboom 18:7b2882874f87 53 delete evThread;
Jan Jongboom 18:7b2882874f87 54 }
Jan Jongboom 18:7b2882874f87 55 // if no evThread then evQueue is not owned by us
Jan Jongboom 18:7b2882874f87 56 }
janjongboom 0:9fa3f3028773 57
janjongboom 0:9fa3f3028773 58 struct MbedClientOptions get_default_options() {
janjongboom 0:9fa3f3028773 59 struct MbedClientOptions options;
janjongboom 0:9fa3f3028773 60 options.Manufacturer = "Manufacturer_String";
janjongboom 0:9fa3f3028773 61 options.Type = "Type_String";
janjongboom 0:9fa3f3028773 62 options.ModelNumber = "ModelNumber_String";
janjongboom 0:9fa3f3028773 63 options.SerialNumber = "SerialNumber_String";
janjongboom 0:9fa3f3028773 64 options.DeviceType = "test";
Jan Jongboom 14:680c2a46cc8a 65 options.SocketMode = M2MInterface::TCP;
Jan Jongboom 17:200624714d15 66 #ifdef MBED_SERVER_ADDRESS
Jan Jongboom 17:200624714d15 67 options.ServerAddress = MBED_SERVER_ADDRESS;
Jan Jongboom 17:200624714d15 68 #else
janjongboom 0:9fa3f3028773 69 options.ServerAddress = "coap://api.connector.mbed.com:5684";
Jan Jongboom 17:200624714d15 70 #endif
Jan Jongboom 3:ce2322965a27 71
janjongboom 0:9fa3f3028773 72 return options;
janjongboom 0:9fa3f3028773 73 }
janjongboom 0:9fa3f3028773 74
Jan Jongboom 4:0f9eae5739dd 75 bool init(NetworkInterface* iface) {
Jan Jongboom 18:7b2882874f87 76 smc_debug_msg("[SMC] Device name %s\r\n", MBED_ENDPOINT_NAME);
Jan Jongboom 3:ce2322965a27 77
janjongboom 0:9fa3f3028773 78 // Create endpoint interface to manage register and unregister
Jan Jongboom 3:ce2322965a27 79 client->create_interface(iface);
Jan Jongboom 3:ce2322965a27 80
janjongboom 0:9fa3f3028773 81 // Create Objects of varying types, see simpleclient.h for more details on implementation.
janjongboom 0:9fa3f3028773 82 M2MSecurity* register_object = client->create_register_object(); // server object specifying connector info
janjongboom 0:9fa3f3028773 83 M2MDevice* device_object = client->create_device_object(); // device resources object
Jan Jongboom 3:ce2322965a27 84
janjongboom 0:9fa3f3028773 85 // Create list of Objects to register
janjongboom 0:9fa3f3028773 86 M2MObjectList object_list;
Jan Jongboom 3:ce2322965a27 87
janjongboom 0:9fa3f3028773 88 // Add objects to list
janjongboom 0:9fa3f3028773 89 object_list.push_back(device_object);
Jan Jongboom 3:ce2322965a27 90
janjongboom 0:9fa3f3028773 91 map<string, M2MObject*>::iterator it;
janjongboom 0:9fa3f3028773 92 for (it = objects.begin(); it != objects.end(); it++)
janjongboom 0:9fa3f3028773 93 {
janjongboom 0:9fa3f3028773 94 object_list.push_back(it->second);
janjongboom 0:9fa3f3028773 95 }
Jan Jongboom 3:ce2322965a27 96
janjongboom 0:9fa3f3028773 97 // Set endpoint registration object
janjongboom 0:9fa3f3028773 98 client->set_register_object(register_object);
Jan Jongboom 3:ce2322965a27 99
janjongboom 0:9fa3f3028773 100 // Issue register command.
janjongboom 0:9fa3f3028773 101 client->test_register(register_object, object_list);
Jan Jongboom 3:ce2322965a27 102
Jan Jongboom 18:7b2882874f87 103 // Keep alive ticker (every 25 seconds)
Jan Jongboom 18:7b2882874f87 104 evQueue->call_every(MBED_CONF_SIMPLE_MBED_CLIENT_UPDATE_INTERVAL,
Jan Jongboom 18:7b2882874f87 105 callback(this, &SimpleMbedClientBase::keep_alive));
Jan Jongboom 18:7b2882874f87 106
janjongboom 0:9fa3f3028773 107 return true;
janjongboom 0:9fa3f3028773 108 }
janjongboom 0:9fa3f3028773 109
Jan Jongboom 4:0f9eae5739dd 110 bool setup(NetworkInterface* iface) {
Jan Jongboom 18:7b2882874f87 111 smc_debug_msg("[SMC] In mbed_client_setup\r\n");
janjongboom 0:9fa3f3028773 112 if (client) {
Jan Jongboom 18:7b2882874f87 113 smc_debug_msg("[SMC] [ERROR] mbed_client_setup called, but mbed_client is already instantiated\r\n");
janjongboom 0:9fa3f3028773 114 return false;
janjongboom 0:9fa3f3028773 115 }
Jan Jongboom 3:ce2322965a27 116
janjongboom 0:9fa3f3028773 117 struct MbedClientOptions options = get_default_options();
Jan Jongboom 3:ce2322965a27 118
Jan Jongboom 12:26810c6b58e1 119 Callback<void(string)> updateFp(this, &SimpleMbedClientBase::resource_updated);
Jan Jongboom 3:ce2322965a27 120 client = new MbedClient(options, updateFp, debug);
Jan Jongboom 3:ce2322965a27 121
janjongboom 0:9fa3f3028773 122 return init(iface);
janjongboom 0:9fa3f3028773 123 }
janjongboom 0:9fa3f3028773 124
Jan Jongboom 4:0f9eae5739dd 125 bool setup(MbedClientOptions options, NetworkInterface* iface) {
janjongboom 0:9fa3f3028773 126 if (client) {
Jan Jongboom 18:7b2882874f87 127 smc_debug_msg("[SMC] [ERROR] mbed_client_setup called, but mbed_client is already instantiated\r\n");
janjongboom 0:9fa3f3028773 128 return false;
janjongboom 0:9fa3f3028773 129 }
Jan Jongboom 3:ce2322965a27 130
Jan Jongboom 12:26810c6b58e1 131 Callback<void(string)> updateFp(this, &SimpleMbedClientBase::resource_updated);
Jan Jongboom 3:ce2322965a27 132 client = new MbedClient(options, updateFp, debug);
Jan Jongboom 3:ce2322965a27 133
janjongboom 0:9fa3f3028773 134 return init(iface);
janjongboom 0:9fa3f3028773 135 }
janjongboom 0:9fa3f3028773 136
janjongboom 0:9fa3f3028773 137 void on_registered(void(*fn)(void)) {
Jan Jongboom 12:26810c6b58e1 138 Callback<void()> fp(fn);
janjongboom 0:9fa3f3028773 139 client->set_registered_function(fp);
janjongboom 0:9fa3f3028773 140 }
janjongboom 0:9fa3f3028773 141
Jan Jongboom 15:b7360c7e0f7f 142 void on_registered(Callback<void()> fp) {
Jan Jongboom 15:b7360c7e0f7f 143 client->set_registered_function(fp);
Jan Jongboom 15:b7360c7e0f7f 144 }
Jan Jongboom 15:b7360c7e0f7f 145
janjongboom 0:9fa3f3028773 146 template<typename T>
Jan Jongboom 3:ce2322965a27 147 void on_registered(T *object, void (T::*member)(void)) {
Jan Jongboom 12:26810c6b58e1 148 Callback<void()> fp(object, member);
janjongboom 0:9fa3f3028773 149 client->set_registered_function(fp);
janjongboom 0:9fa3f3028773 150 }
janjongboom 0:9fa3f3028773 151
janjongboom 0:9fa3f3028773 152 void on_unregistered(void(*fn)(void)) {
Jan Jongboom 12:26810c6b58e1 153 Callback<void()> fp(fn);
janjongboom 0:9fa3f3028773 154 client->set_unregistered_function(fp);
janjongboom 0:9fa3f3028773 155 }
janjongboom 0:9fa3f3028773 156
Jan Jongboom 15:b7360c7e0f7f 157 void on_unregistered(Callback<void()> fp) {
Jan Jongboom 15:b7360c7e0f7f 158 client->set_unregistered_function(fp);
Jan Jongboom 15:b7360c7e0f7f 159 }
Jan Jongboom 15:b7360c7e0f7f 160
janjongboom 0:9fa3f3028773 161 template<typename T>
Jan Jongboom 3:ce2322965a27 162 void on_unregistered(T *object, void (T::*member)(void)) {
Jan Jongboom 12:26810c6b58e1 163 Callback<void()> fp(object, member);
janjongboom 0:9fa3f3028773 164 client->set_unregistered_function(fp);
janjongboom 0:9fa3f3028773 165 }
janjongboom 0:9fa3f3028773 166
Jan Jongboom 19:cf570422d4dd 167 bool define_function(const char* route, Event<void(void*)> ev) {
Jan Jongboom 19:cf570422d4dd 168 if (!define_resource_internal(route, string(), M2MBase::POST_ALLOWED, false)) {
Jan Jongboom 19:cf570422d4dd 169 return false;
Jan Jongboom 19:cf570422d4dd 170 }
Jan Jongboom 19:cf570422d4dd 171
Jan Jongboom 19:cf570422d4dd 172 string route_str(route);
Jan Jongboom 19:cf570422d4dd 173 if (!resources.count(route_str)) {
Jan Jongboom 19:cf570422d4dd 174 smc_debug_msg("[SMC] [ERROR] Should be created, but no such route (%s)\r\n", route);
Jan Jongboom 19:cf570422d4dd 175 return false;
Jan Jongboom 19:cf570422d4dd 176 }
Jan Jongboom 19:cf570422d4dd 177
Jan Jongboom 19:cf570422d4dd 178 // We need a copy of the event. The original event might go out of scope.
Jan Jongboom 19:cf570422d4dd 179 // @todo, do we need to clear this? It's actually meant to live until the end of the program... But it's not nice to alloc and never free.
Jan Jongboom 19:cf570422d4dd 180 Event<void(void*)>* copy = new Event<void(void*)>(ev);
Jan Jongboom 19:cf570422d4dd 181
Jan Jongboom 19:cf570422d4dd 182 // Event::call is const, which FP1 does not like. Cast it to non-const.
Jan Jongboom 19:cf570422d4dd 183 FP1<void, void*> fp(copy, (void (events::Event<void(void*)>::*)(void*))&Event<void(void*)>::call);
Jan Jongboom 19:cf570422d4dd 184
Jan Jongboom 19:cf570422d4dd 185 resources[route_str]->set_execute_function(fp);
Jan Jongboom 19:cf570422d4dd 186 return true;
Jan Jongboom 19:cf570422d4dd 187 }
Jan Jongboom 19:cf570422d4dd 188
janjongboom 0:9fa3f3028773 189 bool define_function(const char* route, void(*fn)(void*)) {
janjongboom 0:9fa3f3028773 190 if (!define_resource_internal(route, string(), M2MBase::POST_ALLOWED, false)) {
janjongboom 0:9fa3f3028773 191 return false;
janjongboom 0:9fa3f3028773 192 }
Jan Jongboom 3:ce2322965a27 193
janjongboom 0:9fa3f3028773 194 string route_str(route);
janjongboom 0:9fa3f3028773 195 if (!resources.count(route_str)) {
Jan Jongboom 18:7b2882874f87 196 smc_debug_msg("[SMC] [ERROR] Should be created, but no such route (%s)\r\n", route);
janjongboom 0:9fa3f3028773 197 return false;
janjongboom 0:9fa3f3028773 198 }
Jan Jongboom 3:ce2322965a27 199
Jan Jongboom 3:ce2322965a27 200 resources[route_str]->set_execute_function(execute_callback_2(fn));
janjongboom 0:9fa3f3028773 201 return true;
janjongboom 0:9fa3f3028773 202 }
janjongboom 0:9fa3f3028773 203
janjongboom 0:9fa3f3028773 204 bool define_function(const char* route, execute_callback fn) {
janjongboom 0:9fa3f3028773 205 if (!define_resource_internal(route, string(), M2MBase::POST_ALLOWED, false)) {
janjongboom 0:9fa3f3028773 206 return false;
janjongboom 0:9fa3f3028773 207 }
Jan Jongboom 3:ce2322965a27 208
janjongboom 0:9fa3f3028773 209 string route_str(route);
janjongboom 0:9fa3f3028773 210 if (!resources.count(route_str)) {
Jan Jongboom 18:7b2882874f87 211 smc_debug_msg("[SMC] [ERROR] Should be created, but no such route (%s)\r\n", route);
janjongboom 0:9fa3f3028773 212 return false;
janjongboom 0:9fa3f3028773 213 }
janjongboom 0:9fa3f3028773 214 // No clue why this is not working?! It works with class member, but not with static function...
janjongboom 0:9fa3f3028773 215 resources[route_str]->set_execute_function(fn);
janjongboom 0:9fa3f3028773 216 return true;
janjongboom 0:9fa3f3028773 217 }
Jan Jongboom 3:ce2322965a27 218
janjongboom 0:9fa3f3028773 219 string get(string route_str) {
janjongboom 0:9fa3f3028773 220 if (!resources.count(route_str)) {
Jan Jongboom 18:7b2882874f87 221 smc_debug_msg("[SMC] [ERROR] No such route (%s)\r\n", route_str.c_str());
janjongboom 0:9fa3f3028773 222 return string();
janjongboom 0:9fa3f3028773 223 }
Jan Jongboom 3:ce2322965a27 224
janjongboom 2:0a015df677a4 225 // otherwise ask mbed Client...
janjongboom 2:0a015df677a4 226 uint8_t* buffIn = NULL;
janjongboom 0:9fa3f3028773 227 uint32_t sizeIn;
janjongboom 0:9fa3f3028773 228 resources[route_str]->get_value(buffIn, sizeIn);
Jan Jongboom 3:ce2322965a27 229
janjongboom 2:0a015df677a4 230 string s((char*)buffIn, sizeIn);
janjongboom 0:9fa3f3028773 231 return s;
janjongboom 0:9fa3f3028773 232 }
janjongboom 0:9fa3f3028773 233
Jan Jongboom 22:17b4681e3353 234 // Note: these `set` calls are async.
Jan Jongboom 22:17b4681e3353 235 // SimpleResource* buffers the value, so when using it through operators you'll get the right value back.
Jan Jongboom 18:7b2882874f87 236 void set(string route_str, string v) {
Jan Jongboom 18:7b2882874f87 237 evQueue->call(callback(this, &SimpleMbedClientBase::internal_set_str), route_str, v);
janjongboom 0:9fa3f3028773 238 }
janjongboom 0:9fa3f3028773 239
Jan Jongboom 18:7b2882874f87 240 void set(string route_str, const int& v) {
Jan Jongboom 18:7b2882874f87 241 evQueue->call(callback(this, &SimpleMbedClientBase::internal_set_int), route_str, v);
janjongboom 0:9fa3f3028773 242 }
janjongboom 0:9fa3f3028773 243
Jan Jongboom 22:17b4681e3353 244 void set(string route_str, const float& v) {
Jan Jongboom 22:17b4681e3353 245 evQueue->call(callback(this, &SimpleMbedClientBase::internal_set_float), route_str, v);
Jan Jongboom 22:17b4681e3353 246 }
Jan Jongboom 22:17b4681e3353 247
Jan Jongboom 16:cb980bd39e32 248 bool define_resource_internal(const char* route, string v, M2MBase::Operation opr, bool observable) {
janjongboom 0:9fa3f3028773 249 if (client) {
Jan Jongboom 18:7b2882874f87 250 smc_debug_msg("[SMC] [ERROR] mbed_client_define_resource, Can only define resources before mbed_client_setup is called!\r\n");
janjongboom 0:9fa3f3028773 251 return false;
janjongboom 0:9fa3f3028773 252 }
Jan Jongboom 3:ce2322965a27 253
janjongboom 0:9fa3f3028773 254 vector<string> segments = parse_route(route);
janjongboom 0:9fa3f3028773 255 if (segments.size() != 3) {
Jan Jongboom 18:7b2882874f87 256 smc_debug_msg("[SMC] [ERROR] mbed_client_define_resource, Route needs to have three segments, split by '/' (%s)\r\n", route);
janjongboom 0:9fa3f3028773 257 return false;
janjongboom 0:9fa3f3028773 258 }
janjongboom 0:9fa3f3028773 259
Jan Jongboom 3:ce2322965a27 260 // segments[1] should be one digit and numeric
janjongboom 10:3fecd642d506 261 char n = segments.at(1).c_str()[0];
janjongboom 10:3fecd642d506 262 if (n < '0' || n > '9') {
Jan Jongboom 18:7b2882874f87 263 smc_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 264 return false;
Jan Jongboom 3:ce2322965a27 265 }
Jan Jongboom 3:ce2322965a27 266
Jan Jongboom 3:ce2322965a27 267 int inst_id = atoi(segments.at(1).c_str());
Jan Jongboom 3:ce2322965a27 268
janjongboom 0:9fa3f3028773 269 M2MObjectInstance* inst;
janjongboom 0:9fa3f3028773 270 if (objectInstances.count(segments.at(0))) {
janjongboom 0:9fa3f3028773 271 inst = objectInstances[segments.at(0)];
janjongboom 0:9fa3f3028773 272 }
janjongboom 0:9fa3f3028773 273 else {
janjongboom 0:9fa3f3028773 274 M2MObject* obj = M2MInterfaceFactory::create_object(segments.at(0).c_str());
janjongboom 0:9fa3f3028773 275 inst = obj->create_object_instance(inst_id);
janjongboom 0:9fa3f3028773 276 objects.insert(std::pair<string, M2MObject*>(segments.at(0), obj));
janjongboom 0:9fa3f3028773 277 objectInstances.insert(std::pair<string, M2MObjectInstance*>(segments.at(0), inst));
janjongboom 0:9fa3f3028773 278 }
Jan Jongboom 3:ce2322965a27 279
janjongboom 0:9fa3f3028773 280 // @todo check if the resource exists yet
janjongboom 0:9fa3f3028773 281 M2MResource* res = inst->create_dynamic_resource(segments.at(2).c_str(), "",
janjongboom 0:9fa3f3028773 282 M2MResourceInstance::STRING, observable);
janjongboom 0:9fa3f3028773 283 res->set_operation(opr);
janjongboom 0:9fa3f3028773 284 res->set_value((uint8_t*)v.c_str(), v.length());
Jan Jongboom 3:ce2322965a27 285
janjongboom 0:9fa3f3028773 286 string route_str(route);
janjongboom 2:0a015df677a4 287 resources.insert(pair<string, M2MResource*>(route_str, res));
Jan Jongboom 3:ce2322965a27 288
janjongboom 0:9fa3f3028773 289 return true;
janjongboom 0:9fa3f3028773 290 }
Jan Jongboom 3:ce2322965a27 291
Jan Jongboom 3:ce2322965a27 292 void register_update_callback(string route, SimpleResourceBase* simpleResource) {
Jan Jongboom 3:ce2322965a27 293 updateValues[route] = simpleResource;
Jan Jongboom 3:ce2322965a27 294 }
Jan Jongboom 3:ce2322965a27 295
Jan Jongboom 6:a1a766d45957 296 M2MResource* get_resource(string route) {
Jan Jongboom 6:a1a766d45957 297 if (!resources.count(route)) {
Jan Jongboom 18:7b2882874f87 298 smc_debug_msg("[SMC] [ERROR] No such route (%s)\r\n", route.c_str());
Jan Jongboom 6:a1a766d45957 299 return NULL;
Jan Jongboom 6:a1a766d45957 300 }
Jan Jongboom 6:a1a766d45957 301
Jan Jongboom 6:a1a766d45957 302 return resources[route];
Jan Jongboom 6:a1a766d45957 303 }
Jan Jongboom 6:a1a766d45957 304
Jan Jongboom 18:7b2882874f87 305 EventQueue* eventQueue() const {
Jan Jongboom 18:7b2882874f87 306 return evQueue;
Jan Jongboom 18:7b2882874f87 307 }
Jan Jongboom 18:7b2882874f87 308
janjongboom 0:9fa3f3028773 309 private:
janjongboom 0:9fa3f3028773 310 vector<string> parse_route(const char* route) {
Jan Jongboom 16:cb980bd39e32 311 const string s(route);
janjongboom 0:9fa3f3028773 312 vector<string> v;
Jan Jongboom 16:cb980bd39e32 313
Jan Jongboom 16:cb980bd39e32 314 split(s, '/', v);
Jan Jongboom 16:cb980bd39e32 315
Jan Jongboom 16:cb980bd39e32 316 return v;
Jan Jongboom 16:cb980bd39e32 317 }
Jan Jongboom 16:cb980bd39e32 318
Jan Jongboom 16:cb980bd39e32 319 void split(const string& s, char delim, vector<string>& v) {
Jan Jongboom 16:cb980bd39e32 320 size_t i = 0;
Jan Jongboom 16:cb980bd39e32 321 size_t pos = s.find(delim);
Jan Jongboom 16:cb980bd39e32 322 while (pos != string::npos) {
Jan Jongboom 16:cb980bd39e32 323 v.push_back(s.substr(i, pos - i));
Jan Jongboom 16:cb980bd39e32 324 i = ++pos;
Jan Jongboom 16:cb980bd39e32 325 pos = s.find(delim, pos);
Jan Jongboom 16:cb980bd39e32 326
Jan Jongboom 16:cb980bd39e32 327 if (pos == string::npos) {
Jan Jongboom 16:cb980bd39e32 328 v.push_back(s.substr(i, s.length()));
Jan Jongboom 16:cb980bd39e32 329 }
janjongboom 0:9fa3f3028773 330 }
janjongboom 0:9fa3f3028773 331 }
janjongboom 0:9fa3f3028773 332
Jan Jongboom 3:ce2322965a27 333 void resource_updated(string uri) {
Jan Jongboom 3:ce2322965a27 334 if (updateValues.count(uri) == 0) return;
Jan Jongboom 3:ce2322965a27 335
Jan Jongboom 3:ce2322965a27 336 string v = get(uri);
Jan Jongboom 3:ce2322965a27 337 if (v.empty()) return;
Jan Jongboom 3:ce2322965a27 338
Jan Jongboom 18:7b2882874f87 339 // Schedule this on the other thread, to avoid blocking this thread
Jan Jongboom 18:7b2882874f87 340 evQueue->call(callback(updateValues[uri], &SimpleResourceBase::update), v);
Jan Jongboom 18:7b2882874f87 341 }
Jan Jongboom 18:7b2882874f87 342
Jan Jongboom 18:7b2882874f87 343 // These operations have side effects, they should not be called immediately,
Jan Jongboom 18:7b2882874f87 344 // but always through the eventqueue
Jan Jongboom 18:7b2882874f87 345 void internal_set_str(string route_str, string v) {
Jan Jongboom 18:7b2882874f87 346 if (!resources.count(route_str)) {
Jan Jongboom 18:7b2882874f87 347 smc_debug_msg("[SMC] [ERROR] No such route (%s)\r\n", route_str.c_str());
Jan Jongboom 18:7b2882874f87 348 return;
Jan Jongboom 18:7b2882874f87 349 }
Jan Jongboom 18:7b2882874f87 350
Jan Jongboom 18:7b2882874f87 351 if (v.length() == 0) {
Jan Jongboom 18:7b2882874f87 352 resources[route_str]->clear_value();
Jan Jongboom 18:7b2882874f87 353 }
Jan Jongboom 18:7b2882874f87 354 else {
Jan Jongboom 18:7b2882874f87 355 resources[route_str]->set_value((uint8_t*)v.c_str(), v.length());
Jan Jongboom 18:7b2882874f87 356 }
Jan Jongboom 18:7b2882874f87 357
Jan Jongboom 18:7b2882874f87 358 updateValues[route_str]->clear_pending_value();
Jan Jongboom 18:7b2882874f87 359 }
Jan Jongboom 18:7b2882874f87 360
Jan Jongboom 18:7b2882874f87 361 void internal_set_int(string route, const int& v) {
Jan Jongboom 18:7b2882874f87 362 char str[13];
Jan Jongboom 18:7b2882874f87 363 sprintf(str, "%d", v);
Jan Jongboom 18:7b2882874f87 364
Jan Jongboom 18:7b2882874f87 365 internal_set_str(route, string(str));
Jan Jongboom 18:7b2882874f87 366 }
Jan Jongboom 18:7b2882874f87 367
Jan Jongboom 22:17b4681e3353 368 void internal_set_float(string route, const float& v) {
Jan Jongboom 22:17b4681e3353 369 int size = snprintf(NULL, 0, "%g", v);
Jan Jongboom 22:17b4681e3353 370
Jan Jongboom 22:17b4681e3353 371 char str[size];
Jan Jongboom 22:17b4681e3353 372 sprintf(str, "%g", v);
Jan Jongboom 22:17b4681e3353 373
Jan Jongboom 22:17b4681e3353 374 internal_set_str(route, string(str));
Jan Jongboom 22:17b4681e3353 375 }
Jan Jongboom 22:17b4681e3353 376
Jan Jongboom 18:7b2882874f87 377 void keep_alive() {
Jan Jongboom 18:7b2882874f87 378 client->test_update_register();
Jan Jongboom 3:ce2322965a27 379 }
Jan Jongboom 3:ce2322965a27 380
janjongboom 0:9fa3f3028773 381 Serial output;
Jan Jongboom 3:ce2322965a27 382
janjongboom 0:9fa3f3028773 383 MbedClient* client;
janjongboom 0:9fa3f3028773 384 map<string, M2MObject*> objects;
janjongboom 0:9fa3f3028773 385 map<string, M2MObjectInstance*> objectInstances;
janjongboom 0:9fa3f3028773 386 map<string, M2MResource*> resources;
janjongboom 2:0a015df677a4 387
Jan Jongboom 18:7b2882874f87 388 EventQueue* evQueue;
Jan Jongboom 18:7b2882874f87 389 Thread* evThread;
Jan Jongboom 18:7b2882874f87 390
Jan Jongboom 3:ce2322965a27 391 bool debug;
Jan Jongboom 3:ce2322965a27 392
Jan Jongboom 3:ce2322965a27 393 map<string, SimpleResourceBase*> updateValues;
janjongboom 0:9fa3f3028773 394 };
janjongboom 0:9fa3f3028773 395
Jan Jongboom 3:ce2322965a27 396 class SimpleResourceString : public SimpleResourceBase {
janjongboom 0:9fa3f3028773 397 public:
Jan Jongboom 12:26810c6b58e1 398 SimpleResourceString(SimpleMbedClientBase* aSimpleClient, string aRoute, Callback<void(string)> aOnUpdate) :
Jan Jongboom 20:bfa6cc52d6d7 399 simpleClient(aSimpleClient), route(aRoute), onUpdate(aOnUpdate), hasPendingValue(false) {}
janjongboom 0:9fa3f3028773 400
janjongboom 0:9fa3f3028773 401 string operator=(const string& newValue) {
Jan Jongboom 18:7b2882874f87 402 pendingValue = newValue;
Jan Jongboom 18:7b2882874f87 403 hasPendingValue = true;
Jan Jongboom 18:7b2882874f87 404
janjongboom 0:9fa3f3028773 405 simpleClient->set(route, newValue);
janjongboom 0:9fa3f3028773 406 return newValue;
janjongboom 0:9fa3f3028773 407 };
Jan Jongboom 18:7b2882874f87 408
janjongboom 0:9fa3f3028773 409 operator string() const {
Jan Jongboom 18:7b2882874f87 410 if (hasPendingValue) {
Jan Jongboom 18:7b2882874f87 411 return pendingValue;
Jan Jongboom 18:7b2882874f87 412 }
Jan Jongboom 18:7b2882874f87 413
janjongboom 0:9fa3f3028773 414 return simpleClient->get(route);
janjongboom 0:9fa3f3028773 415 };
janjongboom 0:9fa3f3028773 416
Jan Jongboom 3:ce2322965a27 417 virtual void update(string v) {
Jan Jongboom 3:ce2322965a27 418 if (onUpdate) onUpdate(v);
Jan Jongboom 3:ce2322965a27 419 }
Jan Jongboom 3:ce2322965a27 420
Jan Jongboom 6:a1a766d45957 421 M2MResource* get_resource() {
Jan Jongboom 6:a1a766d45957 422 return simpleClient->get_resource(route);
Jan Jongboom 6:a1a766d45957 423 }
Jan Jongboom 6:a1a766d45957 424
Jan Jongboom 18:7b2882874f87 425 virtual void clear_pending_value() {
Jan Jongboom 18:7b2882874f87 426 hasPendingValue = false;
Jan Jongboom 18:7b2882874f87 427 }
Jan Jongboom 18:7b2882874f87 428
janjongboom 0:9fa3f3028773 429 private:
janjongboom 0:9fa3f3028773 430 SimpleMbedClientBase* simpleClient;
janjongboom 0:9fa3f3028773 431 string route;
Jan Jongboom 12:26810c6b58e1 432 Callback<void(string)> onUpdate;
Jan Jongboom 18:7b2882874f87 433
Jan Jongboom 18:7b2882874f87 434 // set() is async (because on the event queue, so store the pending value here...)
Jan Jongboom 20:bfa6cc52d6d7 435 bool hasPendingValue;
Jan Jongboom 18:7b2882874f87 436 string pendingValue;
janjongboom 0:9fa3f3028773 437 };
janjongboom 0:9fa3f3028773 438
Jan Jongboom 3:ce2322965a27 439 class SimpleResourceInt : public SimpleResourceBase {
janjongboom 0:9fa3f3028773 440 public:
Jan Jongboom 12:26810c6b58e1 441 SimpleResourceInt(SimpleMbedClientBase* aSimpleClient, string aRoute, Callback<void(int)> aOnUpdate) :
Jan Jongboom 21:816251388f55 442 simpleClient(aSimpleClient), route(aRoute), onUpdate(aOnUpdate), hasPendingValue(false), pendingValue(0) {}
janjongboom 0:9fa3f3028773 443
janjongboom 0:9fa3f3028773 444 int operator=(int newValue) {
Jan Jongboom 18:7b2882874f87 445 pendingValue = newValue;
Jan Jongboom 18:7b2882874f87 446 hasPendingValue = true;
Jan Jongboom 18:7b2882874f87 447
janjongboom 0:9fa3f3028773 448 simpleClient->set(route, newValue);
janjongboom 0:9fa3f3028773 449 return newValue;
janjongboom 0:9fa3f3028773 450 };
janjongboom 0:9fa3f3028773 451 operator int() const {
Jan Jongboom 18:7b2882874f87 452 if (hasPendingValue) {
Jan Jongboom 18:7b2882874f87 453 return pendingValue;
Jan Jongboom 18:7b2882874f87 454 }
Jan Jongboom 18:7b2882874f87 455
janjongboom 0:9fa3f3028773 456 string v = simpleClient->get(route);
janjongboom 0:9fa3f3028773 457 if (v.empty()) return 0;
Jan Jongboom 3:ce2322965a27 458
janjongboom 0:9fa3f3028773 459 return atoi((const char*)v.c_str());
janjongboom 0:9fa3f3028773 460 };
janjongboom 0:9fa3f3028773 461
Jan Jongboom 3:ce2322965a27 462 virtual void update(string v) {
Jan Jongboom 3:ce2322965a27 463 if (!onUpdate) return;
Jan Jongboom 3:ce2322965a27 464
Jan Jongboom 3:ce2322965a27 465 onUpdate(atoi((const char*)v.c_str()));
Jan Jongboom 3:ce2322965a27 466 }
Jan Jongboom 3:ce2322965a27 467
Jan Jongboom 6:a1a766d45957 468 M2MResource* get_resource() {
Jan Jongboom 6:a1a766d45957 469 return simpleClient->get_resource(route);
Jan Jongboom 6:a1a766d45957 470 }
Jan Jongboom 6:a1a766d45957 471
Jan Jongboom 18:7b2882874f87 472 virtual void clear_pending_value() {
Jan Jongboom 18:7b2882874f87 473 hasPendingValue = false;
Jan Jongboom 18:7b2882874f87 474 }
Jan Jongboom 18:7b2882874f87 475
janjongboom 0:9fa3f3028773 476 private:
janjongboom 0:9fa3f3028773 477 SimpleMbedClientBase* simpleClient;
janjongboom 0:9fa3f3028773 478 string route;
Jan Jongboom 12:26810c6b58e1 479 Callback<void(int)> onUpdate;
Jan Jongboom 18:7b2882874f87 480
Jan Jongboom 18:7b2882874f87 481 // set() is async (because on the event queue, so store the pending value here...)
Jan Jongboom 20:bfa6cc52d6d7 482 bool hasPendingValue;
Jan Jongboom 18:7b2882874f87 483 int pendingValue;
janjongboom 0:9fa3f3028773 484 };
janjongboom 0:9fa3f3028773 485
Jan Jongboom 22:17b4681e3353 486 class SimpleResourceFloat : public SimpleResourceBase {
Jan Jongboom 22:17b4681e3353 487 public:
Jan Jongboom 22:17b4681e3353 488 SimpleResourceFloat(SimpleMbedClientBase* aSimpleClient, string aRoute, Callback<void(float)> aOnUpdate) :
Jan Jongboom 22:17b4681e3353 489 simpleClient(aSimpleClient), route(aRoute), onUpdate(aOnUpdate), hasPendingValue(false), pendingValue(0) {}
Jan Jongboom 22:17b4681e3353 490
Jan Jongboom 22:17b4681e3353 491 float operator=(float newValue) {
Jan Jongboom 22:17b4681e3353 492 pendingValue = newValue;
Jan Jongboom 22:17b4681e3353 493 hasPendingValue = true;
Jan Jongboom 22:17b4681e3353 494
Jan Jongboom 22:17b4681e3353 495 simpleClient->set(route, newValue);
Jan Jongboom 22:17b4681e3353 496 return newValue;
Jan Jongboom 22:17b4681e3353 497 };
Jan Jongboom 22:17b4681e3353 498 operator float() const {
Jan Jongboom 22:17b4681e3353 499 if (hasPendingValue) {
Jan Jongboom 22:17b4681e3353 500 return pendingValue;
Jan Jongboom 22:17b4681e3353 501 }
Jan Jongboom 22:17b4681e3353 502
Jan Jongboom 22:17b4681e3353 503 string v = simpleClient->get(route);
Jan Jongboom 22:17b4681e3353 504 if (v.empty()) return 0;
Jan Jongboom 22:17b4681e3353 505
Jan Jongboom 22:17b4681e3353 506 return atof((const char*)v.c_str());
Jan Jongboom 22:17b4681e3353 507 };
Jan Jongboom 22:17b4681e3353 508
Jan Jongboom 22:17b4681e3353 509 virtual void update(string v) {
Jan Jongboom 22:17b4681e3353 510 if (!onUpdate) return;
Jan Jongboom 22:17b4681e3353 511
Jan Jongboom 22:17b4681e3353 512 onUpdate(atof((const char*)v.c_str()));
Jan Jongboom 22:17b4681e3353 513 }
Jan Jongboom 22:17b4681e3353 514
Jan Jongboom 22:17b4681e3353 515 M2MResource* get_resource() {
Jan Jongboom 22:17b4681e3353 516 return simpleClient->get_resource(route);
Jan Jongboom 22:17b4681e3353 517 }
Jan Jongboom 22:17b4681e3353 518
Jan Jongboom 22:17b4681e3353 519 virtual void clear_pending_value() {
Jan Jongboom 22:17b4681e3353 520 hasPendingValue = false;
Jan Jongboom 22:17b4681e3353 521 }
Jan Jongboom 22:17b4681e3353 522
Jan Jongboom 22:17b4681e3353 523 private:
Jan Jongboom 22:17b4681e3353 524 SimpleMbedClientBase* simpleClient;
Jan Jongboom 22:17b4681e3353 525 string route;
Jan Jongboom 22:17b4681e3353 526 Callback<void(float)> onUpdate;
Jan Jongboom 22:17b4681e3353 527
Jan Jongboom 22:17b4681e3353 528 // set() is async (because on the event queue, so store the pending value here...)
Jan Jongboom 22:17b4681e3353 529 bool hasPendingValue;
Jan Jongboom 22:17b4681e3353 530 float pendingValue;
Jan Jongboom 22:17b4681e3353 531 };
Jan Jongboom 22:17b4681e3353 532
janjongboom 0:9fa3f3028773 533 class SimpleMbedClient : public SimpleMbedClientBase {
janjongboom 0:9fa3f3028773 534 public:
janjongboom 1:75015f627e89 535
Jan Jongboom 17:200624714d15 536 SimpleMbedClient(bool aDebug = true)
Jan Jongboom 17:200624714d15 537 : SimpleMbedClientBase(aDebug)
Jan Jongboom 17:200624714d15 538 {
Jan Jongboom 17:200624714d15 539
Jan Jongboom 17:200624714d15 540 }
Jan Jongboom 17:200624714d15 541
Jan Jongboom 18:7b2882874f87 542 SimpleMbedClient(EventQueue* aQueue, bool aDebug = true)
Jan Jongboom 18:7b2882874f87 543 : SimpleMbedClientBase(aQueue, aDebug)
Jan Jongboom 18:7b2882874f87 544 {
Jan Jongboom 18:7b2882874f87 545
Jan Jongboom 18:7b2882874f87 546 }
Jan Jongboom 18:7b2882874f87 547
janjongboom 1:75015f627e89 548 // @todo: macro this up
janjongboom 1:75015f627e89 549
Jan Jongboom 22:17b4681e3353 550 // String
janjongboom 1:75015f627e89 551 SimpleResourceString define_resource(
Jan Jongboom 3:ce2322965a27 552 const char* route,
Jan Jongboom 3:ce2322965a27 553 string v,
Jan Jongboom 3:ce2322965a27 554 M2MBase::Operation opr = M2MBase::GET_PUT_ALLOWED,
janjongboom 1:75015f627e89 555 bool observable = true,
Jan Jongboom 12:26810c6b58e1 556 Callback<void(string)> onUpdate = NULL)
janjongboom 1:75015f627e89 557 {
Jan Jongboom 3:ce2322965a27 558 SimpleResourceString* simpleResource = new SimpleResourceString(this, route, onUpdate);
janjongboom 0:9fa3f3028773 559 bool res = define_resource_internal(route, v, opr, observable);
Jan Jongboom 3:ce2322965a27 560 if (!res) {
Jan Jongboom 3:ce2322965a27 561 printf("Error while creating %s\n", route);
Jan Jongboom 3:ce2322965a27 562 }
Jan Jongboom 3:ce2322965a27 563 else {
Jan Jongboom 3:ce2322965a27 564 register_update_callback(route, simpleResource);
Jan Jongboom 3:ce2322965a27 565 }
Jan Jongboom 3:ce2322965a27 566 return *simpleResource;
janjongboom 0:9fa3f3028773 567 }
janjongboom 1:75015f627e89 568
janjongboom 1:75015f627e89 569 SimpleResourceString define_resource(
Jan Jongboom 3:ce2322965a27 570 const char* route,
Jan Jongboom 3:ce2322965a27 571 string v,
Jan Jongboom 3:ce2322965a27 572 M2MBase::Operation opr,
janjongboom 1:75015f627e89 573 bool observable,
Jan Jongboom 3:ce2322965a27 574 void(*onUpdate)(string))
janjongboom 1:75015f627e89 575 {
Jan Jongboom 12:26810c6b58e1 576 Callback<void(string)> fp;
janjongboom 1:75015f627e89 577 fp.attach(onUpdate);
janjongboom 1:75015f627e89 578 return define_resource(route, v, opr, observable, fp);
janjongboom 1:75015f627e89 579 }
Jan Jongboom 3:ce2322965a27 580
janjongboom 1:75015f627e89 581 SimpleResourceString define_resource(
Jan Jongboom 3:ce2322965a27 582 const char* route,
janjongboom 1:75015f627e89 583 string v,
Jan Jongboom 12:26810c6b58e1 584 Callback<void(string)> onUpdate)
janjongboom 1:75015f627e89 585 {
janjongboom 1:75015f627e89 586 return define_resource(route, v, M2MBase::GET_PUT_ALLOWED, true, onUpdate);
janjongboom 1:75015f627e89 587 }
janjongboom 1:75015f627e89 588
janjongboom 1:75015f627e89 589 SimpleResourceString define_resource(
Jan Jongboom 3:ce2322965a27 590 const char* route,
janjongboom 1:75015f627e89 591 string v,
Jan Jongboom 3:ce2322965a27 592 void(*onUpdate)(string))
janjongboom 1:75015f627e89 593 {
Jan Jongboom 12:26810c6b58e1 594 Callback<void(string)> fp;
janjongboom 1:75015f627e89 595 fp.attach(onUpdate);
janjongboom 1:75015f627e89 596 return define_resource(route, v, M2MBase::GET_PUT_ALLOWED, true, fp);
janjongboom 1:75015f627e89 597 }
Jan Jongboom 3:ce2322965a27 598
Jan Jongboom 22:17b4681e3353 599 // Int
janjongboom 1:75015f627e89 600 SimpleResourceInt define_resource(
Jan Jongboom 3:ce2322965a27 601 const char* route,
Jan Jongboom 3:ce2322965a27 602 int v,
Jan Jongboom 3:ce2322965a27 603 M2MBase::Operation opr = M2MBase::GET_PUT_ALLOWED,
janjongboom 1:75015f627e89 604 bool observable = true,
Jan Jongboom 12:26810c6b58e1 605 Callback<void(int)> onUpdate = NULL)
janjongboom 1:75015f627e89 606 {
Jan Jongboom 3:ce2322965a27 607 SimpleResourceInt* simpleResource = new SimpleResourceInt(this, route, onUpdate);
Jan Jongboom 3:ce2322965a27 608
Jan Jongboom 16:cb980bd39e32 609 char str[13];
Jan Jongboom 16:cb980bd39e32 610 sprintf(str, "%d", v);
Jan Jongboom 16:cb980bd39e32 611
Jan Jongboom 16:cb980bd39e32 612 bool res = define_resource_internal(route, string(str), opr, observable);
Jan Jongboom 3:ce2322965a27 613 if (!res) {
Jan Jongboom 3:ce2322965a27 614 printf("Error while creating %s\n", route);
Jan Jongboom 3:ce2322965a27 615 }
Jan Jongboom 3:ce2322965a27 616 else {
Jan Jongboom 3:ce2322965a27 617 register_update_callback(route, simpleResource);
Jan Jongboom 3:ce2322965a27 618 }
Jan Jongboom 3:ce2322965a27 619 return *simpleResource;
janjongboom 0:9fa3f3028773 620 }
Jan Jongboom 3:ce2322965a27 621
janjongboom 1:75015f627e89 622 SimpleResourceInt define_resource(
Jan Jongboom 3:ce2322965a27 623 const char* route,
Jan Jongboom 3:ce2322965a27 624 int v,
Jan Jongboom 3:ce2322965a27 625 M2MBase::Operation opr,
janjongboom 1:75015f627e89 626 bool observable,
Jan Jongboom 3:ce2322965a27 627 void(*onUpdate)(int))
janjongboom 1:75015f627e89 628 {
Jan Jongboom 12:26810c6b58e1 629 Callback<void(int)> fp;
janjongboom 1:75015f627e89 630 fp.attach(onUpdate);
janjongboom 1:75015f627e89 631 return define_resource(route, v, opr, observable, fp);
janjongboom 1:75015f627e89 632 }
Jan Jongboom 3:ce2322965a27 633
janjongboom 1:75015f627e89 634 SimpleResourceInt define_resource(
Jan Jongboom 3:ce2322965a27 635 const char* route,
janjongboom 1:75015f627e89 636 int v,
Jan Jongboom 12:26810c6b58e1 637 Callback<void(int)> onUpdate)
janjongboom 1:75015f627e89 638 {
janjongboom 1:75015f627e89 639 return define_resource(route, v, M2MBase::GET_PUT_ALLOWED, true, onUpdate);
janjongboom 1:75015f627e89 640 }
janjongboom 1:75015f627e89 641
janjongboom 1:75015f627e89 642 SimpleResourceInt define_resource(
Jan Jongboom 3:ce2322965a27 643 const char* route,
janjongboom 1:75015f627e89 644 int v,
Jan Jongboom 3:ce2322965a27 645 void(*onUpdate)(int))
janjongboom 1:75015f627e89 646 {
Jan Jongboom 12:26810c6b58e1 647 Callback<void(int)> fp;
janjongboom 1:75015f627e89 648 fp.attach(onUpdate);
janjongboom 1:75015f627e89 649 return define_resource(route, v, M2MBase::GET_PUT_ALLOWED, true, fp);
janjongboom 1:75015f627e89 650 }
Jan Jongboom 22:17b4681e3353 651
Jan Jongboom 22:17b4681e3353 652 // Float
Jan Jongboom 22:17b4681e3353 653 SimpleResourceFloat define_resource(
Jan Jongboom 22:17b4681e3353 654 const char* route,
Jan Jongboom 22:17b4681e3353 655 float v,
Jan Jongboom 22:17b4681e3353 656 M2MBase::Operation opr = M2MBase::GET_PUT_ALLOWED,
Jan Jongboom 22:17b4681e3353 657 bool observable = true,
Jan Jongboom 22:17b4681e3353 658 Callback<void(float)> onUpdate = NULL)
Jan Jongboom 22:17b4681e3353 659 {
Jan Jongboom 22:17b4681e3353 660 SimpleResourceFloat* simpleResource = new SimpleResourceFloat(this, route, onUpdate);
Jan Jongboom 22:17b4681e3353 661
Jan Jongboom 22:17b4681e3353 662 int size = snprintf(NULL, 0, "%g", v);
Jan Jongboom 22:17b4681e3353 663
Jan Jongboom 22:17b4681e3353 664 // malloc() would probably be better here
Jan Jongboom 22:17b4681e3353 665 char str[size];
Jan Jongboom 22:17b4681e3353 666 sprintf(str, "%g", v);
Jan Jongboom 22:17b4681e3353 667
Jan Jongboom 22:17b4681e3353 668 bool res = define_resource_internal(route, string(str), opr, observable);
Jan Jongboom 22:17b4681e3353 669 if (!res) {
Jan Jongboom 22:17b4681e3353 670 printf("Error while creating %s\n", route);
Jan Jongboom 22:17b4681e3353 671 }
Jan Jongboom 22:17b4681e3353 672 else {
Jan Jongboom 22:17b4681e3353 673 register_update_callback(route, simpleResource);
Jan Jongboom 22:17b4681e3353 674 }
Jan Jongboom 22:17b4681e3353 675 return *simpleResource;
Jan Jongboom 22:17b4681e3353 676 }
Jan Jongboom 22:17b4681e3353 677
Jan Jongboom 22:17b4681e3353 678 SimpleResourceFloat define_resource(
Jan Jongboom 22:17b4681e3353 679 const char* route,
Jan Jongboom 22:17b4681e3353 680 float v,
Jan Jongboom 22:17b4681e3353 681 M2MBase::Operation opr,
Jan Jongboom 22:17b4681e3353 682 bool observable,
Jan Jongboom 22:17b4681e3353 683 void(*onUpdate)(float))
Jan Jongboom 22:17b4681e3353 684 {
Jan Jongboom 22:17b4681e3353 685 Callback<void(float)> fp;
Jan Jongboom 22:17b4681e3353 686 fp.attach(onUpdate);
Jan Jongboom 22:17b4681e3353 687 return define_resource(route, v, opr, observable, fp);
Jan Jongboom 22:17b4681e3353 688 }
Jan Jongboom 22:17b4681e3353 689
Jan Jongboom 22:17b4681e3353 690 SimpleResourceFloat define_resource(
Jan Jongboom 22:17b4681e3353 691 const char* route,
Jan Jongboom 22:17b4681e3353 692 float v,
Jan Jongboom 22:17b4681e3353 693 Callback<void(float)> onUpdate)
Jan Jongboom 22:17b4681e3353 694 {
Jan Jongboom 22:17b4681e3353 695 return define_resource(route, v, M2MBase::GET_PUT_ALLOWED, true, onUpdate);
Jan Jongboom 22:17b4681e3353 696 }
Jan Jongboom 22:17b4681e3353 697
Jan Jongboom 22:17b4681e3353 698 SimpleResourceFloat define_resource(
Jan Jongboom 22:17b4681e3353 699 const char* route,
Jan Jongboom 22:17b4681e3353 700 float v,
Jan Jongboom 22:17b4681e3353 701 void(*onUpdate)(float))
Jan Jongboom 22:17b4681e3353 702 {
Jan Jongboom 22:17b4681e3353 703 Callback<void(float)> fp;
Jan Jongboom 22:17b4681e3353 704 fp.attach(onUpdate);
Jan Jongboom 22:17b4681e3353 705 return define_resource(route, v, M2MBase::GET_PUT_ALLOWED, true, fp);
Jan Jongboom 22:17b4681e3353 706 }
janjongboom 0:9fa3f3028773 707 };
janjongboom 0:9fa3f3028773 708
Jan Jongboom 3:ce2322965a27 709 #endif // __SIMPLE_MBED_CLIENT_H__