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