sandbox / simple-mbed-client

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

Fork of simple-mbed-client by Jan Jongboom

Committer:
Jan Jongboom
Date:
Tue Feb 07 13:00:32 2017 +0100
Revision:
18:7b2882874f87
Parent:
17:200624714d15
Child:
19:cf570422d4dd
Add EventQueue, auto-update registration and make set() calls safe in ISR

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
janjongboom 0:9fa3f3028773 167 bool define_function(const char* route, void(*fn)(void*)) {
janjongboom 0:9fa3f3028773 168 if (!define_resource_internal(route, string(), M2MBase::POST_ALLOWED, false)) {
janjongboom 0:9fa3f3028773 169 return false;
janjongboom 0:9fa3f3028773 170 }
Jan Jongboom 3:ce2322965a27 171
janjongboom 0:9fa3f3028773 172 string route_str(route);
janjongboom 0:9fa3f3028773 173 if (!resources.count(route_str)) {
Jan Jongboom 18:7b2882874f87 174 smc_debug_msg("[SMC] [ERROR] Should be created, but no such route (%s)\r\n", route);
janjongboom 0:9fa3f3028773 175 return false;
janjongboom 0:9fa3f3028773 176 }
Jan Jongboom 3:ce2322965a27 177
Jan Jongboom 3:ce2322965a27 178 resources[route_str]->set_execute_function(execute_callback_2(fn));
janjongboom 0:9fa3f3028773 179 return true;
janjongboom 0:9fa3f3028773 180 }
janjongboom 0:9fa3f3028773 181
janjongboom 0:9fa3f3028773 182 bool define_function(const char* route, execute_callback fn) {
janjongboom 0:9fa3f3028773 183 if (!define_resource_internal(route, string(), M2MBase::POST_ALLOWED, false)) {
janjongboom 0:9fa3f3028773 184 return false;
janjongboom 0:9fa3f3028773 185 }
Jan Jongboom 3:ce2322965a27 186
janjongboom 0:9fa3f3028773 187 string route_str(route);
janjongboom 0:9fa3f3028773 188 if (!resources.count(route_str)) {
Jan Jongboom 18:7b2882874f87 189 smc_debug_msg("[SMC] [ERROR] Should be created, but no such route (%s)\r\n", route);
janjongboom 0:9fa3f3028773 190 return false;
janjongboom 0:9fa3f3028773 191 }
janjongboom 0:9fa3f3028773 192 // No clue why this is not working?! It works with class member, but not with static function...
janjongboom 0:9fa3f3028773 193 resources[route_str]->set_execute_function(fn);
janjongboom 0:9fa3f3028773 194 return true;
janjongboom 0:9fa3f3028773 195 }
Jan Jongboom 3:ce2322965a27 196
janjongboom 0:9fa3f3028773 197 string get(string route_str) {
janjongboom 0:9fa3f3028773 198 if (!resources.count(route_str)) {
Jan Jongboom 18:7b2882874f87 199 smc_debug_msg("[SMC] [ERROR] No such route (%s)\r\n", route_str.c_str());
janjongboom 0:9fa3f3028773 200 return string();
janjongboom 0:9fa3f3028773 201 }
Jan Jongboom 3:ce2322965a27 202
janjongboom 2:0a015df677a4 203 // otherwise ask mbed Client...
janjongboom 2:0a015df677a4 204 uint8_t* buffIn = NULL;
janjongboom 0:9fa3f3028773 205 uint32_t sizeIn;
janjongboom 0:9fa3f3028773 206 resources[route_str]->get_value(buffIn, sizeIn);
Jan Jongboom 3:ce2322965a27 207
janjongboom 2:0a015df677a4 208 string s((char*)buffIn, sizeIn);
janjongboom 0:9fa3f3028773 209 return s;
janjongboom 0:9fa3f3028773 210 }
janjongboom 0:9fa3f3028773 211
Jan Jongboom 18:7b2882874f87 212 void set(string route_str, string v) {
Jan Jongboom 18:7b2882874f87 213 evQueue->call(callback(this, &SimpleMbedClientBase::internal_set_str), route_str, v);
janjongboom 0:9fa3f3028773 214 }
janjongboom 0:9fa3f3028773 215
Jan Jongboom 18:7b2882874f87 216 void set(string route_str, const int& v) {
Jan Jongboom 18:7b2882874f87 217 evQueue->call(callback(this, &SimpleMbedClientBase::internal_set_int), route_str, v);
janjongboom 0:9fa3f3028773 218 }
janjongboom 0:9fa3f3028773 219
Jan Jongboom 16:cb980bd39e32 220 bool define_resource_internal(const char* route, string v, M2MBase::Operation opr, bool observable) {
janjongboom 0:9fa3f3028773 221 if (client) {
Jan Jongboom 18:7b2882874f87 222 smc_debug_msg("[SMC] [ERROR] mbed_client_define_resource, Can only define resources before mbed_client_setup is called!\r\n");
janjongboom 0:9fa3f3028773 223 return false;
janjongboom 0:9fa3f3028773 224 }
Jan Jongboom 3:ce2322965a27 225
janjongboom 0:9fa3f3028773 226 vector<string> segments = parse_route(route);
janjongboom 0:9fa3f3028773 227 if (segments.size() != 3) {
Jan Jongboom 18:7b2882874f87 228 smc_debug_msg("[SMC] [ERROR] mbed_client_define_resource, Route needs to have three segments, split by '/' (%s)\r\n", route);
janjongboom 0:9fa3f3028773 229 return false;
janjongboom 0:9fa3f3028773 230 }
janjongboom 0:9fa3f3028773 231
Jan Jongboom 3:ce2322965a27 232 // segments[1] should be one digit and numeric
janjongboom 10:3fecd642d506 233 char n = segments.at(1).c_str()[0];
janjongboom 10:3fecd642d506 234 if (n < '0' || n > '9') {
Jan Jongboom 18:7b2882874f87 235 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 236 return false;
Jan Jongboom 3:ce2322965a27 237 }
Jan Jongboom 3:ce2322965a27 238
Jan Jongboom 3:ce2322965a27 239 int inst_id = atoi(segments.at(1).c_str());
Jan Jongboom 3:ce2322965a27 240
janjongboom 0:9fa3f3028773 241 M2MObjectInstance* inst;
janjongboom 0:9fa3f3028773 242 if (objectInstances.count(segments.at(0))) {
janjongboom 0:9fa3f3028773 243 inst = objectInstances[segments.at(0)];
janjongboom 0:9fa3f3028773 244 }
janjongboom 0:9fa3f3028773 245 else {
janjongboom 0:9fa3f3028773 246 M2MObject* obj = M2MInterfaceFactory::create_object(segments.at(0).c_str());
janjongboom 0:9fa3f3028773 247 inst = obj->create_object_instance(inst_id);
janjongboom 0:9fa3f3028773 248 objects.insert(std::pair<string, M2MObject*>(segments.at(0), obj));
janjongboom 0:9fa3f3028773 249 objectInstances.insert(std::pair<string, M2MObjectInstance*>(segments.at(0), inst));
janjongboom 0:9fa3f3028773 250 }
Jan Jongboom 3:ce2322965a27 251
janjongboom 0:9fa3f3028773 252 // @todo check if the resource exists yet
janjongboom 0:9fa3f3028773 253 M2MResource* res = inst->create_dynamic_resource(segments.at(2).c_str(), "",
janjongboom 0:9fa3f3028773 254 M2MResourceInstance::STRING, observable);
janjongboom 0:9fa3f3028773 255 res->set_operation(opr);
janjongboom 0:9fa3f3028773 256 res->set_value((uint8_t*)v.c_str(), v.length());
Jan Jongboom 3:ce2322965a27 257
janjongboom 0:9fa3f3028773 258 string route_str(route);
janjongboom 2:0a015df677a4 259 resources.insert(pair<string, M2MResource*>(route_str, res));
Jan Jongboom 3:ce2322965a27 260
janjongboom 0:9fa3f3028773 261 return true;
janjongboom 0:9fa3f3028773 262 }
Jan Jongboom 3:ce2322965a27 263
Jan Jongboom 3:ce2322965a27 264 void register_update_callback(string route, SimpleResourceBase* simpleResource) {
Jan Jongboom 3:ce2322965a27 265 updateValues[route] = simpleResource;
Jan Jongboom 3:ce2322965a27 266 }
Jan Jongboom 3:ce2322965a27 267
Jan Jongboom 6:a1a766d45957 268 M2MResource* get_resource(string route) {
Jan Jongboom 6:a1a766d45957 269 if (!resources.count(route)) {
Jan Jongboom 18:7b2882874f87 270 smc_debug_msg("[SMC] [ERROR] No such route (%s)\r\n", route.c_str());
Jan Jongboom 6:a1a766d45957 271 return NULL;
Jan Jongboom 6:a1a766d45957 272 }
Jan Jongboom 6:a1a766d45957 273
Jan Jongboom 6:a1a766d45957 274 return resources[route];
Jan Jongboom 6:a1a766d45957 275 }
Jan Jongboom 6:a1a766d45957 276
Jan Jongboom 18:7b2882874f87 277 EventQueue* eventQueue() const {
Jan Jongboom 18:7b2882874f87 278 return evQueue;
Jan Jongboom 18:7b2882874f87 279 }
Jan Jongboom 18:7b2882874f87 280
janjongboom 0:9fa3f3028773 281 private:
janjongboom 0:9fa3f3028773 282 vector<string> parse_route(const char* route) {
Jan Jongboom 16:cb980bd39e32 283 const string s(route);
janjongboom 0:9fa3f3028773 284 vector<string> v;
Jan Jongboom 16:cb980bd39e32 285
Jan Jongboom 16:cb980bd39e32 286 split(s, '/', v);
Jan Jongboom 16:cb980bd39e32 287
Jan Jongboom 16:cb980bd39e32 288 return v;
Jan Jongboom 16:cb980bd39e32 289 }
Jan Jongboom 16:cb980bd39e32 290
Jan Jongboom 16:cb980bd39e32 291 void split(const string& s, char delim, vector<string>& v) {
Jan Jongboom 16:cb980bd39e32 292 size_t i = 0;
Jan Jongboom 16:cb980bd39e32 293 size_t pos = s.find(delim);
Jan Jongboom 16:cb980bd39e32 294 while (pos != string::npos) {
Jan Jongboom 16:cb980bd39e32 295 v.push_back(s.substr(i, pos - i));
Jan Jongboom 16:cb980bd39e32 296 i = ++pos;
Jan Jongboom 16:cb980bd39e32 297 pos = s.find(delim, pos);
Jan Jongboom 16:cb980bd39e32 298
Jan Jongboom 16:cb980bd39e32 299 if (pos == string::npos) {
Jan Jongboom 16:cb980bd39e32 300 v.push_back(s.substr(i, s.length()));
Jan Jongboom 16:cb980bd39e32 301 }
janjongboom 0:9fa3f3028773 302 }
janjongboom 0:9fa3f3028773 303 }
janjongboom 0:9fa3f3028773 304
Jan Jongboom 3:ce2322965a27 305 void resource_updated(string uri) {
Jan Jongboom 3:ce2322965a27 306 if (updateValues.count(uri) == 0) return;
Jan Jongboom 3:ce2322965a27 307
Jan Jongboom 3:ce2322965a27 308 string v = get(uri);
Jan Jongboom 3:ce2322965a27 309 if (v.empty()) return;
Jan Jongboom 3:ce2322965a27 310
Jan Jongboom 18:7b2882874f87 311 // Schedule this on the other thread, to avoid blocking this thread
Jan Jongboom 18:7b2882874f87 312 evQueue->call(callback(updateValues[uri], &SimpleResourceBase::update), v);
Jan Jongboom 18:7b2882874f87 313 }
Jan Jongboom 18:7b2882874f87 314
Jan Jongboom 18:7b2882874f87 315 // These operations have side effects, they should not be called immediately,
Jan Jongboom 18:7b2882874f87 316 // but always through the eventqueue
Jan Jongboom 18:7b2882874f87 317 void internal_set_str(string route_str, string v) {
Jan Jongboom 18:7b2882874f87 318 if (!resources.count(route_str)) {
Jan Jongboom 18:7b2882874f87 319 smc_debug_msg("[SMC] [ERROR] No such route (%s)\r\n", route_str.c_str());
Jan Jongboom 18:7b2882874f87 320 return;
Jan Jongboom 18:7b2882874f87 321 }
Jan Jongboom 18:7b2882874f87 322
Jan Jongboom 18:7b2882874f87 323 if (v.length() == 0) {
Jan Jongboom 18:7b2882874f87 324 resources[route_str]->clear_value();
Jan Jongboom 18:7b2882874f87 325 }
Jan Jongboom 18:7b2882874f87 326 else {
Jan Jongboom 18:7b2882874f87 327 resources[route_str]->set_value((uint8_t*)v.c_str(), v.length());
Jan Jongboom 18:7b2882874f87 328 }
Jan Jongboom 18:7b2882874f87 329
Jan Jongboom 18:7b2882874f87 330 updateValues[route_str]->clear_pending_value();
Jan Jongboom 18:7b2882874f87 331 }
Jan Jongboom 18:7b2882874f87 332
Jan Jongboom 18:7b2882874f87 333 void internal_set_int(string route, const int& v) {
Jan Jongboom 18:7b2882874f87 334 char str[13];
Jan Jongboom 18:7b2882874f87 335 sprintf(str, "%d", v);
Jan Jongboom 18:7b2882874f87 336
Jan Jongboom 18:7b2882874f87 337 internal_set_str(route, string(str));
Jan Jongboom 18:7b2882874f87 338 }
Jan Jongboom 18:7b2882874f87 339
Jan Jongboom 18:7b2882874f87 340 void keep_alive() {
Jan Jongboom 18:7b2882874f87 341 client->test_update_register();
Jan Jongboom 3:ce2322965a27 342 }
Jan Jongboom 3:ce2322965a27 343
janjongboom 0:9fa3f3028773 344 Serial output;
Jan Jongboom 3:ce2322965a27 345
janjongboom 0:9fa3f3028773 346 MbedClient* client;
janjongboom 0:9fa3f3028773 347 map<string, M2MObject*> objects;
janjongboom 0:9fa3f3028773 348 map<string, M2MObjectInstance*> objectInstances;
janjongboom 0:9fa3f3028773 349 map<string, M2MResource*> resources;
janjongboom 2:0a015df677a4 350
Jan Jongboom 18:7b2882874f87 351 EventQueue* evQueue;
Jan Jongboom 18:7b2882874f87 352 Thread* evThread;
Jan Jongboom 18:7b2882874f87 353
Jan Jongboom 3:ce2322965a27 354 bool debug;
Jan Jongboom 3:ce2322965a27 355
Jan Jongboom 3:ce2322965a27 356 map<string, SimpleResourceBase*> updateValues;
janjongboom 0:9fa3f3028773 357 };
janjongboom 0:9fa3f3028773 358
Jan Jongboom 3:ce2322965a27 359 class SimpleResourceString : public SimpleResourceBase {
janjongboom 0:9fa3f3028773 360 public:
Jan Jongboom 12:26810c6b58e1 361 SimpleResourceString(SimpleMbedClientBase* aSimpleClient, string aRoute, Callback<void(string)> aOnUpdate) :
Jan Jongboom 3:ce2322965a27 362 simpleClient(aSimpleClient), route(aRoute), onUpdate(aOnUpdate) {}
janjongboom 0:9fa3f3028773 363
janjongboom 0:9fa3f3028773 364 string operator=(const string& newValue) {
Jan Jongboom 18:7b2882874f87 365 pendingValue = newValue;
Jan Jongboom 18:7b2882874f87 366 hasPendingValue = true;
Jan Jongboom 18:7b2882874f87 367
janjongboom 0:9fa3f3028773 368 simpleClient->set(route, newValue);
janjongboom 0:9fa3f3028773 369 return newValue;
janjongboom 0:9fa3f3028773 370 };
Jan Jongboom 18:7b2882874f87 371
janjongboom 0:9fa3f3028773 372 operator string() const {
Jan Jongboom 18:7b2882874f87 373 if (hasPendingValue) {
Jan Jongboom 18:7b2882874f87 374 return pendingValue;
Jan Jongboom 18:7b2882874f87 375 }
Jan Jongboom 18:7b2882874f87 376
janjongboom 0:9fa3f3028773 377 return simpleClient->get(route);
janjongboom 0:9fa3f3028773 378 };
janjongboom 0:9fa3f3028773 379
Jan Jongboom 3:ce2322965a27 380 virtual void update(string v) {
Jan Jongboom 3:ce2322965a27 381 if (onUpdate) onUpdate(v);
Jan Jongboom 3:ce2322965a27 382 }
Jan Jongboom 3:ce2322965a27 383
Jan Jongboom 6:a1a766d45957 384 M2MResource* get_resource() {
Jan Jongboom 6:a1a766d45957 385 return simpleClient->get_resource(route);
Jan Jongboom 6:a1a766d45957 386 }
Jan Jongboom 6:a1a766d45957 387
Jan Jongboom 18:7b2882874f87 388 virtual void clear_pending_value() {
Jan Jongboom 18:7b2882874f87 389 hasPendingValue = false;
Jan Jongboom 18:7b2882874f87 390 }
Jan Jongboom 18:7b2882874f87 391
janjongboom 0:9fa3f3028773 392 private:
janjongboom 0:9fa3f3028773 393 SimpleMbedClientBase* simpleClient;
janjongboom 0:9fa3f3028773 394 string route;
Jan Jongboom 12:26810c6b58e1 395 Callback<void(string)> onUpdate;
Jan Jongboom 18:7b2882874f87 396
Jan Jongboom 18:7b2882874f87 397 // set() is async (because on the event queue, so store the pending value here...)
Jan Jongboom 18:7b2882874f87 398 bool hasPendingValue = false;
Jan Jongboom 18:7b2882874f87 399 string pendingValue;
janjongboom 0:9fa3f3028773 400 };
janjongboom 0:9fa3f3028773 401
Jan Jongboom 3:ce2322965a27 402 class SimpleResourceInt : public SimpleResourceBase {
janjongboom 0:9fa3f3028773 403 public:
Jan Jongboom 12:26810c6b58e1 404 SimpleResourceInt(SimpleMbedClientBase* aSimpleClient, string aRoute, Callback<void(int)> aOnUpdate) :
Jan Jongboom 18:7b2882874f87 405 simpleClient(aSimpleClient), route(aRoute), onUpdate(aOnUpdate), pendingValue(0) {}
janjongboom 0:9fa3f3028773 406
janjongboom 0:9fa3f3028773 407 int operator=(int newValue) {
Jan Jongboom 18:7b2882874f87 408 pendingValue = newValue;
Jan Jongboom 18:7b2882874f87 409 hasPendingValue = true;
Jan Jongboom 18:7b2882874f87 410
janjongboom 0:9fa3f3028773 411 simpleClient->set(route, newValue);
janjongboom 0:9fa3f3028773 412 return newValue;
janjongboom 0:9fa3f3028773 413 };
janjongboom 0:9fa3f3028773 414 operator int() const {
Jan Jongboom 18:7b2882874f87 415 if (hasPendingValue) {
Jan Jongboom 18:7b2882874f87 416 return pendingValue;
Jan Jongboom 18:7b2882874f87 417 }
Jan Jongboom 18:7b2882874f87 418
janjongboom 0:9fa3f3028773 419 string v = simpleClient->get(route);
janjongboom 0:9fa3f3028773 420 if (v.empty()) return 0;
Jan Jongboom 3:ce2322965a27 421
janjongboom 0:9fa3f3028773 422 return atoi((const char*)v.c_str());
janjongboom 0:9fa3f3028773 423 };
janjongboom 0:9fa3f3028773 424
Jan Jongboom 3:ce2322965a27 425 virtual void update(string v) {
Jan Jongboom 3:ce2322965a27 426 if (!onUpdate) return;
Jan Jongboom 3:ce2322965a27 427
Jan Jongboom 3:ce2322965a27 428 onUpdate(atoi((const char*)v.c_str()));
Jan Jongboom 3:ce2322965a27 429 }
Jan Jongboom 3:ce2322965a27 430
Jan Jongboom 6:a1a766d45957 431 M2MResource* get_resource() {
Jan Jongboom 6:a1a766d45957 432 return simpleClient->get_resource(route);
Jan Jongboom 6:a1a766d45957 433 }
Jan Jongboom 6:a1a766d45957 434
Jan Jongboom 18:7b2882874f87 435 virtual void clear_pending_value() {
Jan Jongboom 18:7b2882874f87 436 hasPendingValue = false;
Jan Jongboom 18:7b2882874f87 437 }
Jan Jongboom 18:7b2882874f87 438
janjongboom 0:9fa3f3028773 439 private:
janjongboom 0:9fa3f3028773 440 SimpleMbedClientBase* simpleClient;
janjongboom 0:9fa3f3028773 441 string route;
Jan Jongboom 12:26810c6b58e1 442 Callback<void(int)> onUpdate;
Jan Jongboom 18:7b2882874f87 443
Jan Jongboom 18:7b2882874f87 444 // set() is async (because on the event queue, so store the pending value here...)
Jan Jongboom 18:7b2882874f87 445 bool hasPendingValue = false;
Jan Jongboom 18:7b2882874f87 446 int pendingValue;
janjongboom 0:9fa3f3028773 447 };
janjongboom 0:9fa3f3028773 448
janjongboom 0:9fa3f3028773 449 class SimpleMbedClient : public SimpleMbedClientBase {
janjongboom 0:9fa3f3028773 450 public:
janjongboom 1:75015f627e89 451
Jan Jongboom 17:200624714d15 452 SimpleMbedClient(bool aDebug = true)
Jan Jongboom 17:200624714d15 453 : SimpleMbedClientBase(aDebug)
Jan Jongboom 17:200624714d15 454 {
Jan Jongboom 17:200624714d15 455
Jan Jongboom 17:200624714d15 456 }
Jan Jongboom 17:200624714d15 457
Jan Jongboom 18:7b2882874f87 458 SimpleMbedClient(EventQueue* aQueue, bool aDebug = true)
Jan Jongboom 18:7b2882874f87 459 : SimpleMbedClientBase(aQueue, aDebug)
Jan Jongboom 18:7b2882874f87 460 {
Jan Jongboom 18:7b2882874f87 461
Jan Jongboom 18:7b2882874f87 462 }
Jan Jongboom 18:7b2882874f87 463
janjongboom 1:75015f627e89 464 // @todo: macro this up
janjongboom 1:75015f627e89 465
janjongboom 1:75015f627e89 466 SimpleResourceString define_resource(
Jan Jongboom 3:ce2322965a27 467 const char* route,
Jan Jongboom 3:ce2322965a27 468 string v,
Jan Jongboom 3:ce2322965a27 469 M2MBase::Operation opr = M2MBase::GET_PUT_ALLOWED,
janjongboom 1:75015f627e89 470 bool observable = true,
Jan Jongboom 12:26810c6b58e1 471 Callback<void(string)> onUpdate = NULL)
janjongboom 1:75015f627e89 472 {
Jan Jongboom 3:ce2322965a27 473 SimpleResourceString* simpleResource = new SimpleResourceString(this, route, onUpdate);
janjongboom 0:9fa3f3028773 474 bool res = define_resource_internal(route, v, opr, observable);
Jan Jongboom 3:ce2322965a27 475 if (!res) {
Jan Jongboom 3:ce2322965a27 476 printf("Error while creating %s\n", route);
Jan Jongboom 3:ce2322965a27 477 }
Jan Jongboom 3:ce2322965a27 478 else {
Jan Jongboom 3:ce2322965a27 479 register_update_callback(route, simpleResource);
Jan Jongboom 3:ce2322965a27 480 }
Jan Jongboom 3:ce2322965a27 481 return *simpleResource;
janjongboom 0:9fa3f3028773 482 }
janjongboom 1:75015f627e89 483
janjongboom 1:75015f627e89 484 SimpleResourceString define_resource(
Jan Jongboom 3:ce2322965a27 485 const char* route,
Jan Jongboom 3:ce2322965a27 486 string v,
Jan Jongboom 3:ce2322965a27 487 M2MBase::Operation opr,
janjongboom 1:75015f627e89 488 bool observable,
Jan Jongboom 3:ce2322965a27 489 void(*onUpdate)(string))
janjongboom 1:75015f627e89 490 {
Jan Jongboom 12:26810c6b58e1 491 Callback<void(string)> fp;
janjongboom 1:75015f627e89 492 fp.attach(onUpdate);
janjongboom 1:75015f627e89 493 return define_resource(route, v, opr, observable, fp);
janjongboom 1:75015f627e89 494 }
Jan Jongboom 3:ce2322965a27 495
janjongboom 1:75015f627e89 496 SimpleResourceString define_resource(
Jan Jongboom 3:ce2322965a27 497 const char* route,
janjongboom 1:75015f627e89 498 string v,
Jan Jongboom 12:26810c6b58e1 499 Callback<void(string)> onUpdate)
janjongboom 1:75015f627e89 500 {
janjongboom 1:75015f627e89 501 return define_resource(route, v, M2MBase::GET_PUT_ALLOWED, true, onUpdate);
janjongboom 1:75015f627e89 502 }
janjongboom 1:75015f627e89 503
janjongboom 1:75015f627e89 504 SimpleResourceString define_resource(
Jan Jongboom 3:ce2322965a27 505 const char* route,
janjongboom 1:75015f627e89 506 string v,
Jan Jongboom 3:ce2322965a27 507 void(*onUpdate)(string))
janjongboom 1:75015f627e89 508 {
Jan Jongboom 12:26810c6b58e1 509 Callback<void(string)> fp;
janjongboom 1:75015f627e89 510 fp.attach(onUpdate);
janjongboom 1:75015f627e89 511 return define_resource(route, v, M2MBase::GET_PUT_ALLOWED, true, fp);
janjongboom 1:75015f627e89 512 }
Jan Jongboom 3:ce2322965a27 513
janjongboom 1:75015f627e89 514 SimpleResourceInt define_resource(
Jan Jongboom 3:ce2322965a27 515 const char* route,
Jan Jongboom 3:ce2322965a27 516 int v,
Jan Jongboom 3:ce2322965a27 517 M2MBase::Operation opr = M2MBase::GET_PUT_ALLOWED,
janjongboom 1:75015f627e89 518 bool observable = true,
Jan Jongboom 12:26810c6b58e1 519 Callback<void(int)> onUpdate = NULL)
janjongboom 1:75015f627e89 520 {
Jan Jongboom 3:ce2322965a27 521 SimpleResourceInt* simpleResource = new SimpleResourceInt(this, route, onUpdate);
Jan Jongboom 3:ce2322965a27 522
Jan Jongboom 16:cb980bd39e32 523 char str[13];
Jan Jongboom 16:cb980bd39e32 524 sprintf(str, "%d", v);
Jan Jongboom 16:cb980bd39e32 525
Jan Jongboom 16:cb980bd39e32 526 bool res = define_resource_internal(route, string(str), opr, observable);
Jan Jongboom 3:ce2322965a27 527 if (!res) {
Jan Jongboom 3:ce2322965a27 528 printf("Error while creating %s\n", route);
Jan Jongboom 3:ce2322965a27 529 }
Jan Jongboom 3:ce2322965a27 530 else {
Jan Jongboom 3:ce2322965a27 531 register_update_callback(route, simpleResource);
Jan Jongboom 3:ce2322965a27 532 }
Jan Jongboom 3:ce2322965a27 533 return *simpleResource;
janjongboom 0:9fa3f3028773 534 }
Jan Jongboom 3:ce2322965a27 535
janjongboom 1:75015f627e89 536 SimpleResourceInt define_resource(
Jan Jongboom 3:ce2322965a27 537 const char* route,
Jan Jongboom 3:ce2322965a27 538 int v,
Jan Jongboom 3:ce2322965a27 539 M2MBase::Operation opr,
janjongboom 1:75015f627e89 540 bool observable,
Jan Jongboom 3:ce2322965a27 541 void(*onUpdate)(int))
janjongboom 1:75015f627e89 542 {
Jan Jongboom 12:26810c6b58e1 543 Callback<void(int)> fp;
janjongboom 1:75015f627e89 544 fp.attach(onUpdate);
janjongboom 1:75015f627e89 545 return define_resource(route, v, opr, observable, fp);
janjongboom 1:75015f627e89 546 }
Jan Jongboom 3:ce2322965a27 547
janjongboom 1:75015f627e89 548 SimpleResourceInt define_resource(
Jan Jongboom 3:ce2322965a27 549 const char* route,
janjongboom 1:75015f627e89 550 int v,
Jan Jongboom 12:26810c6b58e1 551 Callback<void(int)> onUpdate)
janjongboom 1:75015f627e89 552 {
janjongboom 1:75015f627e89 553 return define_resource(route, v, M2MBase::GET_PUT_ALLOWED, true, onUpdate);
janjongboom 1:75015f627e89 554 }
janjongboom 1:75015f627e89 555
janjongboom 1:75015f627e89 556 SimpleResourceInt define_resource(
Jan Jongboom 3:ce2322965a27 557 const char* route,
janjongboom 1:75015f627e89 558 int v,
Jan Jongboom 3:ce2322965a27 559 void(*onUpdate)(int))
janjongboom 1:75015f627e89 560 {
Jan Jongboom 12:26810c6b58e1 561 Callback<void(int)> fp;
janjongboom 1:75015f627e89 562 fp.attach(onUpdate);
janjongboom 1:75015f627e89 563 return define_resource(route, v, M2MBase::GET_PUT_ALLOWED, true, fp);
janjongboom 1:75015f627e89 564 }
janjongboom 0:9fa3f3028773 565 };
janjongboom 0:9fa3f3028773 566
Jan Jongboom 3:ce2322965a27 567 #endif // __SIMPLE_MBED_CLIENT_H__