Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: AsciiFont DisplayApp GR-PEACH_video LCD_shield_config LWIPBP3595Interface_STA_for_mbed-os USBDevice
DynamicResource.cpp
00001 /** 00002 * @file DynamicResource.cpp 00003 * @brief mbed CoAP Endpoint Dynamic Resource class 00004 * @author Doug Anson/Chris Paola 00005 * @version 1.0 00006 * @see 00007 * 00008 * Copyright (c) 2014 00009 * 00010 * Licensed under the Apache License, Version 2.0 (the "License"); 00011 * you may not use this file except in compliance with the License. 00012 * You may obtain a copy of the License at 00013 * 00014 * http://www.apache.org/licenses/LICENSE-2.0 00015 * 00016 * Unless required by applicable law or agreed to in writing, software 00017 * distributed under the License is distributed on an "AS IS" BASIS, 00018 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00019 * See the License for the specific language governing permissions and 00020 * limitations under the License. 00021 */ 00022 00023 // Class support 00024 #include "mbed-connector-interface/DynamicResource.h" 00025 00026 // ResourceObserver help 00027 #include "mbed-connector-interface/ResourceObserver.h" 00028 00029 // Options enablement 00030 #include "mbed-connector-interface/Options.h" 00031 00032 // Endpoint 00033 #include "mbed-connector-interface/ConnectorEndpoint.h" 00034 00035 // GET option that can be used to Start/Stop Observations... 00036 #define START_OBS 0 00037 #define STOP_OBS 1 00038 00039 // MaxAge support for each DynamicResource 00040 #define DEFAULT_MAXAGE 60 00041 00042 // ContentFormat defaults for each DynamicResource 00043 #define DEFAULT_CONTENT_FORMAT 0 00044 00045 // default constructor 00046 DynamicResource::DynamicResource(const Logger *logger,const char *obj_name,const char *res_name,const char *res_type,uint8_t res_mask,const bool observable,const ResourceType type) : Resource<string>(logger,string(obj_name),string(res_name),string("")) 00047 { 00048 this->m_res_type = string(res_type); 00049 this->m_type = type; 00050 this->m_observable = observable; 00051 this->m_res_mask = res_mask; 00052 this->m_obs_number = 0; 00053 this->m_data_wrapper = NULL; 00054 this->m_observer = NULL; 00055 this->m_maxage = DEFAULT_MAXAGE; 00056 this->m_content_format = DEFAULT_CONTENT_FORMAT; 00057 this->m_ep = NULL; 00058 this->m_res = NULL; 00059 } 00060 00061 // constructor (input initial value) 00062 DynamicResource::DynamicResource(const Logger *logger,const char *obj_name,const char *res_name,const char *res_type,const string value,uint8_t res_mask,const bool observable,const ResourceType type) : Resource<string>(logger,string(obj_name),string(res_name),value) 00063 { 00064 this->m_res_type = string(res_type); 00065 this->m_type = type; 00066 this->m_observable = observable; 00067 this->m_res_mask = res_mask; 00068 this->m_obs_number = 0; 00069 this->m_data_wrapper = NULL; 00070 this->m_observer = NULL; 00071 this->m_maxage = DEFAULT_MAXAGE; 00072 this->m_content_format = DEFAULT_CONTENT_FORMAT; 00073 this->m_ep = NULL; 00074 this->m_res = NULL; 00075 } 00076 00077 // constructor (strings) 00078 DynamicResource::DynamicResource(const Logger *logger,const string obj_name,const string res_name,const string res_type,const string value,uint8_t res_mask,const bool observable,const ResourceType type) : Resource<string>(logger,obj_name,res_name,value) 00079 { 00080 this->m_res_type = res_type; 00081 this->m_type = type; 00082 this->m_observable = observable; 00083 this->m_res_mask = res_mask; 00084 this->m_obs_number = 0; 00085 this->m_data_wrapper = NULL; 00086 this->m_observer = NULL; 00087 this->m_maxage = DEFAULT_MAXAGE; 00088 this->m_content_format = DEFAULT_CONTENT_FORMAT; 00089 this->m_ep = NULL; 00090 this->m_res = NULL; 00091 } 00092 00093 // copy constructor 00094 DynamicResource::DynamicResource(const DynamicResource &resource) : Resource<string>((const Resource<string> &)resource) 00095 { 00096 this->m_res_type = resource.m_res_type; 00097 this->m_type = resource.m_type; 00098 this->m_observable = resource.m_observable; 00099 this->m_res_mask = resource.m_res_mask; 00100 this->m_obs_number = resource.m_obs_number; 00101 this->m_data_wrapper = resource.m_data_wrapper; 00102 this->m_observer = resource.m_observer; 00103 this->m_maxage = resource.m_maxage; 00104 this->m_content_format = resource.m_content_format; 00105 this->m_ep = resource.m_ep; 00106 this->m_res = resource.m_res; 00107 } 00108 00109 // destructor 00110 DynamicResource::~DynamicResource() { 00111 } 00112 00113 // bind CoAP Resource... 00114 void DynamicResource::bind(void *ep) { 00115 if (ep != NULL) { 00116 // cast 00117 Connector::Endpoint *endpoint = (Connector::Endpoint *)ep; 00118 00119 // get our ObjectInstanceManager 00120 ObjectInstanceManager *oim = endpoint->getObjectInstanceManager(); 00121 00122 // Create our Resource 00123 this->m_res = (M2MResource *)oim->createDynamicResourceInstance((char *)this->getObjName().c_str(),(char *)this->getResName().c_str(),(char *)this->m_res_type.c_str(),(int)this->m_type,this->m_observable); 00124 if (this->m_res != NULL) { 00125 // Record our Instance Number 00126 this->setInstanceNumber(oim->getLastCreatedInstanceNumber()); 00127 00128 // perform an initial get() to initialize our data value 00129 this->setValue(this->get()); 00130 00131 // now record the data value 00132 if (this->getDataWrapper() != NULL) { 00133 // wrap the data... 00134 this->getDataWrapper()->wrap((uint8_t *)this->getValue().c_str(),(int)this->getValue().size()); 00135 this->m_res->set_operation((M2MBase::Operation)this->m_res_mask); 00136 this->m_res->set_value( this->getDataWrapper()->get(),(uint8_t)this->getDataWrapper()->length()); 00137 this->logger()->logging("%s: [%s] value: [%s] bound (observable: %d)",this->m_res_type.c_str(),this->getFullName().c_str(),this->getDataWrapper()->get(),this->m_observable); 00138 } 00139 else { 00140 // do not wrap the data... 00141 this->m_res->set_operation((M2MBase::Operation)this->m_res_mask); 00142 this->m_res->set_value((uint8_t *)this->getValue().c_str(),(uint8_t)this->getValue().size()); 00143 this->logger()->logging("%s: [%s] value: [%s] bound (observable: %d)",this->m_res_type.c_str(),this->getFullName().c_str(),this->getValue().c_str(),this->m_observable); 00144 } 00145 00146 // set our endpoint instance 00147 this->m_ep = (void *)ep; 00148 00149 // For POST-enabled RESOURCES (only...), we must add a callback 00150 if ((this->m_res_mask & M2MBase::POST_ALLOWED) != 0) { 00151 // add a callback for the execute function...we will just direct through process()... 00152 //this->logger()->logging("DynamicResource::bind(): Setting up POST execute callback function"); 00153 this->m_res->set_execute_function(execute_callback(this, &DynamicResource::process_resource_post)); 00154 } 00155 } 00156 } 00157 else { 00158 // no instance pointer to our endpoint 00159 this->logger()->logging("%s: NULL endpoint instance pointer in bind() request...",this->m_res_type.c_str()); 00160 } 00161 } 00162 00163 // get our M2MBase representation 00164 M2MResource *DynamicResource::getResource() { 00165 return this->m_res; 00166 } 00167 00168 // process inbound mbed-client POST message for a Resource 00169 void DynamicResource::process_resource_post(void *args) { 00170 // just call process() for POST and Resources... 00171 //this->logger()->logging("DynamicResource::process_resource_post(): calling process(POST)"); 00172 (void)this->process(M2MBase::POST_ALLOWED,this->m_res->base_type(),args); 00173 } 00174 00175 // process inbound mbed-client message 00176 uint8_t DynamicResource::process(M2MBase::Operation op,M2MBase::BaseType type,void *args) { 00177 #if defined (HAS_EXECUTE_PARAMS) 00178 M2MResource::M2MExecuteParameter* param = NULL; 00179 00180 // cast args if present... 00181 if (args != NULL) { 00182 param = (M2MResource::M2MExecuteParameter*)args; 00183 } 00184 #endif 00185 // DEBUG 00186 //this->logger()->logging("in %s::process() Operation=0x0%x Type=%x%x",this->m_res_type.c_str(),op,type); 00187 00188 // PUT() check 00189 if ((op & M2MBase::PUT_ALLOWED) != 0) { 00190 string value = this->coapDataToString(this->m_res->value(),this->m_res->value_length()); 00191 this->logger()->logging("%s: put(%d) [%s]=[%s] called.",this->m_res_type.c_str(),type,this->getFullName().c_str(),value.c_str()); 00192 this->put(value.c_str()); 00193 return 0; 00194 } 00195 00196 #if defined (HAS_EXECUTE_PARAMS) 00197 // POST() check 00198 if ((op & M2MBase::POST_ALLOWED) != 0) { 00199 string value; 00200 if (param != NULL) { 00201 // use parameters 00202 String object_name = param->get_argument_object_name(); 00203 int instance_id = (int)param->get_argument_object_instance_id(); 00204 String resource_name = param->get_argument_resource_name(); 00205 value = this->coapDataToString(param->get_argument_value(),param->get_argument_value_length()); 00206 this->logger()->logging("%s: post(%d) [%s/%d/%s]=[%s]) called.",this->m_res_type.c_str(),type,object_name.c_str(),instance_id,resource_name.c_str(),value.c_str()); 00207 } 00208 else { 00209 // use the resource value itself 00210 value = this->coapDataToString(this->m_res->value(),this->m_res->value_length()); 00211 this->logger()->logging("%s: post(%d) [%s]=[%s] called.",this->m_res_type.c_str(),type,this->getFullName().c_str(),value.c_str()); 00212 } 00213 00214 // invoke 00215 this->post(args); 00216 return 0; 00217 } 00218 #else 00219 // POST() check 00220 if ((op & M2MBase::POST_ALLOWED) != 0) { 00221 if (args != NULL) { 00222 this->logger()->logging("%s: post(%d) [%s]=[%s] called.",this->m_res_type.c_str(),type,this->getFullName().c_str(),(char *)args); 00223 this->post(args); 00224 } 00225 else { 00226 string value = this->coapDataToString(this->m_res->value(),this->m_res->value_length()); 00227 this->logger()->logging("%s: post(%d) [%s]=[%s] called.",this->m_res_type.c_str(),type,this->getFullName().c_str(),value.c_str()); 00228 this->post((void *)value.c_str()); 00229 } 00230 return 0; 00231 } 00232 #endif 00233 00234 #if defined (HAS_EXECUTE_PARAMS) 00235 // DELETE() check 00236 if ((op & M2MBase::DELETE_ALLOWED) != 0) { 00237 if (param != NULL) { 00238 // use parameters 00239 String object_name = param->get_argument_object_name(); 00240 int instance_id = (int)param->get_argument_object_instance_id(); 00241 String resource_name = param->get_argument_resource_name(); 00242 string value = this->coapDataToString(param->get_argument_value(),param->get_argument_value_length()); 00243 this->logger()->logging("%s: delete(%d) [%s/%d/%s]=[%s]) called.",this->m_res_type.c_str(),type,object_name.c_str(),instance_id,resource_name.c_str(),value.c_str()); 00244 } 00245 else { 00246 // use the resource value itself 00247 string value = this->coapDataToString(this->m_res->value(),this->m_res->value_length()); 00248 this->logger()->logging("%s: delete(%d) [%s]=[%s] called.",this->m_res_type.c_str(),type,this->getFullName().c_str(),value.c_str()); 00249 } 00250 00251 // invoke 00252 this->del(args); 00253 return 0; 00254 } 00255 #else 00256 // DELETE() check 00257 if ((op & M2MBase::DELETE_ALLOWED) != 0) { 00258 if (args != NULL) { 00259 this->logger()->logging("%s: delete(%d) [%s]=[%s] called.",this->m_res_type.c_str(),type,this->getFullName().c_str(),(char *)args); 00260 this->del(args); 00261 } 00262 else { 00263 string value = this->coapDataToString(this->m_res->value(),this->m_res->value_length()); 00264 this->logger()->logging("%s: delete(%d) [%s]=[%s] called.",this->m_res_type.c_str(),type,this->getFullName().c_str(),value.c_str()); 00265 this->del((void *)value.c_str()); 00266 } 00267 } 00268 #endif 00269 00270 // unknown type... 00271 this->logger()->logging("%s: Unknown Operation (0x%x) for [%s]=[%s]... FAILED.",op,this->m_res_type.c_str(),this->getFullName().c_str(),this->m_res->value()); 00272 return 1; 00273 } 00274 00275 // send the notification 00276 int DynamicResource::notify(const string data) { 00277 return this->notify((uint8_t *)data.c_str(),(int)data.length()); 00278 } 00279 00280 // send the notification 00281 int DynamicResource::notify(uint8_t *data,int data_length) { 00282 uint8_t *notify_data = NULL; 00283 int notify_data_length = 0; 00284 int status = 0; 00285 00286 // convert the string from the GET to something suitable for CoAP payloads 00287 if (this->getDataWrapper() != NULL) { 00288 // wrap the data... 00289 this->getDataWrapper()->wrap((uint8_t *)data,data_length); 00290 00291 // announce (after wrap) 00292 //this->logger()->logging("Notify payload [%s]...",this->getDataWrapper()->get()); 00293 00294 // fill notify 00295 notify_data_length = this->getDataWrapper()->length(); 00296 notify_data = this->getDataWrapper()->get(); 00297 } 00298 else { 00299 // announce (no wrap) 00300 //this->logger()->logging("Notify payload [%s]...",data); 00301 00302 // do not wrap the data... 00303 notify_data_length = data_length; 00304 notify_data = data; 00305 } 00306 00307 // update the resource 00308 this->m_res->set_value((uint8_t *)notify_data,(uint8_t)notify_data_length); 00309 00310 // return our status 00311 return status; 00312 } 00313 00314 // default GET (does nothing) 00315 string DynamicResource::get() 00316 { 00317 // not used by default 00318 //this->logger()->logging("DynamicResource::get() invoked (NOOP)"); 00319 return string(""); 00320 } 00321 00322 // default PUT (does nothing) 00323 void DynamicResource::put(const string /* value */) 00324 { 00325 // not used by default 00326 //this->logger()->logging("DynamicResource::put() invoked (NOOP)"); 00327 } 00328 00329 // default POST (does nothing) 00330 void DynamicResource::post(void * /* args */) 00331 { 00332 // not used by default 00333 //this->logger()->logging("DynamicResource::post() invoked (NOOP)"); 00334 } 00335 00336 // default DELETE (does nothing) 00337 void DynamicResource::del(void * /* args */) 00338 { 00339 // not used by default 00340 //this->logger()->logging("DynamicResource::del() invoked (NOOP)"); 00341 } 00342 00343 // default observe behavior 00344 void DynamicResource::observe() { 00345 if (this->m_observable == true && this->isRegistered() == true) { 00346 this->notify(this->get()); 00347 } 00348 } 00349 00350 // set the observer pointer 00351 void DynamicResource::setObserver(void *observer) { 00352 this->m_observer = observer; 00353 } 00354 00355 // set the content-format in responses 00356 void DynamicResource::setContentFormat(uint8_t content_format) { 00357 this->m_content_format = content_format; 00358 } 00359 00360 // set the max-age of responses 00361 void DynamicResource::setMaxAge(uint8_t maxage) { 00362 this->m_maxage = maxage; 00363 } 00364 00365 // convert the CoAP data pointer to a string type 00366 string DynamicResource::coapDataToString(uint8_t *coap_data_ptr,int coap_data_ptr_length) 00367 { 00368 if (coap_data_ptr != NULL && coap_data_ptr_length > 0) { 00369 if (this->getDataWrapper() != NULL) { 00370 // unwrap the data... 00371 this->getDataWrapper()->unwrap(coap_data_ptr,coap_data_ptr_length); 00372 char *buf = (char *)this->getDataWrapper()->get(); // assumes data is null terminated in DataWrapper... 00373 return string(buf); 00374 } 00375 else { 00376 // no unwrap of the data... 00377 char buf[MAX_VALUE_BUFFER_LENGTH+1]; 00378 memset(buf,0,MAX_VALUE_BUFFER_LENGTH+1); 00379 memcpy(buf,(char *)coap_data_ptr,coap_data_ptr_length); 00380 return string(buf); 00381 } 00382 } 00383 return string(""); 00384 } 00385 00386 // convert the CoAP data pointer to an integer type 00387 int DynamicResource::coapDataToInteger(uint8_t *coap_data_ptr,int coap_data_ptr_length) { 00388 int value = 0; 00389 if (coap_data_ptr != NULL && coap_data_ptr_length > 0) { 00390 if (this->getDataWrapper() != NULL) { 00391 // unwrap the data... 00392 this->getDataWrapper()->unwrap(coap_data_ptr,coap_data_ptr_length); 00393 //value = (int)this->getDataWrapper()->get(); // assumes data is null terminated in DataWrapper... 00394 } 00395 else { 00396 // no unwrap of the data... 00397 //value = (int)coap_data_ptr; 00398 } 00399 } 00400 return value; 00401 } 00402 00403 // convert the CoAP data pointer to a float type 00404 float DynamicResource::coapDataToFloat(uint8_t *coap_data_ptr,int coap_data_ptr_length) { 00405 float value = 0.0; 00406 if (coap_data_ptr != NULL && coap_data_ptr_length > 0) { 00407 if (this->getDataWrapper() != NULL) { 00408 // unwrap the data... 00409 this->getDataWrapper()->unwrap(coap_data_ptr,coap_data_ptr_length); 00410 //value = (float)this->getDataWrapper()->get(); // assumes data is null terminated in DataWrapper... 00411 } 00412 else { 00413 // no unwrap of the data... 00414 //value = (float)coap_data_ptr; 00415 } 00416 } 00417 return value; 00418 } 00419 00420 // convert the CoAP data pointer to an opaque type 00421 void *DynamicResource::coapDataToOpaque(uint8_t *coap_data_ptr,int coap_data_ptr_length) { 00422 if (coap_data_ptr != NULL && coap_data_ptr_length > 0) { 00423 if (this->getDataWrapper() != NULL) { 00424 // unwrap the data... 00425 this->getDataWrapper()->unwrap(coap_data_ptr,coap_data_ptr_length); 00426 char *buf = (char *)this->getDataWrapper()->get(); // assumes data is null terminated in DataWrapper... 00427 return (void *)buf; 00428 } 00429 } 00430 return (void *)coap_data_ptr; 00431 } 00432 00433 // Determine if we are connected or not 00434 bool DynamicResource::isConnected() { 00435 bool is_connected = false; 00436 00437 // get our Endpoint 00438 Connector::Endpoint *ep = (Connector::Endpoint *)this->m_endpoint; 00439 if (ep != NULL) { 00440 is_connected = ep->isConnected(); 00441 if (is_connected) { 00442 //this->logger()->logging("DynamicResource::isConnected = true"); 00443 } 00444 else { 00445 //this->logger()->logging("DynamicResource::isConnected = false"); 00446 } 00447 } 00448 else { 00449 this->logger()->logging("DynamicResource::isConnected = false (no endpoint)"); 00450 } 00451 00452 // return our endpoint connection state 00453 return is_connected; 00454 } 00455 00456 // Determine if we are registered or not 00457 bool DynamicResource::isRegistered() { 00458 bool is_registered = false; 00459 00460 if (this->isConnected() == true) { 00461 // get our Endpoint 00462 Connector::Endpoint *ep = (Connector::Endpoint *)this->m_endpoint; 00463 if (ep != NULL) { 00464 is_registered = ep->isRegistered(); 00465 if (is_registered) { 00466 //this->logger()->logging("DynamicResource::isRegistered = true"); 00467 } 00468 else { 00469 //this->logger()->logging("DynamicResource::isRegistered = false"); 00470 } 00471 } 00472 else { 00473 this->logger()->logging("DynamicResource::isRegistered = false (no endpoint)"); 00474 } 00475 } 00476 00477 // return our endpoint registration state 00478 return is_registered; 00479 } 00480 00481 // get our observer 00482 void *DynamicResource::getObserver() { 00483 return this->m_observer; 00484 }
Generated on Tue Jul 12 2022 18:38:05 by
1.7.2