Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 }
Generated on Tue Jul 12 2022 21:20:27 by
1.7.2