sandbox / mbed-client

Fork of mbed-client by Christopher Haster

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 "include/nsdllinker.h"
00023 #include "mbed-trace/mbed_trace.h"
00024 
00025 #define TRACE_GROUP "mClt"
00026 
00027 M2MResource& M2MResource::operator=(const M2MResource& other)
00028 {
00029     if (this != &other) { // protect against invalid self-assignment
00030         _has_multiple_instances = other._has_multiple_instances;
00031         if(!other._resource_instance_list.empty()){
00032             M2MResourceInstance* ins = NULL;
00033             M2MResourceInstanceList::const_iterator it;
00034             it = other._resource_instance_list.begin();
00035             for (; it!=other._resource_instance_list.end(); it++ ) {
00036                 ins = *it;
00037                 _resource_instance_list.push_back(new M2MResourceInstance(*ins));
00038             }
00039         }
00040         if(other._delayed_token) {
00041             _delayed_token = (uint8_t*)malloc(other._delayed_token_len);
00042             if(_delayed_token) {
00043                 memcpy(_delayed_token,other._delayed_token,other._delayed_token_len);
00044                 _delayed_token_len = other._delayed_token_len;
00045             }
00046         }
00047     }
00048     return *this;
00049 }
00050 
00051 M2MResource::M2MResource(const M2MResource& other)
00052 : M2MResourceInstance(other),
00053   _delayed_response(false),
00054   _delayed_token(NULL),
00055   _delayed_token_len(0)
00056 {
00057     this->operator=(other);
00058 }
00059 
00060 M2MResource::M2MResource(M2MObjectInstanceCallback &object_instance_callback,
00061                          const String &resource_name,
00062                          const String &resource_type,
00063                          M2MResourceInstance::ResourceType type,
00064                          const uint8_t *value,
00065                          const uint8_t value_length,
00066                          const uint16_t object_instance_id,
00067                          const String &object_name,
00068                          bool multiple_instance)
00069 : M2MResourceInstance(resource_name, resource_type, type, value, value_length,
00070                       object_instance_callback, object_instance_id, object_name),
00071   _has_multiple_instances(multiple_instance),
00072   _delayed_response(false),
00073   _delayed_token(NULL),
00074   _delayed_token_len(0)
00075 {
00076     M2MBase::set_base_type(M2MBase::Resource);
00077     M2MBase::set_operation(M2MBase::GET_ALLOWED);
00078     M2MBase::set_observable(false);
00079 }
00080 
00081 M2MResource::M2MResource(M2MObjectInstanceCallback &object_instance_callback,
00082                          const String &resource_name,
00083                          const String &resource_type,
00084                          M2MResourceInstance::ResourceType type,
00085                          bool observable,
00086                          const uint16_t object_instance_id,
00087                          const String &object_name,
00088                          bool multiple_instance)
00089 : M2MResourceInstance(resource_name, resource_type, type,
00090                       object_instance_callback, object_instance_id, object_name),
00091   _has_multiple_instances(multiple_instance),
00092   _delayed_response(false),
00093   _delayed_token(NULL),
00094   _delayed_token_len(0)
00095 {
00096     M2MBase::set_base_type(M2MBase::Resource);
00097     M2MBase::set_operation(M2MBase::GET_PUT_ALLOWED);
00098     M2MBase::set_observable(observable);
00099 }
00100 
00101 M2MResource::~M2MResource()
00102 {
00103     if(!_resource_instance_list.empty()) {
00104         M2MResourceInstance* res = NULL;
00105         M2MResourceInstanceList::const_iterator it;
00106         it = _resource_instance_list.begin();
00107         for (; it!=_resource_instance_list.end(); it++ ) {
00108             //Free allocated memory for resources.
00109             res = *it;
00110             delete res;
00111             res = NULL;
00112         }
00113         _resource_instance_list.clear();
00114     }
00115     if(_delayed_token) {
00116         free(_delayed_token);
00117         _delayed_token = NULL;
00118     }
00119 }
00120 
00121 bool M2MResource::supports_multiple_instances() const
00122 {
00123     return _has_multiple_instances;
00124 }
00125 
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         observation_handler()->send_delayed_response(this);
00137     }
00138     return success;
00139 }
00140 
00141 void M2MResource::get_delayed_token(uint8_t *&token, uint8_t &token_length)
00142 {
00143     token = _delayed_token;
00144     token_length = _delayed_token_len;
00145 }
00146 
00147 bool M2MResource::remove_resource_instance(uint16_t inst_id)
00148 {
00149     tr_debug("M2MResource::remove_resource(inst_id %d)", inst_id);
00150     bool success = false;
00151     if(!_resource_instance_list.empty()) {
00152         M2MResourceInstance* res = NULL;
00153         M2MResourceInstanceList::const_iterator it;
00154         it = _resource_instance_list.begin();
00155         int pos = 0;
00156         for ( ; it != _resource_instance_list.end(); it++, pos++ ) {
00157             if(((*it)->instance_id() == inst_id)) {
00158                 // Resource found and deleted.
00159                 res = *it;
00160                 delete res;
00161                 res = NULL;
00162                 _resource_instance_list.erase(pos);
00163                 success = true;
00164                 break;
00165             }
00166         }
00167     }
00168     return success;
00169 }
00170 
00171 M2MResourceInstance* M2MResource::resource_instance(uint16_t inst_id) const
00172 {
00173     tr_debug("M2MResource::resource(resource_name inst_id %d)", inst_id);
00174     M2MResourceInstance *res = NULL;
00175     if(!_resource_instance_list.empty()) {
00176         M2MResourceInstanceList::const_iterator it;
00177         it = _resource_instance_list.begin();
00178         for ( ; it != _resource_instance_list.end(); it++ ) {
00179             if(((*it)->instance_id() == inst_id)) {
00180                 // Resource found.
00181                 res = *it;
00182                 break;
00183             }
00184         }
00185     }
00186     return res;
00187 }
00188 
00189 const M2MResourceInstanceList& M2MResource::resource_instances() const
00190 {
00191     return _resource_instance_list;
00192 }
00193 
00194 uint16_t M2MResource::resource_instance_count() const
00195 {
00196     return (uint16_t)_resource_instance_list.size();
00197 }
00198 
00199 bool M2MResource::delayed_response() const
00200 {
00201     return _delayed_response;
00202 }
00203 
00204 bool M2MResource::handle_observation_attribute(char *&query)
00205 {
00206     tr_debug("M2MResource::handle_observation_attribute");
00207     bool success = false;
00208     M2MReportHandler *handler = M2MBase::report_handler();
00209     if (handler) {
00210         success = handler->parse_notification_attribute(query,
00211                 M2MBase::base_type(), _resource_type);
00212         if (success) {            
00213             if ((handler->attribute_flags() & M2MReportHandler::Cancel) == 0) {
00214                 handler->set_under_observation(true);
00215             } else {
00216                 handler->set_under_observation(false);
00217             }
00218         }
00219         else {
00220             handler->set_default_values();
00221         }
00222 
00223         if (success) {
00224             if(!_resource_instance_list.empty()) {
00225                 M2MResourceInstanceList::const_iterator it;
00226                 it = _resource_instance_list.begin();
00227                 for ( ; it != _resource_instance_list.end(); it++ ) {
00228                     M2MReportHandler *report_handler = (*it)->report_handler();
00229                     if(report_handler && is_observable()) {
00230                         report_handler->set_notification_trigger();
00231                     }
00232                 }
00233             }
00234         }
00235     }
00236     return success;
00237 }
00238 
00239 void M2MResource::add_observation_level(M2MBase::Observation observation_level)
00240 {
00241     M2MBase::add_observation_level(observation_level);
00242     if(!_resource_instance_list.empty()) {
00243         M2MResourceInstanceList::const_iterator inst;
00244         inst = _resource_instance_list.begin();
00245         for ( ; inst != _resource_instance_list.end(); inst++ ) {
00246             (*inst)->add_observation_level(observation_level);
00247         }
00248     }
00249 }
00250 
00251 void M2MResource::remove_observation_level(M2MBase::Observation observation_level)
00252 {
00253     M2MBase::remove_observation_level(observation_level);
00254     if(!_resource_instance_list.empty()) {
00255         M2MResourceInstanceList::const_iterator inst;
00256         inst = _resource_instance_list.begin();
00257         for ( ; inst != _resource_instance_list.end(); inst++ ) {
00258             (*inst)->remove_observation_level(observation_level);
00259         }
00260     }
00261 }
00262 
00263 void M2MResource::add_resource_instance(M2MResourceInstance *res)
00264 {
00265     tr_debug("M2MResource::add_resource_instance()");
00266     if(res) {
00267         _resource_instance_list.push_back(res);
00268     }
00269 }
00270 
00271 sn_coap_hdr_s* M2MResource::handle_get_request(nsdl_s *nsdl,
00272                                                sn_coap_hdr_s *received_coap_header,
00273                                                M2MObservationHandler *observation_handler)
00274 {
00275     tr_debug("M2MResource::handle_get_request()");
00276     sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CONTENT;
00277     sn_coap_hdr_s * coap_response = NULL;
00278     if(_has_multiple_instances) {
00279         coap_response = sn_nsdl_build_response(nsdl,
00280                                                received_coap_header,
00281                                                msg_code);
00282         if(received_coap_header) {
00283             // process the GET if we have registered a callback for it
00284             if ((operation() & SN_GRS_GET_ALLOWED) != 0) {
00285                 if(coap_response) {
00286                     uint16_t coap_content_type = 0;
00287                     bool content_type_present = false;
00288                     if(received_coap_header->content_type_ptr){
00289                         content_type_present = true;
00290                         coap_response->content_type_ptr =
00291                                 m2m::String::convert_integer_to_array(0,
00292                                       coap_response->content_type_len,
00293                                       received_coap_header->content_type_ptr,
00294                                       received_coap_header->content_type_len);
00295                         if(coap_response->content_type_ptr) {
00296                             for(uint8_t i = 0; i < coap_response->content_type_len; i++) {
00297                                 coap_content_type = (coap_content_type << 8) +
00298                                         (coap_response->content_type_ptr[i] & 0xFF);
00299                             }
00300                         }
00301                     }
00302 
00303                     if(!content_type_present &&
00304                        M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE) {
00305                         coap_content_type = COAP_CONTENT_OMA_TLV_TYPE;
00306                     }
00307 
00308                     tr_debug("M2MResource::handle_get_request() - Request Content-Type %d", coap_content_type);
00309                     if (!coap_response->content_type_ptr) {
00310                         coap_response->content_type_ptr =
00311                                 m2m::String::convert_integer_to_array(coap_content_type,
00312                                     coap_response->content_type_len);
00313                         if (coap_response->content_type_ptr) {
00314                             set_coap_content_type(coap_content_type);
00315                         }
00316                     }
00317                     uint8_t *data = NULL;
00318                     uint32_t data_length = 0;
00319                     // fill in the CoAP response payload
00320                     if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) {
00321                         M2MTLVSerializer *serializer = new M2MTLVSerializer();
00322                         if(serializer) {
00323                             data = serializer->serialize(this, data_length);
00324                             delete serializer;
00325                         }
00326                     } else {
00327                         msg_code = COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT; // Content format not supported
00328                     }
00329 
00330                     coap_response->payload_len = data_length;
00331                     coap_response->payload_ptr = data;
00332 
00333                     coap_response->options_list_ptr = (sn_coap_options_list_s*)malloc(sizeof(sn_coap_options_list_s));
00334                     memset(coap_response->options_list_ptr, 0, sizeof(sn_coap_options_list_s));
00335 
00336                     coap_response->options_list_ptr->max_age_ptr =
00337                             m2m::String::convert_integer_to_array(max_age(),
00338                                 coap_response->options_list_ptr->max_age_len);
00339 
00340                     if(received_coap_header->token_ptr) {
00341                         tr_debug("M2MResource::handle_get_request - Sets Observation Token to resource");
00342                         set_observation_token(received_coap_header->token_ptr,
00343                                               received_coap_header->token_len);
00344                     }
00345 
00346                     if(received_coap_header->options_list_ptr) {
00347                         if(received_coap_header->options_list_ptr->observe) {
00348                             if (is_observable()) {
00349                                 uint32_t number = 0;
00350                                 uint8_t observe_option = 0;
00351                                 if(received_coap_header->options_list_ptr->observe_ptr) {
00352                                     observe_option = *received_coap_header->options_list_ptr->observe_ptr;
00353                                 }
00354                                 if(START_OBSERVATION == observe_option) {
00355                                     tr_debug("M2MResource::handle_get_request - Starts Observation");
00356                                     // If the observe length is 0 means register for observation.
00357                                     if(received_coap_header->options_list_ptr->observe_len != 0) {
00358                                         for(int i=0;i < received_coap_header->options_list_ptr->observe_len; i++) {
00359                                             number = (*(received_coap_header->options_list_ptr->observe_ptr + i) & 0xff) <<
00360                                                      8*(received_coap_header->options_list_ptr->observe_len- 1 - i);
00361                                             }
00362                                     }
00363                                     // If the observe value is 0 means register for observation.
00364                                     if(number == 0) {
00365                                         tr_debug("M2MResource::handle_get_request - Put Resource under Observation");
00366                                         M2MResourceInstanceList::const_iterator it;
00367                                         it = _resource_instance_list.begin();
00368                                         for (; it!=_resource_instance_list.end(); it++ ) {
00369                                             tr_debug("M2MResource::handle_get_request - set_resource_observer");
00370                                             (*it)->set_resource_observer(this);
00371                                             (*it)->add_observation_level(M2MBase::R_Attribute);
00372                                         }
00373                                         set_under_observation(true,observation_handler);
00374                                         M2MBase::add_observation_level(M2MBase::R_Attribute);
00375                                         coap_response->options_list_ptr->observe_ptr =
00376                                                 m2m::String::convert_integer_to_array(observation_number(),
00377                                                       coap_response->options_list_ptr->observe_len);
00378                                     }
00379                                 } else if (STOP_OBSERVATION == observe_option) {
00380                                     tr_debug("M2MResource::handle_get_request - Stops Observation");
00381                                     set_under_observation(false,NULL);
00382                                     M2MBase::remove_observation_level(M2MBase::R_Attribute);
00383                                     M2MResourceInstanceList::const_iterator it;
00384                                     it = _resource_instance_list.begin();
00385                                     for (; it!=_resource_instance_list.end(); it++ ) {
00386                                         (*it)->set_resource_observer(NULL);
00387                                     }
00388                                 }
00389                                 msg_code = COAP_MSG_CODE_RESPONSE_CONTENT;
00390                             }
00391                             else {
00392                                 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00393                             }
00394                         }
00395                     }
00396                 }
00397             } else {
00398                 tr_error("M2MResource::handle_get_request - Return COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
00399                 // Operation is not allowed.
00400                 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00401             }
00402         }
00403         if(coap_response) {
00404             coap_response->msg_code = msg_code;
00405         }
00406     } else {
00407         coap_response = M2MResourceInstance::handle_get_request(nsdl,
00408                             received_coap_header,
00409                             observation_handler);
00410     }
00411     return coap_response;
00412 }
00413 
00414 sn_coap_hdr_s* M2MResource::handle_put_request(nsdl_s *nsdl,
00415                                                sn_coap_hdr_s *received_coap_header,
00416                                                M2MObservationHandler *observation_handler,
00417                                                bool &execute_value_updated)
00418 {
00419     tr_debug("M2MResource::handle_put_request()");
00420     sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04
00421     sn_coap_hdr_s * coap_response = NULL;
00422     if(_has_multiple_instances) {
00423         coap_response = sn_nsdl_build_response(nsdl,
00424                                                received_coap_header,
00425                                                msg_code);
00426         // process the PUT if we have registered a callback for it
00427         if(received_coap_header) {
00428             uint16_t coap_content_type = 0;
00429             bool content_type_present = false;
00430             if(received_coap_header->content_type_ptr) {
00431                 if(coap_response) {
00432                     content_type_present = true;
00433                     coap_response->content_type_ptr =
00434                             m2m::String::convert_integer_to_array(0,
00435                                 coap_response->content_type_len,
00436                                 received_coap_header->content_type_ptr,
00437                                 received_coap_header->content_type_len);
00438 
00439                     if(coap_response->content_type_ptr) {
00440                         for(uint8_t i = 0; i < coap_response->content_type_len; i++) {
00441                             coap_content_type = (coap_content_type << 8) +
00442                                     (coap_response->content_type_ptr[i] & 0xFF);
00443                         }
00444                     }
00445                 }
00446             }
00447             if(received_coap_header->options_list_ptr &&
00448                received_coap_header->options_list_ptr->uri_query_ptr) {
00449                 char *query = (char*)malloc(received_coap_header->options_list_ptr->uri_query_len+1);
00450                 if (query){
00451                     msg_code = COAP_MSG_CODE_RESPONSE_CHANGED;
00452                     memset(query, 0, received_coap_header->options_list_ptr->uri_query_len+1);
00453                     memcpy(query,
00454                         received_coap_header->options_list_ptr->uri_query_ptr,
00455                         received_coap_header->options_list_ptr->uri_query_len);
00456                     memset(query + received_coap_header->options_list_ptr->uri_query_len,'\0',1);//String terminator
00457                     tr_debug("M2MResource::handle_put_request() - Query %s", query);
00458                     // if anything was updated, re-initialize the stored notification attributes
00459                     if (!handle_observation_attribute(query)){
00460                         tr_debug("M2MResource::handle_put_request() - Invalid query");
00461                         msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // 4.00
00462                     }
00463                     free(query);
00464                 }
00465             } else if ((operation() & SN_GRS_PUT_ALLOWED) != 0) {
00466                 if(!content_type_present &&
00467                    M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE) {
00468                     coap_content_type = COAP_CONTENT_OMA_TLV_TYPE;
00469                 }
00470 
00471                 tr_debug("M2MResource::handle_put_request() - Request Content-Type %d", coap_content_type);
00472 
00473                 if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) {
00474                     M2MTLVDeserializer *deserializer = new M2MTLVDeserializer();
00475                     if(deserializer) {
00476                         M2MTLVDeserializer::Error error = M2MTLVDeserializer::None;
00477                         error = deserializer->deserialize_resource_instances(received_coap_header->payload_ptr,
00478                                                                              received_coap_header->payload_len,
00479                                                                              *this,
00480                                                                              M2MTLVDeserializer::Put);
00481                         switch(error) {
00482                             case M2MTLVDeserializer::None:
00483                                 if(observation_handler) {
00484                                     String value = "";
00485                                     if (received_coap_header->uri_path_ptr != NULL &&
00486                                         received_coap_header->uri_path_len > 0) {
00487                                         char* buf = (char*)malloc(received_coap_header->uri_path_len+1);
00488                                         if(buf) {
00489                                             memset(buf,0,received_coap_header->uri_path_len+1);
00490                                             memcpy(buf,received_coap_header->uri_path_ptr,received_coap_header->uri_path_len);
00491                                             value = String(buf);
00492                                             free(buf);
00493                                         }
00494                                     }
00495                                     execute_value_updated = true;
00496                                 }
00497                                 msg_code = COAP_MSG_CODE_RESPONSE_CHANGED;
00498                                 break;
00499                             case M2MTLVDeserializer::NotFound:
00500                                 msg_code = COAP_MSG_CODE_RESPONSE_NOT_FOUND;
00501                                 break;
00502                             case M2MTLVDeserializer::NotAllowed:
00503                                 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00504                                 break;
00505                             case M2MTLVDeserializer::NotValid:
00506                                 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
00507                                 break;
00508                         }
00509                         delete deserializer;
00510                     }
00511                 } else {
00512                     msg_code =COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT;
00513                 } // if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type)
00514             } else {
00515                 // Operation is not allowed.
00516                 tr_error("M2MResource::handle_put_request() - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
00517                 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00518             }
00519         } else {
00520             msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00521         }
00522         if(coap_response) {
00523             coap_response->msg_code = msg_code;
00524         }
00525     } else {        
00526         coap_response = M2MResourceInstance::handle_put_request(nsdl,
00527                             received_coap_header,
00528                             observation_handler,
00529                             execute_value_updated);
00530     }
00531     return coap_response;
00532 }
00533 
00534 sn_coap_hdr_s* M2MResource::handle_post_request(nsdl_s *nsdl,
00535                                                 sn_coap_hdr_s *received_coap_header,
00536                                                 M2MObservationHandler */*observation_handler*/,
00537                                                 bool &/*execute_value_updated*/)
00538 {
00539     tr_debug("M2MResource::handle_post_request()");
00540     sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04
00541     sn_coap_hdr_s * coap_response = sn_nsdl_build_response(nsdl,
00542                                                            received_coap_header,
00543                                                            msg_code);
00544     // process the POST if we have registered a callback for it
00545     if(received_coap_header) {
00546         if ((operation() & SN_GRS_POST_ALLOWED) != 0) {
00547             M2MResource::M2MExecuteParameter *exec_params = NULL;
00548             uint16_t coap_content_type = 0;
00549             if(received_coap_header->payload_ptr) {
00550                 if(received_coap_header->content_type_ptr) {
00551                     for(uint8_t i = 0; i < received_coap_header->content_type_len; i++) {
00552                         coap_content_type = (coap_content_type << 8) + (received_coap_header->content_type_ptr[i] & 0xFF);
00553                     }
00554                 }
00555                 if(coap_content_type == 0) {
00556                     exec_params = new M2MResource::M2MExecuteParameter();
00557                     if (exec_params){
00558                         exec_params->_value = (uint8_t*)malloc(received_coap_header->payload_len+1);
00559                         if (exec_params->_value) {
00560                             memset(exec_params->_value, 0, received_coap_header->payload_len+1);
00561                             memcpy(exec_params->_value,
00562                                 received_coap_header->payload_ptr,
00563                                 received_coap_header->payload_len);
00564                             exec_params->_value_length = received_coap_header->payload_len;
00565                         }
00566                         exec_params->_object_name = object_name();
00567                         exec_params->_resource_name = name();
00568                         exec_params->_object_instance_id = object_instance_id();
00569                     }
00570                 } else {
00571                     msg_code = COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT;
00572                 }
00573             }
00574             if(COAP_MSG_CODE_RESPONSE_CHANGED == msg_code) {
00575                 tr_debug("M2MResource::handle_post_request - Execute resource function");
00576                 execute(exec_params);
00577                 if(exec_params) {
00578                     delete exec_params;
00579                 }
00580 
00581                 if(_delayed_response) {
00582                     coap_response->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT;
00583                     coap_response->msg_code = COAP_MSG_CODE_EMPTY;
00584                     coap_response->msg_id = received_coap_header->msg_id;
00585                     if(received_coap_header->token_len) {
00586                         if(_delayed_token) {
00587                          free(_delayed_token);
00588                          _delayed_token = NULL;
00589                          _delayed_token_len = 0;
00590                         }
00591                         _delayed_token = (uint8_t*)malloc(received_coap_header->token_len);
00592                         if(_delayed_token) {
00593                             memset(_delayed_token,0,received_coap_header->token_len);
00594                             _delayed_token_len = received_coap_header->token_len;
00595                             memcpy(_delayed_token, received_coap_header->token_ptr, _delayed_token_len);
00596                         }
00597                     }
00598                 } else {
00599                     uint32_t length = 0;
00600                     get_value(coap_response->payload_ptr, length);
00601                     coap_response->payload_len = length;
00602                 }
00603             }
00604         } else { // if ((object->operation() & SN_GRS_POST_ALLOWED) != 0)
00605             tr_error("M2MResource::handle_post_request - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
00606             msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; // 4.05
00607         }
00608     } else { //if(object && received_coap_header)
00609         tr_error("M2MResource::handle_post_request - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
00610         msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; // 4.01
00611     }
00612     if(coap_response) {
00613         coap_response->msg_code = msg_code;
00614     }
00615     return coap_response;
00616 }
00617 
00618 void M2MResource::notification_update()
00619 {
00620     tr_debug("M2MResource::notification_update()");
00621     M2MReportHandler *report_handler = M2MBase::report_handler();
00622     if(report_handler && is_observable()) {
00623         report_handler->set_notification_trigger();
00624     }
00625 }
00626 
00627 M2MResource::M2MExecuteParameter::M2MExecuteParameter()
00628 {
00629     _value = NULL;
00630     _value_length = 0;
00631     _object_name = "";
00632     _resource_name = "";
00633     _object_instance_id = 0;
00634 }
00635 
00636 M2MResource::M2MExecuteParameter::~M2MExecuteParameter()
00637 {
00638     if(_value) {
00639         free(_value);
00640     }
00641 }
00642 
00643 uint8_t *M2MResource::M2MExecuteParameter::get_argument_value() const
00644 {
00645     return _value;
00646 }
00647 
00648 uint16_t M2MResource::M2MExecuteParameter::get_argument_value_length() const
00649 {
00650     return _value_length;
00651 }
00652 
00653 const String& M2MResource::M2MExecuteParameter::get_argument_object_name() const
00654 {
00655     return _object_name;
00656 }
00657 
00658 const String& M2MResource::M2MExecuteParameter::get_argument_resource_name() const
00659 {
00660     return _resource_name;
00661 }
00662 
00663 uint16_t M2MResource::M2MExecuteParameter::get_argument_object_instance_id() const
00664 {
00665     return _object_instance_id;
00666 }