Ram Gandikota / Mbed OS ABCD
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers m2mobjectinstance.cpp Source File

m2mobjectinstance.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/m2mobjectinstance.h"
00017 #include "mbed-client/m2mobject.h"
00018 #include "mbed-client/m2mconstants.h"
00019 #include "mbed-client/m2mresource.h"
00020 #include "mbed-client/m2mresource.h"
00021 #include "mbed-client/m2mobservationhandler.h"
00022 #include "mbed-client/m2mstring.h"
00023 #include "mbed-client/m2mstringbuffer.h"
00024 #include "include/m2mtlvserializer.h"
00025 #include "include/m2mtlvdeserializer.h"
00026 #include "include/nsdllinker.h"
00027 #include "include/m2mreporthandler.h"
00028 #include "mbed-trace/mbed_trace.h"
00029 
00030 #include <stdlib.h>
00031 
00032 #define BUFFER_SIZE 10
00033 #define TRACE_GROUP "mClt"
00034 
00035 M2MObjectInstance::M2MObjectInstance(M2MObject& parent, const String &object_name,
00036                                      const String &resource_type,
00037                                      char *path,
00038                                      bool external_blockwise_store)
00039 : M2MBase(object_name,
00040           M2MBase::Dynamic,
00041           resource_type,
00042           path,
00043           external_blockwise_store),
00044   _parent(parent)
00045 {
00046     M2MBase::set_base_type(M2MBase::ObjectInstance);
00047     M2MBase::set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE);
00048 }
00049 
00050 M2MObjectInstance::M2MObjectInstance(M2MObject& parent, const lwm2m_parameters_s* static_res)
00051 : M2MBase(static_res), _parent(parent)
00052 {
00053     M2MBase::set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE);
00054 }
00055 
00056 M2MObjectInstance::~M2MObjectInstance()
00057 {
00058     if(!_resource_list.empty()) {
00059         M2MResource* res = NULL;
00060         M2MResourceList::const_iterator it;
00061         it = _resource_list.begin();
00062         for (; it!=_resource_list.end(); it++ ) {
00063             //Free allocated memory for resources.
00064             res = *it;
00065             delete res;
00066         }
00067         _resource_list.clear();
00068     }
00069 }
00070 
00071 // TBD, ResourceType to the base class struct?? TODO!
00072 M2MResource* M2MObjectInstance::create_static_resource(const lwm2m_parameters_s* static_res,
00073                                                        M2MResourceInstance::ResourceType type)
00074 {
00075     tr_debug("M2MObjectInstance::create_static_resource(lwm2m_parameters_s resource_name %s)", static_res->name);
00076     M2MResource *res = NULL;
00077     if (validate_string_length(static_res->name, 1, MAX_ALLOWED_STRING_LENGTH) == false) {
00078         return res;
00079     }
00080     if(!resource(static_res->name)) {
00081         res = new M2MResource(*this, static_res, type, (const uint16_t) M2MBase::instance_id());
00082         if(res) {
00083             res->add_observation_level(observation_level());
00084             //if (multiple_instance) {
00085                 //res->set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE);
00086             //}
00087             _resource_list.push_back(res);
00088         }
00089     }
00090     return res;
00091 }
00092 
00093 M2MResource* M2MObjectInstance::create_static_resource(const String &resource_name,
00094                                                        const String &resource_type,
00095                                                        M2MResourceInstance::ResourceType type,
00096                                                        const uint8_t *value,
00097                                                        const uint8_t value_length,
00098                                                        bool multiple_instance,
00099                                                        bool external_blockwise_store)
00100 {
00101     tr_debug("M2MObjectInstance::create_static_resource(resource_name %s)",resource_name.c_str());
00102     M2MResource *res = NULL;
00103     if (validate_string_length(resource_name, 1, MAX_ALLOWED_STRING_LENGTH) == false) {
00104         return res;
00105     }
00106     if(!resource(resource_name)) {
00107         char *path = create_path(*this, resource_name.c_str());
00108 
00109         if (path) {
00110             res = new M2MResource(*this, resource_name, resource_type, type,
00111                                   value, value_length, path, M2MBase::instance_id(),
00112                                   multiple_instance, external_blockwise_store);
00113             if(res) {
00114                 res->add_observation_level(observation_level());
00115                 if (multiple_instance) {
00116                     res->set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE);
00117                 }
00118                 _resource_list.push_back(res);
00119             }
00120         }
00121     }
00122     return res;
00123 }
00124 
00125 M2MResource* M2MObjectInstance::create_dynamic_resource(const lwm2m_parameters_s* static_res,
00126                                                         M2MResourceInstance::ResourceType type,
00127                                                         bool observable)
00128 {
00129     tr_debug("M2MObjectInstance::create_dynamic_resource(resource_name %s)", static_res->name);
00130     M2MResource *res = NULL;
00131 
00132     if (validate_string_length(static_res->name, 1, MAX_ALLOWED_STRING_LENGTH) == false) {
00133         return res;
00134     }
00135     if(!resource(static_res->name)) {
00136         res = new M2MResource(*this, static_res, type, M2MBase::instance_id());
00137         if(res) {
00138             //if (multiple_instance) { // TODO!
00139               //  res->set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE);
00140             //}
00141             res->add_observation_level(observation_level());
00142             _resource_list.push_back(res);
00143         }
00144     }
00145     return res;
00146 }
00147 
00148 M2MResource* M2MObjectInstance::create_dynamic_resource(const String &resource_name,
00149                                                 const String &resource_type,
00150                                                 M2MResourceInstance::ResourceType type,
00151                                                 bool observable,
00152                                                 bool multiple_instance,
00153                                                 bool external_blockwise_store)
00154 {
00155     tr_debug("M2MObjectInstance::create_dynamic_resource(resource_name %s)",resource_name.c_str());
00156     M2MResource *res = NULL;
00157     if (validate_string_length(resource_name, 1, MAX_ALLOWED_STRING_LENGTH) == false) {
00158         return res;
00159     }
00160     if(!resource(resource_name)) {
00161         char *path = create_path(*this, resource_name.c_str());
00162         if (path) {
00163             res = new M2MResource(*this, resource_name, resource_type, type,
00164                                   observable, path, M2MBase::instance_id(),
00165                                   multiple_instance, external_blockwise_store);
00166             if(res) {
00167                 if (multiple_instance) {
00168                     res->set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE);
00169                 }
00170                 res->add_observation_level(observation_level());
00171                 _resource_list.push_back(res);
00172             }
00173         }
00174     }
00175     return res;
00176 }
00177 
00178 M2MResourceInstance* M2MObjectInstance::create_static_resource_instance(const String &resource_name,
00179                                                                         const String &resource_type,
00180                                                                         M2MResourceInstance::ResourceType type,
00181                                                                         const uint8_t *value,
00182                                                                         const uint8_t value_length,
00183                                                                         uint16_t instance_id,
00184                                                                         bool external_blockwise_store)
00185 {
00186     tr_debug("M2MObjectInstance::create_static_resource_instance(resource_name %s)",resource_name.c_str());
00187     M2MResourceInstance *instance = NULL;
00188     if (validate_string_length(resource_name, 1, MAX_ALLOWED_STRING_LENGTH) == false) {
00189 
00190         return instance;
00191     }
00192     M2MResource *res = resource(resource_name);
00193     if(!res) {
00194         char *path = create_path(*this, resource_name.c_str());
00195         if (path) {
00196             res = new M2MResource(*this, resource_name, resource_type, type,
00197                                   value, value_length, path, M2MBase::instance_id(),
00198                                   true, external_blockwise_store);
00199             _resource_list.push_back(res);
00200             res->set_operation(M2MBase::GET_ALLOWED);
00201             res->set_observable(false);
00202             res->set_register_uri(false);
00203         }
00204     }
00205     if(res && res->supports_multiple_instances()&& (res->resource_instance(instance_id) == NULL)) {
00206         char *path = M2MBase::create_path(*res, instance_id);
00207         if (path) {
00208             instance = new M2MResourceInstance(*res, resource_name, resource_type, type,
00209                                                value, value_length,
00210                                                M2MBase::instance_id(),
00211                                                path, external_blockwise_store);
00212             if(instance) {
00213                 instance->set_operation(M2MBase::GET_ALLOWED);
00214                 instance->set_instance_id(instance_id);
00215                 res->add_resource_instance(instance);
00216             }
00217         }
00218     }
00219     return instance;
00220 }
00221 
00222 M2MResourceInstance* M2MObjectInstance::create_dynamic_resource_instance(const String &resource_name,
00223                                                                          const String &resource_type,
00224                                                                          M2MResourceInstance::ResourceType type,
00225                                                                          bool observable,
00226                                                                          uint16_t instance_id,
00227                                                                          bool external_blockwise_store)
00228 {
00229     tr_debug("M2MObjectInstance::create_dynamic_resource_instance(resource_name %s)",resource_name.c_str());
00230     M2MResourceInstance *instance = NULL;
00231     if (validate_string_length(resource_name, 1, MAX_ALLOWED_STRING_LENGTH) == false) {
00232         return instance;
00233     }
00234     M2MResource *res = resource(resource_name);
00235     if(!res) {
00236         char *path = create_path(*this, resource_name.c_str());
00237         if (path) {
00238             res = new M2MResource(*this, resource_name, resource_type, type,
00239                                   false, path, M2MBase::instance_id(), true);
00240             _resource_list.push_back(res);
00241             res->set_register_uri(false);
00242             res->set_operation(M2MBase::GET_ALLOWED);
00243         }
00244     }
00245     if (res && res->supports_multiple_instances() && (res->resource_instance(instance_id) == NULL)) {
00246         char *path = create_path(*res, instance_id);
00247         if (path) {
00248             instance = new M2MResourceInstance(*res, resource_name, resource_type, type,
00249                                                M2MBase::instance_id(),
00250                                                path, external_blockwise_store);
00251             if(instance) {
00252                 instance->set_operation(M2MBase::GET_ALLOWED);
00253                 instance->set_observable(observable);
00254                 instance->set_instance_id(instance_id);
00255                 res->add_resource_instance(instance);
00256             }
00257         }
00258     }
00259     return instance;
00260 }
00261 
00262 bool M2MObjectInstance::remove_resource(const String &resource_name)
00263 {
00264     return remove_resource(resource_name.c_str());
00265 }
00266 
00267 bool M2MObjectInstance::remove_resource(const char *resource_name)
00268 {
00269     tr_debug("M2MObjectInstance::remove_resource(resource_name %s)", resource_name);
00270 
00271     bool success = false;
00272     if(!_resource_list.empty()) {
00273          M2MResource* res = NULL;
00274          M2MResourceList::const_iterator it;
00275          it = _resource_list.begin();
00276          int pos = 0;
00277          for ( ; it != _resource_list.end(); it++, pos++ ) {
00278              if(strcmp((*it)->name(), resource_name) == 0) {
00279                 // Resource found and deleted.
00280                 res = *it;
00281                 delete res;
00282                 res = NULL;
00283                 _resource_list.erase(pos);
00284                 success = true;
00285                 break;
00286              }
00287          }
00288      }
00289     return success;
00290 }
00291 
00292 bool M2MObjectInstance::remove_resource_instance(const String &resource_name,
00293                                                  uint16_t inst_id)
00294 {
00295     tr_debug("M2MObjectInstance::remove_resource_instance(resource_name %s inst_id %d)",
00296              resource_name.c_str(), inst_id);
00297     bool success = false;
00298     M2MResource *res = resource(resource_name);
00299     if(res) {
00300         M2MResourceInstanceList list = res->resource_instances();
00301         M2MResourceInstanceList::const_iterator it;
00302         it = list.begin();
00303         for ( ; it != list.end(); it++) {
00304             if((*it)->instance_id() == inst_id) {
00305                 success = res->remove_resource_instance(inst_id);
00306                 if(res->resource_instance_count() == 0) {
00307                     M2MResourceList::const_iterator itr;
00308                     itr = _resource_list.begin();
00309                     int pos = 0;
00310                     for ( ; itr != _resource_list.end(); itr++, pos++ ) {
00311                         if(strcmp((*itr)->name(),resource_name.c_str()) == 0) {
00312                             delete res;
00313                             res = NULL;
00314                             _resource_list.erase(pos);
00315                             break;
00316                         }
00317                     }
00318                 }
00319                 break;
00320             }
00321         }
00322     }
00323     return success;
00324 }
00325 
00326 M2MResource* M2MObjectInstance::resource(const String &resource_name) const
00327 {
00328     return resource(resource_name.c_str());
00329 }
00330 
00331 M2MResource* M2MObjectInstance::resource(const char *resource_name) const
00332 {
00333     M2MResource *res = NULL;
00334     if(!_resource_list.empty()) {
00335         M2MResourceList::const_iterator it;
00336         it = _resource_list.begin();
00337         for (; it!=_resource_list.end(); it++ ) {
00338             if(strcmp((*it)->name(), resource_name) == 0) {
00339                 res = *it;
00340                 break;
00341             }
00342         }
00343     }
00344     return res;
00345 }
00346 
00347 const M2MResourceList& M2MObjectInstance::resources() const
00348 {
00349     return _resource_list;
00350 }
00351 
00352 uint16_t M2MObjectInstance::resource_count() const
00353 {
00354     uint16_t count = 0;
00355     if(!_resource_list.empty()) {
00356         M2MResourceList::const_iterator it;
00357         it = _resource_list.begin();
00358         for ( ; it != _resource_list.end(); it++ ) {
00359             if((*it)->supports_multiple_instances()) {
00360                 count += (*it)->resource_instance_count();
00361             } else {
00362                 count++;
00363             }
00364         }
00365     }
00366     return count;
00367 }
00368 
00369 uint16_t M2MObjectInstance::resource_count(const String& resource) const
00370 {
00371 
00372     return resource_count(resource.c_str());
00373 }
00374 
00375 uint16_t M2MObjectInstance::resource_count(const char *resource) const
00376 {
00377     uint16_t count = 0;
00378     if(!_resource_list.empty()) {
00379         M2MResourceList::const_iterator it;
00380         it = _resource_list.begin();
00381         for ( ; it != _resource_list.end(); it++ ) {
00382             if(strcmp((*it)->name(), resource) == 0) {
00383                 if((*it)->supports_multiple_instances()) {
00384                     count += (*it)->resource_instance_count();
00385                 } else {
00386                     count++;
00387                 }
00388             }
00389         }
00390     }
00391     return count;
00392 }
00393 
00394 M2MBase::BaseType M2MObjectInstance::base_type() const
00395 {
00396     return M2MBase::base_type();
00397 }
00398 
00399 void M2MObjectInstance::add_observation_level(M2MBase::Observation observation_level)
00400 {
00401     M2MBase::add_observation_level(observation_level);
00402     if(!_resource_list.empty()) {
00403         M2MResourceList::const_iterator it;
00404         it = _resource_list.begin();
00405         for ( ; it != _resource_list.end(); it++ ) {
00406             (*it)->add_observation_level(observation_level);
00407         }
00408     }
00409 }
00410 
00411 void M2MObjectInstance::remove_observation_level(M2MBase::Observation observation_level)
00412 {
00413     M2MBase::remove_observation_level(observation_level);
00414     if(!_resource_list.empty()) {
00415         M2MResourceList::const_iterator it;
00416         it = _resource_list.begin();
00417         for ( ; it != _resource_list.end(); it++ ) {
00418            (*it)->remove_observation_level(observation_level);
00419         }
00420     }
00421 }
00422 
00423 sn_coap_hdr_s* M2MObjectInstance::handle_get_request(nsdl_s *nsdl,
00424                                                      sn_coap_hdr_s *received_coap_header,
00425                                                      M2MObservationHandler *observation_handler)
00426 {
00427     tr_debug("M2MObjectInstance::handle_get_request()");
00428     sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CONTENT;
00429     sn_coap_hdr_s * coap_response = sn_nsdl_build_response(nsdl,
00430                                                            received_coap_header,
00431                                                            msg_code);
00432     uint8_t * data = NULL;
00433     uint32_t  data_length = 0;
00434     if(received_coap_header) {
00435         // process the GET if we have registered a callback for it
00436         if ((operation() & SN_GRS_GET_ALLOWED) != 0) {
00437             if(coap_response) {
00438                 uint16_t coap_content_type = 0;
00439                 bool content_type_present = false;
00440 
00441                 if(received_coap_header->content_format != COAP_CT_NONE) {
00442                     content_type_present = true;
00443                     coap_content_type = received_coap_header->content_format;
00444                 }
00445                 if(!content_type_present &&
00446                    M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE) {
00447                     coap_content_type = COAP_CONTENT_OMA_TLV_TYPE;
00448                 }
00449 
00450                 tr_debug("M2MObjectInstance::handle_get_request() - Request Content-Type %d", coap_content_type);
00451                 if (coap_response->content_format == COAP_CT_NONE) {
00452                     coap_response->content_format = sn_coap_content_format_e(coap_content_type);
00453 
00454                     if (coap_response->content_format != COAP_CT_NONE) {
00455                         set_coap_content_type(coap_content_type);
00456                     }
00457                 }
00458                 // fill in the CoAP response payload
00459                 if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) {
00460                     M2MTLVSerializer serializer;
00461                     data = serializer.serialize(_resource_list, data_length);
00462                 } else {
00463                     msg_code = COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT; // Content format not supported
00464                 }
00465 
00466                 coap_response->payload_len = data_length;
00467                 coap_response->payload_ptr = data;
00468 
00469                 if(data) {
00470                     coap_response->options_list_ptr = sn_nsdl_alloc_options_list(nsdl, coap_response);
00471 
00472                     coap_response->options_list_ptr->max_age = max_age();
00473 
00474                     if(received_coap_header->options_list_ptr) {
00475                         if(received_coap_header->options_list_ptr->observe != -1) {
00476                             if (is_observable()) {
00477                                 uint32_t number = 0;
00478                                 uint8_t observe_option = 0;
00479                                 observe_option = received_coap_header->options_list_ptr->observe;
00480                                 if(START_OBSERVATION == observe_option) {
00481                                     tr_debug("M2MObjectInstance::handle_get_request - Starts Observation");
00482                                     // If the observe length is 0 means register for observation.
00483                                     if(received_coap_header->options_list_ptr->observe != -1) {
00484                                         number = received_coap_header->options_list_ptr->observe;
00485                                     }
00486                                     if(received_coap_header->token_ptr) {
00487                                         tr_debug("M2MObjectInstance::handle_get_request - Sets Observation Token to resource");
00488                                         set_observation_token(received_coap_header->token_ptr,
00489                                                               received_coap_header->token_len);
00490                                     }
00491 
00492                                     // If the observe value is 0 means register for observation.
00493                                     if(number == 0) {
00494                                         tr_debug("M2MObjectInstance::handle_get_request - Put Resource under Observation");
00495                                         set_under_observation(true,observation_handler);
00496                                         add_observation_level(M2MBase::OI_Attribute);
00497                                         coap_response->options_list_ptr->observe = observation_number();
00498                                     }
00499                                 } else if (STOP_OBSERVATION == observe_option) {
00500                                     tr_debug("M2MObjectInstance::handle_get_request - Stops Observation");
00501                                     set_under_observation(false,NULL);
00502                                     remove_observation_level(M2MBase::OI_Attribute);
00503 
00504                                 }
00505                                 msg_code = COAP_MSG_CODE_RESPONSE_CONTENT;
00506                             }
00507                             else {
00508                                 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00509                             }
00510                         }
00511                     }
00512                 } else {
00513                     msg_code = COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT; // Content format not supported
00514                 }
00515             }
00516         }else {
00517             tr_error("M2MObjectInstance::handle_get_request - Return COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
00518             // Operation is not allowed.
00519             msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00520         }
00521     } else {
00522         msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00523     }
00524     if(coap_response) {
00525         coap_response->msg_code = msg_code;
00526     }
00527     return coap_response;
00528 }
00529 
00530 sn_coap_hdr_s* M2MObjectInstance::handle_put_request(nsdl_s *nsdl,
00531                                                      sn_coap_hdr_s *received_coap_header,
00532                                                      M2MObservationHandler *observation_handler,
00533                                                      bool &/*execute_value_updated*/)
00534 {
00535     tr_debug("M2MObjectInstance::handle_put_request()");
00536     sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04
00537     sn_coap_hdr_s * coap_response = sn_nsdl_build_response(nsdl,
00538                                                            received_coap_header,
00539                                                            msg_code);;
00540     if(received_coap_header) {
00541         uint16_t coap_content_type = 0;
00542         bool content_type_present = false;
00543         if(received_coap_header->content_format != COAP_CT_NONE) {
00544             content_type_present = true;
00545             if(coap_response) {
00546                 coap_content_type = received_coap_header->content_format;
00547             }
00548         }
00549         if(received_coap_header->options_list_ptr &&
00550            received_coap_header->options_list_ptr->uri_query_ptr) {
00551             char *query = (char*)alloc_string_copy(received_coap_header->options_list_ptr->uri_query_ptr,
00552                                                     received_coap_header->options_list_ptr->uri_query_len);
00553             if (query){
00554                 tr_debug("M2MObjectInstance::handle_put_request() - Query %s", query);
00555                 // if anything was updated, re-initialize the stored notification attributes
00556                 if (!handle_observation_attribute(query)){
00557                     tr_debug("M2MObjectInstance::handle_put_request() - Invalid query");
00558                     msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // 4.00
00559                 } else {
00560                     msg_code =COAP_MSG_CODE_RESPONSE_CHANGED;
00561                 }
00562                 free(query);
00563             }
00564         } else if ((operation() & SN_GRS_PUT_ALLOWED) != 0) {
00565             if(!content_type_present &&
00566                M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE) {
00567                 coap_content_type = COAP_CONTENT_OMA_TLV_TYPE;
00568             }
00569 
00570             tr_debug("M2MObjectInstance::handle_put_request() - Request Content-Type %d", coap_content_type);
00571 
00572             if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) {
00573                 M2MTLVDeserializer::Error error = M2MTLVDeserializer::None;
00574                 M2MTLVDeserializer deserializer;
00575                 if(received_coap_header->payload_ptr) {
00576                     error = deserializer.deserialize_resources(received_coap_header->payload_ptr,
00577                                                                 received_coap_header->payload_len,
00578                                                                 *this,
00579                                                                 M2MTLVDeserializer::Put);
00580                     switch(error) {
00581                         case M2MTLVDeserializer::None:
00582                             if(observation_handler) {
00583                                 observation_handler->value_updated(this);
00584                             }
00585                             msg_code = COAP_MSG_CODE_RESPONSE_CHANGED;
00586                             break;
00587                         case M2MTLVDeserializer::NotFound:
00588                             msg_code = COAP_MSG_CODE_RESPONSE_NOT_FOUND;
00589                             break;
00590                         case M2MTLVDeserializer::NotAllowed:
00591                             msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00592                             break;
00593                         case M2MTLVDeserializer::NotValid:
00594                             msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
00595                             break;
00596                     }
00597                 }
00598             } else {
00599                 msg_code =COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT;
00600             } // if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type)
00601         } else {
00602             // Operation is not allowed.
00603             tr_error("M2MObjectInstance::handle_put_request() - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
00604             msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00605         }
00606     } else {
00607        msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00608     }
00609     if(coap_response) {
00610         coap_response->msg_code = msg_code;
00611     }
00612     return coap_response;
00613 }
00614 
00615 
00616 
00617 
00618 sn_coap_hdr_s* M2MObjectInstance::handle_post_request(nsdl_s *nsdl,
00619                                                       sn_coap_hdr_s *received_coap_header,
00620                                                       M2MObservationHandler *observation_handler,
00621                                                       bool &execute_value_updated,
00622                                                       sn_nsdl_addr_s *)
00623 {
00624     tr_debug("M2MObjectInstance::handle_post_request()");
00625     sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04
00626     sn_coap_hdr_s * coap_response = sn_nsdl_build_response(nsdl,
00627                                                            received_coap_header,
00628                                                            msg_code);
00629     if(received_coap_header) {
00630         if ((operation() & SN_GRS_POST_ALLOWED) != 0) {
00631             uint16_t coap_content_type = 0;
00632             bool content_type_present = false;
00633             if(received_coap_header->content_format != COAP_CT_NONE) {
00634                 content_type_present = true;
00635                 if(coap_response) {
00636                     coap_content_type = received_coap_header->content_format;
00637                 }
00638             }
00639             if(!content_type_present &&
00640                M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE) {
00641                 coap_content_type = COAP_CONTENT_OMA_TLV_TYPE;
00642             }
00643 
00644             tr_debug("M2MObjectInstance::handle_post_request() - Request Content-Type %d", coap_content_type);
00645 
00646             if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) {
00647                 M2MTLVDeserializer deserializer;
00648                 M2MTLVDeserializer::Error error = M2MTLVDeserializer::None;
00649                 error = deserializer.deserialize_resources(received_coap_header->payload_ptr,
00650                                                             received_coap_header->payload_len,
00651                                                             *this,
00652                                                             M2MTLVDeserializer::Post);
00653 
00654                 uint16_t instance_id = deserializer.instance_id(received_coap_header->payload_ptr);
00655                 switch(error) {
00656                     case M2MTLVDeserializer::None:
00657                         if(observation_handler) {
00658                             execute_value_updated = true;
00659                         }
00660                         coap_response->options_list_ptr = sn_nsdl_alloc_options_list(nsdl, coap_response);
00661 
00662                         if (coap_response->options_list_ptr) {
00663 
00664                               StringBuffer<MAX_PATH_SIZE_3> obj_name;
00665                               if(!build_path(obj_name, M2MBase::name(), M2MBase::instance_id(), instance_id))
00666                               {
00667                                   msg_code = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
00668                                   break;
00669                               }
00670 
00671                               coap_response->options_list_ptr->location_path_len = obj_name.get_size();
00672                               coap_response->options_list_ptr->location_path_ptr =
00673                                   alloc_string_copy((uint8_t*)obj_name.c_str(),
00674                                                     coap_response->options_list_ptr->location_path_len);
00675                               // todo: handle allocation error
00676                         }
00677                         msg_code = COAP_MSG_CODE_RESPONSE_CREATED;
00678                         break;
00679                     case M2MTLVDeserializer::NotAllowed:
00680                         msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00681                         break;
00682                     case M2MTLVDeserializer::NotValid:
00683                         msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
00684                         break;
00685                     default:
00686                         break;
00687                 }
00688             } else {
00689                 msg_code =COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT;
00690             } // if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type)
00691         } else {
00692             // Operation is not allowed.
00693             tr_error("M2MObjectInstance::handle_post_request() - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
00694             msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00695         }
00696     } else {
00697         msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00698     }
00699     if(coap_response) {
00700         coap_response->msg_code = msg_code;
00701     }
00702     return coap_response;
00703 }
00704 
00705 void M2MObjectInstance::notification_update(M2MBase::Observation observation_level)
00706 {
00707     tr_debug("M2MObjectInstance::notification_update() - level(%d)", observation_level);
00708     if((M2MBase::O_Attribute & observation_level) == M2MBase::O_Attribute) {
00709         tr_debug("M2MObjectInstance::notification_update() - object callback");
00710         _parent.notification_update(instance_id());
00711     }
00712     if((M2MBase::OI_Attribute & observation_level) == M2MBase::OI_Attribute) {
00713         tr_debug("M2MObjectInstance::notification_update() - object instance callback");
00714         M2MReportHandler *report_handler = M2MBase::report_handler();
00715         if(report_handler && is_under_observation()) {
00716             report_handler->set_notification_trigger();
00717         }
00718 
00719     }
00720 }