Mayank Gupta / Mbed OS pelion-example-frdm

Dependencies:   FXAS21002 FXOS8700Q

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers m2mresource.cpp Source File

m2mresource.cpp

00001 /*
00002  * Copyright (c) 2015 ARM Limited. All rights reserved.
00003  * SPDX-License-Identifier: Apache-2.0
00004  * Licensed under the Apache License, Version 2.0 (the License); you may
00005  * not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #include "mbed-client/m2mconstants.h"
00017 #include "mbed-client/m2mresource.h"
00018 #include "mbed-client/m2mobservationhandler.h"
00019 #include "include/m2mreporthandler.h"
00020 #include "include/m2mtlvserializer.h"
00021 #include "include/m2mtlvdeserializer.h"
00022 #include "mbed-trace/mbed_trace.h"
00023 
00024 #include <stdlib.h>
00025 
00026 #define TRACE_GROUP "mClt"
00027 
00028 M2MResource::M2MResource(M2MObjectInstance &parent,
00029                          const String &resource_name,
00030                          M2MBase::Mode resource_mode,
00031                          const String &resource_type,
00032                          M2MBase::DataType type,
00033                          const uint8_t *value,
00034                          const uint8_t value_length,
00035                          char *path,
00036                          bool multiple_instance,
00037                          bool external_blockwise_store)
00038 : M2MResourceBase(resource_name, resource_mode, resource_type, type, value, value_length,
00039                       path, external_blockwise_store, multiple_instance),
00040   _parent(parent)
00041 #ifndef DISABLE_DELAYED_RESPONSE
00042   ,_delayed_token(NULL),
00043   _delayed_token_len(0),
00044   _delayed_response(false)
00045 #endif
00046 {
00047     M2MBase::set_base_type(M2MBase::Resource);
00048     M2MBase::set_operation(M2MBase::GET_ALLOWED);
00049     M2MBase::set_observable(false);
00050     if (multiple_instance) {
00051         M2MBase::set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE_OLD);
00052     }
00053 
00054 }
00055 
00056 M2MResource::M2MResource(M2MObjectInstance &parent,
00057                          const lwm2m_parameters_s* s,
00058                           M2MBase::DataType type)
00059 : M2MResourceBase(s, type),
00060   _parent(parent)
00061 #ifndef DISABLE_DELAYED_RESPONSE
00062   ,_delayed_token(NULL),
00063   _delayed_token_len(0),
00064   _delayed_response(false)
00065 #endif
00066 {
00067     // verify, that the client has hardcoded proper type to the structure
00068     assert(base_type() == M2MBase::Resource);
00069 }
00070 
00071 M2MResource::M2MResource(M2MObjectInstance &parent,
00072                          const String &resource_name,
00073                          M2MBase::Mode resource_mode,
00074                          const String &resource_type,
00075                          M2MBase::DataType type,
00076                          bool observable,
00077                          char *path,
00078                          bool multiple_instance,
00079                          bool external_blockwise_store)
00080 : M2MResourceBase(resource_name, resource_mode, resource_type, type,
00081                       path,
00082                       external_blockwise_store,multiple_instance),
00083   _parent(parent)
00084 #ifndef DISABLE_DELAYED_RESPONSE
00085   ,_delayed_token(NULL),
00086   _delayed_token_len(0),
00087   _delayed_response(false)
00088 #endif
00089 {
00090     M2MBase::set_base_type(M2MBase::Resource);
00091     M2MBase::set_operation(M2MBase::GET_PUT_ALLOWED);
00092     M2MBase::set_observable(observable);
00093     if (multiple_instance) {
00094         M2MBase::set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE_OLD);
00095     }
00096 }
00097 
00098 
00099 M2MResource::~M2MResource()
00100 {
00101     if(!_resource_instance_list.empty()) {
00102         M2MResourceInstance* res = NULL;
00103         M2MResourceInstanceList::const_iterator it;
00104         it = _resource_instance_list.begin();
00105         for (; it!=_resource_instance_list.end(); it++ ) {
00106             //Free allocated memory for resources.
00107             res = *it;
00108             delete res;
00109         }
00110         _resource_instance_list.clear();
00111     }
00112 #ifndef DISABLE_DELAYED_RESPONSE
00113     free(_delayed_token);
00114 #endif
00115 
00116     free_resources();
00117 }
00118 
00119 bool M2MResource::supports_multiple_instances() const
00120 {
00121     M2MBase::lwm2m_parameters_s* param = M2MBase::get_lwm2m_parameters();
00122     return param->multiple_instance;
00123 }
00124 
00125 #ifndef DISABLE_DELAYED_RESPONSE
00126 void M2MResource::set_delayed_response(bool delayed_response)
00127 {
00128     _delayed_response = delayed_response;
00129 }
00130 
00131 bool M2MResource::send_delayed_post_response()
00132 {
00133     bool success = false;
00134     if(_delayed_response) {
00135         success = true;
00136         // At least on some unit tests the resource object is not fully constructed, which would
00137         // cause issues if the observation_handler is NULL. So do the check before dereferencing pointer.
00138         M2MObservationHandler* obs = observation_handler();
00139         if (obs) {
00140             obs->send_delayed_response(this);
00141         }
00142     }
00143     return success;
00144 }
00145 
00146 void M2MResource::get_delayed_token(uint8_t *&token, uint8_t &token_length)
00147 {
00148     token_length = 0;
00149     if(token) {
00150         free(token);
00151         token = NULL;
00152     }
00153     if(_delayed_token && _delayed_token_len > 0) {
00154         token = alloc_copy(_delayed_token, _delayed_token_len);
00155         if(token) {
00156             token_length = _delayed_token_len;
00157         }
00158     }
00159 }
00160 #endif
00161 
00162 bool M2MResource::remove_resource_instance(uint16_t inst_id)
00163 {
00164     tr_debug("M2MResource::remove_resource(inst_id %d)", inst_id);
00165     bool success = false;
00166     if(!_resource_instance_list.empty()) {
00167         M2MResourceInstance* res = NULL;
00168         M2MResourceInstanceList::const_iterator it;
00169         it = _resource_instance_list.begin();
00170         int pos = 0;
00171         for ( ; it != _resource_instance_list.end(); it++, pos++ ) {
00172             if(((*it)->instance_id() == inst_id)) {
00173                 // Resource found and deleted.
00174                 res = *it;
00175                 delete res;
00176                 _resource_instance_list.erase(pos);
00177                 set_changed();
00178                 success = true;
00179                 break;
00180             }
00181         }
00182     }
00183     return success;
00184 }
00185 
00186 M2MResourceInstance* M2MResource::resource_instance(uint16_t inst_id) const
00187 {
00188     tr_debug("M2MResource::resource(resource_name inst_id %d)", inst_id);
00189     M2MResourceInstance *res = NULL;
00190     if(!_resource_instance_list.empty()) {
00191         M2MResourceInstanceList::const_iterator it;
00192         it = _resource_instance_list.begin();
00193         for ( ; it != _resource_instance_list.end(); it++ ) {
00194             if(((*it)->instance_id() == inst_id)) {
00195                 // Resource found.
00196                 res = *it;
00197                 break;
00198             }
00199         }
00200     }
00201     return res;
00202 }
00203 
00204 const M2MResourceInstanceList& M2MResource::resource_instances() const
00205 {
00206     return _resource_instance_list;
00207 }
00208 
00209 uint16_t M2MResource::resource_instance_count() const
00210 {
00211     return (uint16_t)_resource_instance_list.size();
00212 }
00213 
00214 #ifndef DISABLE_DELAYED_RESPONSE
00215 bool M2MResource::delayed_response() const
00216 {
00217     return _delayed_response;
00218 }
00219 #endif
00220 
00221 M2MObservationHandler* M2MResource::observation_handler() const
00222 {
00223     const M2MObjectInstance& parent_object_instance = get_parent_object_instance();
00224 
00225     // XXX: need to check the flag too
00226     return parent_object_instance.observation_handler();
00227 }
00228 
00229 void M2MResource::set_observation_handler(M2MObservationHandler *handler)
00230 {
00231     M2MObjectInstance& parent_object_instance = get_parent_object_instance();
00232 
00233     // XXX: need to set the flag too
00234     parent_object_instance.set_observation_handler(handler);
00235 }
00236 
00237 bool M2MResource::handle_observation_attribute(const char *query)
00238 {
00239     tr_debug("M2MResource::handle_observation_attribute - is_under_observation(%d)", is_under_observation());
00240     bool success = false;
00241     M2MReportHandler *handler = M2MBase::report_handler();
00242     if (!handler) {
00243         handler = M2MBase::create_report_handler();
00244     }
00245 
00246     if (handler) {
00247         success = handler->parse_notification_attribute(query,
00248                 M2MBase::base_type(), resource_instance_type());
00249         if (success) {
00250             if (is_under_observation()) {
00251                 handler->set_under_observation(true);
00252             }
00253         }
00254         else {
00255             handler->set_default_values();
00256         }
00257 
00258         if (success) {
00259             if(!_resource_instance_list.empty()) {
00260                 M2MResourceInstanceList::const_iterator it;
00261                 it = _resource_instance_list.begin();
00262                 for ( ; it != _resource_instance_list.end(); it++ ) {
00263                     M2MReportHandler *report_handler = (*it)->report_handler();
00264                     if(report_handler && is_under_observation()) {
00265                         report_handler->set_notification_trigger();
00266                     }
00267                 }
00268             }
00269         }
00270     }
00271     return success;
00272 }
00273 
00274 void M2MResource::add_observation_level(M2MBase::Observation observation_level)
00275 {
00276     M2MBase::add_observation_level(observation_level);
00277     if(!_resource_instance_list.empty()) {
00278         M2MResourceInstanceList::const_iterator inst;
00279         inst = _resource_instance_list.begin();
00280         for ( ; inst != _resource_instance_list.end(); inst++ ) {
00281             (*inst)->add_observation_level(observation_level);
00282         }
00283     }
00284 }
00285 
00286 void M2MResource::remove_observation_level(M2MBase::Observation observation_level)
00287 {
00288     M2MBase::remove_observation_level(observation_level);
00289     if(!_resource_instance_list.empty()) {
00290         M2MResourceInstanceList::const_iterator inst;
00291         inst = _resource_instance_list.begin();
00292         for ( ; inst != _resource_instance_list.end(); inst++ ) {
00293             (*inst)->remove_observation_level(observation_level);
00294         }
00295     }
00296 }
00297 
00298 void M2MResource::add_resource_instance(M2MResourceInstance *res)
00299 {
00300     tr_debug("M2MResource::add_resource_instance()");
00301     if(res) {
00302         _resource_instance_list.push_back(res);
00303         set_changed();
00304     }
00305 }
00306 
00307 sn_coap_hdr_s* M2MResource::handle_get_request(nsdl_s *nsdl,
00308                                                sn_coap_hdr_s *received_coap_header,
00309                                                M2MObservationHandler *observation_handler)
00310 {
00311     tr_info("M2MResource::handle_get_request()");
00312     sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CONTENT;
00313     sn_coap_hdr_s * coap_response = NULL;
00314     if(supports_multiple_instances()) {
00315         coap_response = sn_nsdl_build_response(nsdl,
00316                                                received_coap_header,
00317                                                msg_code);
00318         if(received_coap_header) {
00319             // process the GET if we have registered a callback for it
00320             if ((operation() & M2MBase::GET_ALLOWED) != 0) {
00321                 if(coap_response) {
00322                     bool content_type_present = false;
00323                     bool is_content_type_supported = true;
00324 
00325                     if (received_coap_header->options_list_ptr &&
00326                             received_coap_header->options_list_ptr->accept != COAP_CT_NONE) {
00327                         content_type_present = true;
00328                         coap_response->content_format = received_coap_header->options_list_ptr->accept;
00329                     }
00330 
00331                     // Check if preferred content type is supported
00332                     if (content_type_present) {
00333                         if (coap_response->content_format != COAP_CONTENT_OMA_TLV_TYPE_OLD &&
00334                             coap_response->content_format != COAP_CONTENT_OMA_TLV_TYPE) {
00335                             is_content_type_supported = false;
00336                         }
00337                     }
00338 
00339                     if (is_content_type_supported) {
00340                         if(!content_type_present &&
00341                            (M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE ||
00342                             M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE_OLD)) {
00343                             coap_response->content_format = sn_coap_content_format_e(M2MBase::coap_content_type());
00344                         }
00345 
00346                         tr_debug("M2MResource::handle_get_request() - Request Content-type: %d", coap_response->content_format);
00347 
00348                         uint8_t *data = NULL;
00349                         uint32_t data_length = 0;
00350                         // fill in the CoAP response payload
00351                         if(COAP_CONTENT_OMA_TLV_TYPE == coap_response->content_format ||
00352                            COAP_CONTENT_OMA_TLV_TYPE_OLD == coap_response->content_format) {
00353                             set_coap_content_type(coap_response->content_format);
00354                             data = M2MTLVSerializer::serialize(this, data_length);
00355                         }
00356 
00357                         coap_response->payload_len = data_length;
00358                         coap_response->payload_ptr = data;
00359 
00360                         coap_response->options_list_ptr = sn_nsdl_alloc_options_list(nsdl, coap_response);
00361                         if (coap_response->options_list_ptr) {
00362                             coap_response->options_list_ptr->max_age = max_age();
00363                         }
00364 
00365                         if(received_coap_header->options_list_ptr) {
00366                             if(received_coap_header->options_list_ptr->observe != -1) {
00367                                 handle_observation(nsdl, *received_coap_header, *coap_response, observation_handler, msg_code);
00368                             }
00369                         }
00370                     } else {
00371                         tr_error("M2MResource::handle_get_request() - Content-Type %d not supported", coap_response->content_format);
00372                         msg_code = COAP_MSG_CODE_RESPONSE_NOT_ACCEPTABLE;
00373                     }
00374                 }
00375             } else {
00376                 tr_error("M2MResource::handle_get_request - Return COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
00377                 // Operation is not allowed.
00378                 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00379             }
00380         }
00381         if(coap_response) {
00382             coap_response->msg_code = msg_code;
00383         }
00384     } else {
00385         coap_response = M2MResourceBase::handle_get_request(nsdl,
00386                             received_coap_header,
00387                             observation_handler);
00388     }
00389     return coap_response;
00390 }
00391 
00392 sn_coap_hdr_s* M2MResource::handle_put_request(nsdl_s *nsdl,
00393                                                sn_coap_hdr_s *received_coap_header,
00394                                                M2MObservationHandler *observation_handler,
00395                                                bool &execute_value_updated)
00396 {
00397     tr_info("M2MResource::handle_put_request()");
00398     sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04
00399     sn_coap_hdr_s * coap_response = NULL;
00400     if(supports_multiple_instances()) {
00401         coap_response = sn_nsdl_build_response(nsdl,
00402                                                received_coap_header,
00403                                                msg_code);
00404         // process the PUT if we have registered a callback for it
00405         if(received_coap_header) {
00406             uint16_t coap_content_type = 0;
00407             bool content_type_present = false;
00408             if(received_coap_header->content_format != COAP_CT_NONE && coap_response) {
00409                 content_type_present = true;
00410                 coap_content_type = received_coap_header->content_format;
00411             }
00412             if(received_coap_header->options_list_ptr &&
00413                received_coap_header->options_list_ptr->uri_query_ptr) {
00414                 char *query = (char*)alloc_string_copy(received_coap_header->options_list_ptr->uri_query_ptr,
00415                                                         received_coap_header->options_list_ptr->uri_query_len);
00416                 if (query){
00417                     msg_code = COAP_MSG_CODE_RESPONSE_CHANGED;
00418                     tr_info("M2MResource::handle_put_request() - query %s", query);
00419                     // if anything was updated, re-initialize the stored notification attributes
00420                     if (!handle_observation_attribute(query)){
00421                         tr_debug("M2MResource::handle_put_request() - Invalid query");
00422                         msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // 4.00
00423                     }
00424                     free(query);
00425                 }
00426             } else if ((operation() & M2MBase::PUT_ALLOWED) != 0) {
00427                 if(!content_type_present &&
00428                    (M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE ||
00429                     M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE_OLD)) {
00430                     coap_content_type = COAP_CONTENT_OMA_TLV_TYPE;
00431                 }
00432 
00433                 tr_debug("M2MResource::handle_put_request() - Request Content-type: %d", coap_content_type);
00434 
00435                 if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type ||
00436                    COAP_CONTENT_OMA_TLV_TYPE_OLD == coap_content_type) {
00437                     set_coap_content_type(coap_content_type);
00438                     M2MTLVDeserializer::Error error = M2MTLVDeserializer::None;
00439                     error = M2MTLVDeserializer::deserialize_resource_instances(received_coap_header->payload_ptr,
00440                                                                          received_coap_header->payload_len,
00441                                                                          *this,
00442                                                                          M2MTLVDeserializer::Put);
00443                     switch(error) {
00444                         case M2MTLVDeserializer::None:
00445                             if(observation_handler) {
00446                                 String value = "";
00447                                 if (received_coap_header->uri_path_ptr != NULL &&
00448                                     received_coap_header->uri_path_len > 0) {
00449 
00450                                     value.append_raw((char*)received_coap_header->uri_path_ptr,received_coap_header->uri_path_len);
00451                                 }
00452                                 execute_value_updated = true;
00453                             }
00454                             msg_code = COAP_MSG_CODE_RESPONSE_CHANGED;
00455                             break;
00456                         case M2MTLVDeserializer::NotFound:
00457                             msg_code = COAP_MSG_CODE_RESPONSE_NOT_FOUND;
00458                             break;
00459                         case M2MTLVDeserializer::NotAllowed:
00460                             msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00461                             break;
00462                         case M2MTLVDeserializer::NotValid:
00463                             msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
00464                             break;
00465                         case M2MTLVDeserializer::OutOfMemory:
00466                             msg_code = COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE;
00467                             break;
00468                     }
00469                 } else {
00470                     msg_code =COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT;
00471                 } // if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type)
00472             } else {
00473                 // Operation is not allowed.
00474                 tr_error("M2MResource::handle_put_request() - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
00475                 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00476             }
00477         } else {
00478             msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00479         }
00480         if(coap_response) {
00481             coap_response->msg_code = msg_code;
00482         }
00483     } else {
00484         coap_response = M2MResourceBase::handle_put_request(nsdl,
00485                             received_coap_header,
00486                             observation_handler,
00487                             execute_value_updated);
00488     }
00489     return coap_response;
00490 }
00491 
00492 
00493 sn_coap_hdr_s* M2MResource::handle_post_request(nsdl_s *nsdl,
00494                                                 sn_coap_hdr_s *received_coap_header,
00495                                                 M2MObservationHandler */*observation_handler*/,
00496                                                 bool &/*execute_value_updated*/,
00497                                                 sn_nsdl_addr_s *address)
00498 {
00499     tr_info("M2MResource::handle_post_request()");
00500     sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04
00501     sn_coap_hdr_s * coap_response = sn_nsdl_build_response(nsdl,
00502                                                            received_coap_header,
00503                                                            msg_code);
00504 
00505     // process the POST if we have registered a callback for it
00506     if(received_coap_header) {
00507         if ((operation() & M2MBase::POST_ALLOWED) != 0) {
00508 #ifndef MEMORY_OPTIMIZED_API
00509             const String &obj_name = object_name();
00510             const String &res_name = name();
00511             M2MResource::M2MExecuteParameter exec_params(obj_name, res_name, object_instance_id());
00512 #else
00513             M2MResource::M2MExecuteParameter exec_params(object_name(), name(), object_instance_id());
00514 #endif
00515 
00516 
00517 
00518             uint16_t coap_content_type = 0;
00519             if(received_coap_header->payload_ptr) {
00520                 if(received_coap_header->content_format != COAP_CT_NONE) {
00521                     coap_content_type = received_coap_header->content_format;
00522                 }
00523 
00524                 if(coap_content_type == COAP_CT_TEXT_PLAIN) {
00525                     exec_params._value = received_coap_header->payload_ptr;
00526                     if (exec_params._value) {
00527                         exec_params._value_length = received_coap_header->payload_len;
00528                     }
00529                 } else {
00530                     msg_code = COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT;
00531                 }
00532             }
00533             if(COAP_MSG_CODE_RESPONSE_CHANGED == msg_code) {
00534                 tr_debug("M2MResource::handle_post_request - Execute resource function");
00535 #ifndef DISABLE_DELAYED_RESPONSE
00536                 if (coap_response) {
00537                     if(_delayed_response) {
00538                         if(received_coap_header->token_len) {
00539                             free(_delayed_token);
00540                             _delayed_token = NULL;
00541                             _delayed_token_len = 0;
00542                             _delayed_token = alloc_copy(received_coap_header->token_ptr, received_coap_header->token_len);
00543                             if(_delayed_token) {
00544                                 _delayed_token_len = received_coap_header->token_len;
00545                             }
00546                         }
00547                     } else {
00548     #endif
00549                         uint32_t length = 0;
00550                         get_value(coap_response->payload_ptr, length);
00551                         coap_response->payload_len = length;
00552     #ifndef DISABLE_DELAYED_RESPONSE
00553                     }
00554                 }
00555 #endif
00556                 execute(&exec_params);
00557             }
00558 
00559         } else { // if ((object->operation() & SN_GRS_POST_ALLOWED) != 0)
00560             tr_error("M2MResource::handle_post_request - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
00561             msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; // 4.05
00562         }
00563     } else { //if(object && received_coap_header)
00564         tr_error("M2MResource::handle_post_request - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
00565         msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; // 4.01
00566     }
00567     if(coap_response) {
00568         coap_response->msg_code = msg_code;
00569     }
00570     return coap_response;
00571 }
00572 
00573 M2MBase *M2MResource::get_parent() const
00574 {
00575     return (M2MBase *) &get_parent_object_instance();
00576 }
00577 
00578 M2MObjectInstance& M2MResource::get_parent_object_instance() const
00579 {
00580     return _parent;
00581 }
00582 
00583 uint16_t M2MResource::object_instance_id() const
00584 {
00585     const M2MObjectInstance& parent_object_instance = get_parent_object_instance();
00586     return parent_object_instance.instance_id();
00587 }
00588 
00589 M2MResource& M2MResource::get_parent_resource() const
00590 {
00591     return (M2MResource&)*this;
00592 }
00593 
00594 const char* M2MResource::object_name() const
00595 {
00596     const M2MObjectInstance& parent_object_instance = _parent;
00597     const M2MObject& parent_object = parent_object_instance.get_parent_object();
00598 
00599     return parent_object.name();
00600 }
00601 
00602 #ifdef MEMORY_OPTIMIZED_API
00603 M2MResource::M2MExecuteParameter::M2MExecuteParameter(const char *object_name, const char *resource_name,
00604                                                       uint16_t object_instance_id) :
00605 _object_name(object_name),
00606 _resource_name(resource_name),
00607 _value(NULL),
00608 _value_length(0),
00609 _object_instance_id(object_instance_id)
00610 {
00611 }
00612 #else
00613 M2MResource::M2MExecuteParameter::M2MExecuteParameter(const String &object_name,
00614                                                       const String &resource_name,
00615                                                       uint16_t object_instance_id) :
00616 _object_name(object_name),
00617 _resource_name(resource_name),
00618 _value(NULL),
00619 _value_length(0),
00620 _object_instance_id(object_instance_id)
00621 {
00622 }
00623 #endif
00624 
00625 // These could be actually changed to be inline ones, as it would likely generate
00626 // smaller code at application side.
00627 
00628 const uint8_t *M2MResource::M2MExecuteParameter::get_argument_value() const
00629 {
00630     return _value;
00631 }
00632 
00633 uint16_t M2MResource::M2MExecuteParameter::get_argument_value_length() const
00634 {
00635     return _value_length;
00636 }
00637 
00638 #ifdef MEMORY_OPTIMIZED_API
00639 const char* M2MResource::M2MExecuteParameter::get_argument_object_name() const
00640 {
00641     return _object_name;
00642 }
00643 
00644 const char* M2MResource::M2MExecuteParameter::get_argument_resource_name() const
00645 {
00646     return _resource_name;
00647 }
00648 #else
00649 const String& M2MResource::M2MExecuteParameter::get_argument_object_name() const
00650 {
00651     return _object_name;
00652 }
00653 
00654 const String& M2MResource::M2MExecuteParameter::get_argument_resource_name() const
00655 {
00656     return _resource_name;
00657 }
00658 #endif
00659 
00660 uint16_t M2MResource::M2MExecuteParameter::get_argument_object_instance_id() const
00661 {
00662     return _object_instance_id;
00663 }