Fork for workshops

Committer:
JimCarver
Date:
Fri Oct 12 21:22:49 2018 +0000
Revision:
0:6b753f761943
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JimCarver 0:6b753f761943 1 // ----------------------------------------------------------------------------
JimCarver 0:6b753f761943 2 // Copyright 2016-2017 ARM Ltd.
JimCarver 0:6b753f761943 3 //
JimCarver 0:6b753f761943 4 // SPDX-License-Identifier: Apache-2.0
JimCarver 0:6b753f761943 5 //
JimCarver 0:6b753f761943 6 // Licensed under the Apache License, Version 2.0 (the "License");
JimCarver 0:6b753f761943 7 // you may not use this file except in compliance with the License.
JimCarver 0:6b753f761943 8 // You may obtain a copy of the License at
JimCarver 0:6b753f761943 9 //
JimCarver 0:6b753f761943 10 // http://www.apache.org/licenses/LICENSE-2.0
JimCarver 0:6b753f761943 11 //
JimCarver 0:6b753f761943 12 // Unless required by applicable law or agreed to in writing, software
JimCarver 0:6b753f761943 13 // distributed under the License is distributed on an "AS IS" BASIS,
JimCarver 0:6b753f761943 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
JimCarver 0:6b753f761943 15 // See the License for the specific language governing permissions and
JimCarver 0:6b753f761943 16 // limitations under the License.
JimCarver 0:6b753f761943 17 // ----------------------------------------------------------------------------
JimCarver 0:6b753f761943 18
JimCarver 0:6b753f761943 19 #include "mbed-cloud-client/SimpleM2MResource.h"
JimCarver 0:6b753f761943 20 #include "mbed-trace/mbed_trace.h"
JimCarver 0:6b753f761943 21
JimCarver 0:6b753f761943 22 #include <ctype.h>
JimCarver 0:6b753f761943 23
JimCarver 0:6b753f761943 24 #include<stdio.h>
JimCarver 0:6b753f761943 25
JimCarver 0:6b753f761943 26 #define TRACE_GROUP "mClt"
JimCarver 0:6b753f761943 27
JimCarver 0:6b753f761943 28
JimCarver 0:6b753f761943 29 SimpleM2MResourceBase::SimpleM2MResourceBase()
JimCarver 0:6b753f761943 30 : _client(NULL), _route("")
JimCarver 0:6b753f761943 31 {
JimCarver 0:6b753f761943 32 tr_debug("SimpleM2MResourceBase::SimpleM2MResourceBase()");
JimCarver 0:6b753f761943 33 }
JimCarver 0:6b753f761943 34
JimCarver 0:6b753f761943 35 SimpleM2MResourceBase::SimpleM2MResourceBase(MbedCloudClient* client, string route)
JimCarver 0:6b753f761943 36 : _client(client),_route(route)
JimCarver 0:6b753f761943 37 {
JimCarver 0:6b753f761943 38 tr_debug("SimpleM2MResourceBase::SimpleM2MResourceBase(), resource name %s\r\n", _route.c_str());
JimCarver 0:6b753f761943 39 }
JimCarver 0:6b753f761943 40
JimCarver 0:6b753f761943 41 SimpleM2MResourceBase::~SimpleM2MResourceBase()
JimCarver 0:6b753f761943 42 {
JimCarver 0:6b753f761943 43 }
JimCarver 0:6b753f761943 44
JimCarver 0:6b753f761943 45 bool SimpleM2MResourceBase::define_resource_internal(std::string v, M2MBase::Operation opr, bool observable)
JimCarver 0:6b753f761943 46 {
JimCarver 0:6b753f761943 47 tr_debug("SimpleM2MResourceBase::define_resource_internal(), resource name %s!\r\n", _route.c_str());
JimCarver 0:6b753f761943 48
JimCarver 0:6b753f761943 49 vector<string> segments = parse_route(_route.c_str());
JimCarver 0:6b753f761943 50 if (segments.size() != 3) {
JimCarver 0:6b753f761943 51 tr_debug("[SimpleM2MResourceBase] [ERROR] define_resource_internal(), Route needs to have three segments, split by '/' (%s)\r\n", _route.c_str());
JimCarver 0:6b753f761943 52 return false;
JimCarver 0:6b753f761943 53 }
JimCarver 0:6b753f761943 54
JimCarver 0:6b753f761943 55 // segments[1] should be one digit and numeric
JimCarver 0:6b753f761943 56 if (!isdigit(segments.at(1).c_str()[0])) {
JimCarver 0:6b753f761943 57 tr_debug("[SimpleM2MResourceBase] [ERROR] define_resource_internal(), second route segment should be numeric, but was not (%s)\r\n", _route.c_str());
JimCarver 0:6b753f761943 58 return false;
JimCarver 0:6b753f761943 59 }
JimCarver 0:6b753f761943 60
JimCarver 0:6b753f761943 61 int inst_id = atoi(segments.at(1).c_str());
JimCarver 0:6b753f761943 62
JimCarver 0:6b753f761943 63 // Check if object exists
JimCarver 0:6b753f761943 64 M2MObject* obj;
JimCarver 0:6b753f761943 65 map<string,M2MObject*>::iterator obj_it = _client->_objects.find(segments[0]) ;
JimCarver 0:6b753f761943 66 if(obj_it != _client->_objects.end()) {
JimCarver 0:6b753f761943 67 tr_debug("Found object... %s\r\n", segments.at(0).c_str());
JimCarver 0:6b753f761943 68 obj = obj_it->second;
JimCarver 0:6b753f761943 69 } else {
JimCarver 0:6b753f761943 70 tr_debug("Create new object... %s\r\n", segments.at(0).c_str());
JimCarver 0:6b753f761943 71 obj = M2MInterfaceFactory::create_object(segments.at(0).c_str());
JimCarver 0:6b753f761943 72 if (!obj) {
JimCarver 0:6b753f761943 73 return false;
JimCarver 0:6b753f761943 74 }
JimCarver 0:6b753f761943 75 _client->_objects.insert(std::pair<string, M2MObject*>(segments.at(0), obj));
JimCarver 0:6b753f761943 76 }
JimCarver 0:6b753f761943 77
JimCarver 0:6b753f761943 78 // Check if object instance exists
JimCarver 0:6b753f761943 79 M2MObjectInstance* inst = obj->object_instance(inst_id);
JimCarver 0:6b753f761943 80 if(!inst) {
JimCarver 0:6b753f761943 81 tr_debug("Create new object instance... %s\r\n", segments.at(1).c_str());
JimCarver 0:6b753f761943 82 inst = obj->create_object_instance(inst_id);
JimCarver 0:6b753f761943 83 if(!inst) {
JimCarver 0:6b753f761943 84 return false;
JimCarver 0:6b753f761943 85 }
JimCarver 0:6b753f761943 86 }
JimCarver 0:6b753f761943 87
JimCarver 0:6b753f761943 88 // @todo check if the resource exists yet
JimCarver 0:6b753f761943 89 M2MResource* res = inst->resource(segments.at(2).c_str());
JimCarver 0:6b753f761943 90 if(!res) {
JimCarver 0:6b753f761943 91 res = inst->create_dynamic_resource(segments.at(2).c_str(), "",
JimCarver 0:6b753f761943 92 M2MResourceInstance::STRING, observable);
JimCarver 0:6b753f761943 93 if(!res) {
JimCarver 0:6b753f761943 94 return false;
JimCarver 0:6b753f761943 95 }
JimCarver 0:6b753f761943 96 res->set_operation(opr);
JimCarver 0:6b753f761943 97 res->set_value((uint8_t*)v.c_str(), v.length());
JimCarver 0:6b753f761943 98
JimCarver 0:6b753f761943 99 _client->_resources.insert(pair<string, M2MResource*>(_route, res));
JimCarver 0:6b753f761943 100 _client->register_update_callback(_route, this);
JimCarver 0:6b753f761943 101 }
JimCarver 0:6b753f761943 102
JimCarver 0:6b753f761943 103 return true;
JimCarver 0:6b753f761943 104 }
JimCarver 0:6b753f761943 105
JimCarver 0:6b753f761943 106 vector<string> SimpleM2MResourceBase::parse_route(const char* route)
JimCarver 0:6b753f761943 107 {
JimCarver 0:6b753f761943 108 string s(route);
JimCarver 0:6b753f761943 109 vector<string> v;
JimCarver 0:6b753f761943 110 std::size_t found = s.find_first_of("/");
JimCarver 0:6b753f761943 111
JimCarver 0:6b753f761943 112 while (found!=std::string::npos) {
JimCarver 0:6b753f761943 113 v.push_back(s.substr(0,found));
JimCarver 0:6b753f761943 114 s = s.substr(found+1);
JimCarver 0:6b753f761943 115 found=s.find_first_of("/");
JimCarver 0:6b753f761943 116 if(found == std::string::npos) {
JimCarver 0:6b753f761943 117 v.push_back(s);
JimCarver 0:6b753f761943 118 }
JimCarver 0:6b753f761943 119 }
JimCarver 0:6b753f761943 120 return v;
JimCarver 0:6b753f761943 121 }
JimCarver 0:6b753f761943 122
JimCarver 0:6b753f761943 123 string SimpleM2MResourceBase::get() const
JimCarver 0:6b753f761943 124 {
JimCarver 0:6b753f761943 125 tr_debug("SimpleM2MResourceBase::get() resource (%s)", _route.c_str());
JimCarver 0:6b753f761943 126 if (!_client->_resources.count(_route)) {
JimCarver 0:6b753f761943 127 tr_debug("[SimpleM2MResourceBase] [ERROR] No such route (%s)\r\n", _route.c_str());
JimCarver 0:6b753f761943 128 return string();
JimCarver 0:6b753f761943 129 }
JimCarver 0:6b753f761943 130
JimCarver 0:6b753f761943 131 // otherwise ask mbed Client...
JimCarver 0:6b753f761943 132 uint8_t* buffIn = NULL;
JimCarver 0:6b753f761943 133 uint32_t sizeIn;
JimCarver 0:6b753f761943 134 _client->_resources[_route]->get_value(buffIn, sizeIn);
JimCarver 0:6b753f761943 135
JimCarver 0:6b753f761943 136 string s((char*)buffIn, sizeIn);
JimCarver 0:6b753f761943 137 tr_debug("SimpleM2MResourceBase::get() resource value (%s)", s.c_str());
JimCarver 0:6b753f761943 138 free(buffIn);
JimCarver 0:6b753f761943 139 return s;
JimCarver 0:6b753f761943 140 }
JimCarver 0:6b753f761943 141
JimCarver 0:6b753f761943 142 bool SimpleM2MResourceBase::set(string v)
JimCarver 0:6b753f761943 143 {
JimCarver 0:6b753f761943 144 // Potentially set() happens in InterruptContext. That's not good.
JimCarver 0:6b753f761943 145 tr_debug("SimpleM2MResourceBase::set() resource (%s)", _route.c_str());
JimCarver 0:6b753f761943 146 if (!_client->_resources.count(_route)) {
JimCarver 0:6b753f761943 147 tr_debug("[SimpleM2MResourceBase] [ERROR] No such route (%s)\r\n", _route.c_str());
JimCarver 0:6b753f761943 148 return false;
JimCarver 0:6b753f761943 149 }
JimCarver 0:6b753f761943 150
JimCarver 0:6b753f761943 151 if (v.length() == 0) {
JimCarver 0:6b753f761943 152 _client->_resources[_route]->clear_value();
JimCarver 0:6b753f761943 153 }
JimCarver 0:6b753f761943 154 else {
JimCarver 0:6b753f761943 155 _client->_resources[_route]->set_value((uint8_t*)v.c_str(), v.length());
JimCarver 0:6b753f761943 156 }
JimCarver 0:6b753f761943 157
JimCarver 0:6b753f761943 158 return true;
JimCarver 0:6b753f761943 159 }
JimCarver 0:6b753f761943 160
JimCarver 0:6b753f761943 161 bool SimpleM2MResourceBase::set(const int& v)
JimCarver 0:6b753f761943 162 {
JimCarver 0:6b753f761943 163 char buffer[20];
JimCarver 0:6b753f761943 164 int size = sprintf(buffer,"%d",v);
JimCarver 0:6b753f761943 165 std::string stringified(buffer,size);
JimCarver 0:6b753f761943 166
JimCarver 0:6b753f761943 167 return set(stringified);
JimCarver 0:6b753f761943 168 }
JimCarver 0:6b753f761943 169
JimCarver 0:6b753f761943 170 bool SimpleM2MResourceBase::set_post_function(void(*fn)(void*))
JimCarver 0:6b753f761943 171 {
JimCarver 0:6b753f761943 172 //TODO: Check the resource exists with right operation being set or append the operation into it.
JimCarver 0:6b753f761943 173 M2MResource *resource = get_resource();
JimCarver 0:6b753f761943 174 if(!resource) {
JimCarver 0:6b753f761943 175 return false;
JimCarver 0:6b753f761943 176 }
JimCarver 0:6b753f761943 177 M2MBase::Operation op = resource->operation();
JimCarver 0:6b753f761943 178 op = (M2MBase::Operation)(op | M2MBase::POST_ALLOWED);
JimCarver 0:6b753f761943 179 resource->set_operation(op);
JimCarver 0:6b753f761943 180
JimCarver 0:6b753f761943 181 _client->_resources[_route]->set_execute_function(execute_callback_2(fn));
JimCarver 0:6b753f761943 182 return true;
JimCarver 0:6b753f761943 183 }
JimCarver 0:6b753f761943 184
JimCarver 0:6b753f761943 185 bool SimpleM2MResourceBase::set_post_function(execute_callback fn)
JimCarver 0:6b753f761943 186 {
JimCarver 0:6b753f761943 187 //TODO: Check the resource exists with right operation being set or append the operation into it.
JimCarver 0:6b753f761943 188 M2MResource *resource = get_resource();
JimCarver 0:6b753f761943 189 if(!resource) {
JimCarver 0:6b753f761943 190 return false;
JimCarver 0:6b753f761943 191 }
JimCarver 0:6b753f761943 192 M2MBase::Operation op = resource->operation();
JimCarver 0:6b753f761943 193 op = (M2MBase::Operation)(op | M2MBase::POST_ALLOWED);
JimCarver 0:6b753f761943 194 resource->set_operation(op);
JimCarver 0:6b753f761943 195
JimCarver 0:6b753f761943 196 // No clue why this is not working?! It works with class member, but not with static function...
JimCarver 0:6b753f761943 197 _client->_resources[_route]->set_execute_function(fn);
JimCarver 0:6b753f761943 198 return true;
JimCarver 0:6b753f761943 199 }
JimCarver 0:6b753f761943 200
JimCarver 0:6b753f761943 201 M2MResource* SimpleM2MResourceBase::get_resource()
JimCarver 0:6b753f761943 202 {
JimCarver 0:6b753f761943 203 if (!_client->_resources.count(_route)) {
JimCarver 0:6b753f761943 204 tr_debug("[SimpleM2MResourceBase] [ERROR] No such route (%s)\r\n", _route.c_str());
JimCarver 0:6b753f761943 205 return NULL;
JimCarver 0:6b753f761943 206 }
JimCarver 0:6b753f761943 207 return _client->_resources[_route];
JimCarver 0:6b753f761943 208 }
JimCarver 0:6b753f761943 209
JimCarver 0:6b753f761943 210 SimpleM2MResourceString::SimpleM2MResourceString(MbedCloudClient* client,
JimCarver 0:6b753f761943 211 const char* route,
JimCarver 0:6b753f761943 212 string v,
JimCarver 0:6b753f761943 213 M2MBase::Operation opr,
JimCarver 0:6b753f761943 214 bool observable,
JimCarver 0:6b753f761943 215 FP1<void, string> on_update)
JimCarver 0:6b753f761943 216 : SimpleM2MResourceBase(client,route),_on_update(on_update)
JimCarver 0:6b753f761943 217 {
JimCarver 0:6b753f761943 218 tr_debug("SimpleM2MResourceString::SimpleM2MResourceString() creating (%s)\r\n", route);
JimCarver 0:6b753f761943 219 define_resource_internal(v, opr, observable);
JimCarver 0:6b753f761943 220 }
JimCarver 0:6b753f761943 221
JimCarver 0:6b753f761943 222 SimpleM2MResourceString::SimpleM2MResourceString(MbedCloudClient* client,
JimCarver 0:6b753f761943 223 const char* route,
JimCarver 0:6b753f761943 224 string v,
JimCarver 0:6b753f761943 225 M2MBase::Operation opr,
JimCarver 0:6b753f761943 226 bool observable,
JimCarver 0:6b753f761943 227 void(*on_update)(string))
JimCarver 0:6b753f761943 228
JimCarver 0:6b753f761943 229 : SimpleM2MResourceBase(client,route)
JimCarver 0:6b753f761943 230 {
JimCarver 0:6b753f761943 231 tr_debug("SimpleM2MResourceString::SimpleM2MResourceString() overloaded creating (%s)\r\n", route);
JimCarver 0:6b753f761943 232 FP1<void, string> fp;
JimCarver 0:6b753f761943 233 fp.attach(on_update);
JimCarver 0:6b753f761943 234 _on_update = fp;
JimCarver 0:6b753f761943 235 define_resource_internal(v, opr, observable);
JimCarver 0:6b753f761943 236 }
JimCarver 0:6b753f761943 237
JimCarver 0:6b753f761943 238 SimpleM2MResourceString::~SimpleM2MResourceString()
JimCarver 0:6b753f761943 239 {
JimCarver 0:6b753f761943 240 }
JimCarver 0:6b753f761943 241
JimCarver 0:6b753f761943 242 string SimpleM2MResourceString::operator=(const string& new_value)
JimCarver 0:6b753f761943 243 {
JimCarver 0:6b753f761943 244 tr_debug("SimpleM2MResourceString::operator=()");
JimCarver 0:6b753f761943 245 set(new_value);
JimCarver 0:6b753f761943 246 return new_value;
JimCarver 0:6b753f761943 247 }
JimCarver 0:6b753f761943 248
JimCarver 0:6b753f761943 249 SimpleM2MResourceString::operator string() const
JimCarver 0:6b753f761943 250 {
JimCarver 0:6b753f761943 251 tr_debug("SimpleM2MResourceString::operator string()");
JimCarver 0:6b753f761943 252 string value = get();
JimCarver 0:6b753f761943 253 return value;
JimCarver 0:6b753f761943 254 }
JimCarver 0:6b753f761943 255
JimCarver 0:6b753f761943 256 void SimpleM2MResourceString::update()
JimCarver 0:6b753f761943 257 {
JimCarver 0:6b753f761943 258 string v = get();
JimCarver 0:6b753f761943 259 _on_update(v);
JimCarver 0:6b753f761943 260 }
JimCarver 0:6b753f761943 261
JimCarver 0:6b753f761943 262 SimpleM2MResourceInt::SimpleM2MResourceInt(MbedCloudClient* client,
JimCarver 0:6b753f761943 263 const char* route,
JimCarver 0:6b753f761943 264 int v,
JimCarver 0:6b753f761943 265 M2MBase::Operation opr,
JimCarver 0:6b753f761943 266 bool observable,
JimCarver 0:6b753f761943 267 FP1<void, int> on_update)
JimCarver 0:6b753f761943 268 : SimpleM2MResourceBase(client,route),_on_update(on_update)
JimCarver 0:6b753f761943 269 {
JimCarver 0:6b753f761943 270 tr_debug("SimpleM2MResourceInt::SimpleM2MResourceInt() creating (%s)\r\n", route);
JimCarver 0:6b753f761943 271 char buffer[20];
JimCarver 0:6b753f761943 272 int size = sprintf(buffer,"%d",v);
JimCarver 0:6b753f761943 273 std::string stringified(buffer,size);
JimCarver 0:6b753f761943 274 define_resource_internal(stringified, opr, observable);
JimCarver 0:6b753f761943 275 }
JimCarver 0:6b753f761943 276
JimCarver 0:6b753f761943 277 SimpleM2MResourceInt::SimpleM2MResourceInt(MbedCloudClient* client,
JimCarver 0:6b753f761943 278 const char* route,
JimCarver 0:6b753f761943 279 int v,
JimCarver 0:6b753f761943 280 M2MBase::Operation opr,
JimCarver 0:6b753f761943 281 bool observable,
JimCarver 0:6b753f761943 282 void(*on_update)(int))
JimCarver 0:6b753f761943 283 : SimpleM2MResourceBase(client,route)
JimCarver 0:6b753f761943 284 {
JimCarver 0:6b753f761943 285 tr_debug("SimpleM2MResourceInt::SimpleM2MResourceInt() overloaded creating (%s)\r\n", route);
JimCarver 0:6b753f761943 286 FP1<void, int> fp;
JimCarver 0:6b753f761943 287 fp.attach(on_update);
JimCarver 0:6b753f761943 288 _on_update = fp;
JimCarver 0:6b753f761943 289 char buffer[20];
JimCarver 0:6b753f761943 290 int size = sprintf(buffer,"%d",v);
JimCarver 0:6b753f761943 291 std::string stringified(buffer,size);
JimCarver 0:6b753f761943 292 define_resource_internal(stringified, opr, observable);
JimCarver 0:6b753f761943 293 }
JimCarver 0:6b753f761943 294
JimCarver 0:6b753f761943 295 SimpleM2MResourceInt::~SimpleM2MResourceInt()
JimCarver 0:6b753f761943 296 {
JimCarver 0:6b753f761943 297 }
JimCarver 0:6b753f761943 298
JimCarver 0:6b753f761943 299 int SimpleM2MResourceInt::operator=(int new_value)
JimCarver 0:6b753f761943 300 {
JimCarver 0:6b753f761943 301 set(new_value);
JimCarver 0:6b753f761943 302 return new_value;
JimCarver 0:6b753f761943 303 }
JimCarver 0:6b753f761943 304
JimCarver 0:6b753f761943 305 SimpleM2MResourceInt::operator int() const
JimCarver 0:6b753f761943 306 {
JimCarver 0:6b753f761943 307 string v = get();
JimCarver 0:6b753f761943 308 if (v.empty()) return 0;
JimCarver 0:6b753f761943 309
JimCarver 0:6b753f761943 310 return atoi((const char*)v.c_str());
JimCarver 0:6b753f761943 311 }
JimCarver 0:6b753f761943 312
JimCarver 0:6b753f761943 313 void SimpleM2MResourceInt::update()
JimCarver 0:6b753f761943 314 {
JimCarver 0:6b753f761943 315 string v = get();
JimCarver 0:6b753f761943 316 if (v.empty()) {
JimCarver 0:6b753f761943 317 _on_update(0);
JimCarver 0:6b753f761943 318 } else {
JimCarver 0:6b753f761943 319 _on_update(atoi((const char*)v.c_str()));
JimCarver 0:6b753f761943 320 }
JimCarver 0:6b753f761943 321 }