Committer:
leothedragon
Date:
Sun Apr 18 15:20:23 2021 +0000
Revision:
0:25fa8795676b
DS

Who changed what in which revision?

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