Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
SimpleM2MResource.cpp
00001 // ---------------------------------------------------------------------------- 00002 // Copyright 2016-2017 ARM Ltd. 00003 // 00004 // SPDX-License-Identifier: Apache-2.0 00005 // 00006 // Licensed under the Apache License, Version 2.0 (the "License"); 00007 // you may not use this file except in compliance with the License. 00008 // You may obtain a copy of the License at 00009 // 00010 // http://www.apache.org/licenses/LICENSE-2.0 00011 // 00012 // Unless required by applicable law or agreed to in writing, software 00013 // distributed under the License is distributed on an "AS IS" BASIS, 00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 // See the License for the specific language governing permissions and 00016 // limitations under the License. 00017 // ---------------------------------------------------------------------------- 00018 00019 #include "mbed-cloud-client/SimpleM2MResource.h" 00020 #include "mbed-trace/mbed_trace.h" 00021 00022 #include <ctype.h> 00023 00024 #include<stdio.h> 00025 00026 #define TRACE_GROUP "mClt" 00027 00028 00029 SimpleM2MResourceBase::SimpleM2MResourceBase() 00030 : _client(NULL), _route("") 00031 { 00032 tr_debug("SimpleM2MResourceBase::SimpleM2MResourceBase()"); 00033 } 00034 00035 SimpleM2MResourceBase::SimpleM2MResourceBase(MbedCloudClient* client, string route) 00036 : _client(client),_route(route) 00037 { 00038 tr_debug("SimpleM2MResourceBase::SimpleM2MResourceBase(), resource name %s\r\n", _route.c_str()); 00039 } 00040 00041 SimpleM2MResourceBase::~SimpleM2MResourceBase() 00042 { 00043 } 00044 00045 bool SimpleM2MResourceBase::define_resource_internal(std::string v, M2MBase::Operation opr, bool observable) 00046 { 00047 tr_debug("SimpleM2MResourceBase::define_resource_internal(), resource name %s!\r\n", _route.c_str()); 00048 00049 vector<string> segments = parse_route(_route.c_str()); 00050 if (segments.size() != 3) { 00051 tr_debug("[SimpleM2MResourceBase] [ERROR] define_resource_internal(), Route needs to have three segments, split by '/' (%s)\r\n", _route.c_str()); 00052 return false; 00053 } 00054 00055 // segments[1] should be one digit and numeric 00056 if (!isdigit(segments.at(1).c_str()[0])) { 00057 tr_debug("[SimpleM2MResourceBase] [ERROR] define_resource_internal(), second route segment should be numeric, but was not (%s)\r\n", _route.c_str()); 00058 return false; 00059 } 00060 00061 int inst_id = atoi(segments.at(1).c_str()); 00062 00063 // Check if object exists 00064 M2MObject* obj; 00065 map<string,M2MObject*>::iterator obj_it = _client->_objects.find(segments[0]) ; 00066 if(obj_it != _client->_objects.end()) { 00067 tr_debug("Found object... %s\r\n", segments.at(0).c_str()); 00068 obj = obj_it->second; 00069 } else { 00070 tr_debug("Create new object... %s\r\n", segments.at(0).c_str()); 00071 obj = M2MInterfaceFactory::create_object(segments.at(0).c_str()); 00072 if (!obj) { 00073 return false; 00074 } 00075 _client->_objects.insert(std::pair<string, M2MObject*>(segments.at(0), obj)); 00076 } 00077 00078 // Check if object instance exists 00079 M2MObjectInstance* inst = obj->object_instance(inst_id); 00080 if(!inst) { 00081 tr_debug("Create new object instance... %s\r\n", segments.at(1).c_str()); 00082 inst = obj->create_object_instance(inst_id); 00083 if(!inst) { 00084 return false; 00085 } 00086 } 00087 00088 // @todo check if the resource exists yet 00089 M2MResource* res = inst->resource(segments.at(2).c_str()); 00090 if(!res) { 00091 res = inst->create_dynamic_resource(segments.at(2).c_str(), "", 00092 M2MResourceInstance::STRING, observable); 00093 if(!res) { 00094 return false; 00095 } 00096 res->set_operation(opr); 00097 res->set_value((uint8_t*)v.c_str(), v.length()); 00098 00099 _client->_resources.insert(pair<string, M2MResource*>(_route, res)); 00100 _client->register_update_callback(_route, this); 00101 } 00102 00103 return true; 00104 } 00105 00106 vector<string> SimpleM2MResourceBase::parse_route(const char* route) 00107 { 00108 string s(route); 00109 vector<string> v; 00110 std::size_t found = s.find_first_of("/"); 00111 00112 while (found!=std::string::npos) { 00113 v.push_back(s.substr(0,found)); 00114 s = s.substr(found+1); 00115 found=s.find_first_of("/"); 00116 if(found == std::string::npos) { 00117 v.push_back(s); 00118 } 00119 } 00120 return v; 00121 } 00122 00123 string SimpleM2MResourceBase::get() const 00124 { 00125 tr_debug("SimpleM2MResourceBase::get() resource (%s)", _route.c_str()); 00126 if (!_client->_resources.count(_route)) { 00127 tr_debug("[SimpleM2MResourceBase] [ERROR] No such route (%s)\r\n", _route.c_str()); 00128 return string(); 00129 } 00130 00131 // otherwise ask mbed Client... 00132 uint8_t* buffIn = NULL; 00133 uint32_t sizeIn; 00134 _client->_resources[_route]->get_value(buffIn, sizeIn); 00135 00136 string s((char*)buffIn, sizeIn); 00137 tr_debug("SimpleM2MResourceBase::get() resource value (%s)", s.c_str()); 00138 free(buffIn); 00139 return s; 00140 } 00141 00142 bool SimpleM2MResourceBase::set(string v) 00143 { 00144 // Potentially set() happens in InterruptContext. That's not good. 00145 tr_debug("SimpleM2MResourceBase::set() resource (%s)", _route.c_str()); 00146 if (!_client->_resources.count(_route)) { 00147 tr_debug("[SimpleM2MResourceBase] [ERROR] No such route (%s)\r\n", _route.c_str()); 00148 return false; 00149 } 00150 00151 if (v.length() == 0) { 00152 _client->_resources[_route]->clear_value(); 00153 } 00154 else { 00155 _client->_resources[_route]->set_value((uint8_t*)v.c_str(), v.length()); 00156 } 00157 00158 return true; 00159 } 00160 00161 bool SimpleM2MResourceBase::set(const int& v) 00162 { 00163 char buffer[20]; 00164 int size = sprintf(buffer,"%d",v); 00165 std::string stringified(buffer,size); 00166 00167 return set(stringified); 00168 } 00169 00170 bool SimpleM2MResourceBase::set_post_function(void(*fn)(void*)) 00171 { 00172 //TODO: Check the resource exists with right operation being set or append the operation into it. 00173 M2MResource *resource = get_resource(); 00174 if(!resource) { 00175 return false; 00176 } 00177 M2MBase::Operation op = resource->operation(); 00178 op = (M2MBase::Operation)(op | M2MBase::POST_ALLOWED); 00179 resource->set_operation(op); 00180 00181 _client->_resources[_route]->set_execute_function(execute_callback_2(fn)); 00182 return true; 00183 } 00184 00185 bool SimpleM2MResourceBase::set_post_function(execute_callback fn) 00186 { 00187 //TODO: Check the resource exists with right operation being set or append the operation into it. 00188 M2MResource *resource = get_resource(); 00189 if(!resource) { 00190 return false; 00191 } 00192 M2MBase::Operation op = resource->operation(); 00193 op = (M2MBase::Operation)(op | M2MBase::POST_ALLOWED); 00194 resource->set_operation(op); 00195 00196 // No clue why this is not working?! It works with class member, but not with static function... 00197 _client->_resources[_route]->set_execute_function(fn); 00198 return true; 00199 } 00200 00201 M2MResource* SimpleM2MResourceBase::get_resource() 00202 { 00203 if (!_client->_resources.count(_route)) { 00204 tr_debug("[SimpleM2MResourceBase] [ERROR] No such route (%s)\r\n", _route.c_str()); 00205 return NULL; 00206 } 00207 return _client->_resources[_route]; 00208 } 00209 00210 SimpleM2MResourceString::SimpleM2MResourceString(MbedCloudClient* client, 00211 const char* route, 00212 string v, 00213 M2MBase::Operation opr, 00214 bool observable, 00215 FP1<void, string> on_update) 00216 : SimpleM2MResourceBase(client,route),_on_update(on_update) 00217 { 00218 tr_debug("SimpleM2MResourceString::SimpleM2MResourceString() creating (%s)\r\n", route); 00219 define_resource_internal(v, opr, observable); 00220 } 00221 00222 SimpleM2MResourceString::SimpleM2MResourceString(MbedCloudClient* client, 00223 const char* route, 00224 string v, 00225 M2MBase::Operation opr, 00226 bool observable, 00227 void(*on_update)(string)) 00228 00229 : SimpleM2MResourceBase(client,route) 00230 { 00231 tr_debug("SimpleM2MResourceString::SimpleM2MResourceString() overloaded creating (%s)\r\n", route); 00232 FP1<void, string> fp; 00233 fp.attach(on_update); 00234 _on_update = fp; 00235 define_resource_internal(v, opr, observable); 00236 } 00237 00238 SimpleM2MResourceString::~SimpleM2MResourceString() 00239 { 00240 } 00241 00242 string SimpleM2MResourceString::operator=(const string& new_value) 00243 { 00244 tr_debug("SimpleM2MResourceString::operator=()"); 00245 set(new_value); 00246 return new_value; 00247 } 00248 00249 SimpleM2MResourceString::operator string() const 00250 { 00251 tr_debug("SimpleM2MResourceString::operator string()"); 00252 string value = get(); 00253 return value; 00254 } 00255 00256 void SimpleM2MResourceString::update() 00257 { 00258 string v = get(); 00259 _on_update(v); 00260 } 00261 00262 SimpleM2MResourceInt::SimpleM2MResourceInt(MbedCloudClient* client, 00263 const char* route, 00264 int v, 00265 M2MBase::Operation opr, 00266 bool observable, 00267 FP1<void, int> on_update) 00268 : SimpleM2MResourceBase(client,route),_on_update(on_update) 00269 { 00270 tr_debug("SimpleM2MResourceInt::SimpleM2MResourceInt() creating (%s)\r\n", route); 00271 char buffer[20]; 00272 int size = sprintf(buffer,"%d",v); 00273 std::string stringified(buffer,size); 00274 define_resource_internal(stringified, opr, observable); 00275 } 00276 00277 SimpleM2MResourceInt::SimpleM2MResourceInt(MbedCloudClient* client, 00278 const char* route, 00279 int v, 00280 M2MBase::Operation opr, 00281 bool observable, 00282 void(*on_update)(int)) 00283 : SimpleM2MResourceBase(client,route) 00284 { 00285 tr_debug("SimpleM2MResourceInt::SimpleM2MResourceInt() overloaded creating (%s)\r\n", route); 00286 FP1<void, int> fp; 00287 fp.attach(on_update); 00288 _on_update = fp; 00289 char buffer[20]; 00290 int size = sprintf(buffer,"%d",v); 00291 std::string stringified(buffer,size); 00292 define_resource_internal(stringified, opr, observable); 00293 } 00294 00295 SimpleM2MResourceInt::~SimpleM2MResourceInt() 00296 { 00297 } 00298 00299 int SimpleM2MResourceInt::operator=(int new_value) 00300 { 00301 set(new_value); 00302 return new_value; 00303 } 00304 00305 SimpleM2MResourceInt::operator int() const 00306 { 00307 string v = get(); 00308 if (v.empty()) return 0; 00309 00310 return atoi((const char*)v.c_str()); 00311 } 00312 00313 void SimpleM2MResourceInt::update() 00314 { 00315 string v = get(); 00316 if (v.empty()) { 00317 _on_update(0); 00318 } else { 00319 _on_update(atoi((const char*)v.c_str())); 00320 } 00321 }
Generated on Tue Jul 12 2022 19:01:37 by 1.7.2