This is the sample program that can see the decode result of barcode data on Watson IoT.

Dependencies:   AsciiFont DisplayApp GR-PEACH_video LCD_shield_config LWIPBP3595Interface_STA_for_mbed-os USBDevice

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DynamicResource.cpp Source File

DynamicResource.cpp

Go to the documentation of this file.
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 }