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: FXAS21002 FXOS8700Q
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 Tue Jul 12 2022 20:21:00 by
