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