Toyomasa Watarai / simple-mbed-cloud-client

Dependents:  

Committer:
MACRUM
Date:
Mon Jul 02 06:30:39 2018 +0000
Revision:
0:276e7a263c35
Initial commit

Who changed what in which revision?

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