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.
Dependencies: MAX44000 PWM_Tone_Library nexpaq_mdk
Fork of LED_Demo by
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:28:38 by
