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() & SN_GRS_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 if (is_observable()) { 00500 uint32_t number = 0; 00501 uint8_t observe_option = 0; 00502 observe_option = received_coap_header->options_list_ptr->observe; 00503 if (START_OBSERVATION == observe_option) { 00504 // If the observe length is 0 means register for observation. 00505 if (received_coap_header->options_list_ptr->observe != -1) { 00506 number = received_coap_header->options_list_ptr->observe; 00507 } 00508 00509 // If the observe value is 0 means register for observation. 00510 if (number == 0) { 00511 tr_info("M2MObjectInstance::handle_get_request - put resource under observation"); 00512 set_under_observation(true,observation_handler); 00513 add_observation_level(M2MBase::OI_Attribute); 00514 send_notification_delivery_status(*this, NOTIFICATION_STATUS_SUBSCRIBED); 00515 if (coap_response->options_list_ptr) { 00516 coap_response->options_list_ptr->observe = observation_number(); 00517 } 00518 } 00519 00520 if (received_coap_header->token_ptr) { 00521 set_observation_token(received_coap_header->token_ptr, 00522 received_coap_header->token_len); 00523 } 00524 00525 } else if (STOP_OBSERVATION == observe_option) { 00526 tr_info("M2MObjectInstance::handle_get_request - stops observation"); 00527 set_under_observation(false,NULL); 00528 remove_observation_level(M2MBase::OI_Attribute); 00529 send_notification_delivery_status(*this, NOTIFICATION_STATUS_UNSUBSCRIBED); 00530 } 00531 msg_code = COAP_MSG_CODE_RESPONSE_CONTENT; 00532 } 00533 else { 00534 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00535 } 00536 } 00537 } 00538 } else { 00539 msg_code = COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT; // Content format not supported 00540 } 00541 } else { 00542 tr_error("M2MObjectInstance::handle_get_request() - Content-type: %d not supported", coap_response->content_format); 00543 msg_code = COAP_MSG_CODE_RESPONSE_NOT_ACCEPTABLE; 00544 } 00545 } 00546 } else { 00547 tr_error("M2MObjectInstance::handle_get_request - Return COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED"); 00548 // Operation is not allowed. 00549 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00550 } 00551 } else { 00552 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00553 } 00554 if(coap_response) { 00555 coap_response->msg_code = msg_code; 00556 } 00557 return coap_response; 00558 } 00559 00560 sn_coap_hdr_s* M2MObjectInstance::handle_put_request(nsdl_s *nsdl, 00561 sn_coap_hdr_s *received_coap_header, 00562 M2MObservationHandler *observation_handler, 00563 bool &/*execute_value_updated*/) 00564 { 00565 tr_info("M2MObjectInstance::handle_put_request()"); 00566 sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04 00567 sn_coap_hdr_s * coap_response = sn_nsdl_build_response(nsdl, 00568 received_coap_header, 00569 msg_code);; 00570 if(received_coap_header) { 00571 uint16_t coap_content_type = 0; 00572 bool content_type_present = false; 00573 00574 if(received_coap_header->content_format != COAP_CT_NONE) { 00575 content_type_present = true; 00576 set_coap_content_type(received_coap_header->content_format); 00577 if(coap_response) { 00578 coap_content_type = received_coap_header->content_format; 00579 } 00580 } 00581 if(received_coap_header->options_list_ptr && 00582 received_coap_header->options_list_ptr->uri_query_ptr) { 00583 char *query = (char*)alloc_string_copy(received_coap_header->options_list_ptr->uri_query_ptr, 00584 received_coap_header->options_list_ptr->uri_query_len); 00585 if (query){ 00586 tr_info("M2MObjectInstance::handle_put_request() - query %s", query); 00587 // if anything was updated, re-initialize the stored notification attributes 00588 if (!handle_observation_attribute(query)){ 00589 tr_debug("M2MObjectInstance::handle_put_request() - Invalid query"); 00590 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // 4.00 00591 } else { 00592 msg_code =COAP_MSG_CODE_RESPONSE_CHANGED; 00593 } 00594 free(query); 00595 } 00596 } else if ((operation() & SN_GRS_PUT_ALLOWED) != 0) { 00597 if(!content_type_present && 00598 (M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE || 00599 M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE_OLD)) { 00600 coap_content_type = M2MBase::coap_content_type(); 00601 } 00602 00603 tr_debug("M2MObjectInstance::handle_put_request() - Request Content-type: %d", coap_content_type); 00604 00605 if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type || 00606 COAP_CONTENT_OMA_TLV_TYPE_OLD == coap_content_type ) { 00607 set_coap_content_type(coap_content_type); 00608 M2MTLVDeserializer::Error error = M2MTLVDeserializer::None; 00609 if(received_coap_header->payload_ptr) { 00610 error = M2MTLVDeserializer::deserialize_resources( 00611 received_coap_header->payload_ptr, 00612 received_coap_header->payload_len, *this, 00613 M2MTLVDeserializer::Put); 00614 switch(error) { 00615 case M2MTLVDeserializer::None: 00616 if(observation_handler) { 00617 observation_handler->value_updated(this); 00618 } 00619 msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; 00620 break; 00621 case M2MTLVDeserializer::NotFound: 00622 msg_code = COAP_MSG_CODE_RESPONSE_NOT_FOUND; 00623 break; 00624 case M2MTLVDeserializer::NotAllowed: 00625 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00626 break; 00627 case M2MTLVDeserializer::NotValid: 00628 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 00629 break; 00630 case M2MTLVDeserializer::OutOfMemory: 00631 msg_code = COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE; 00632 break; 00633 } 00634 } 00635 } else { 00636 msg_code =COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT; 00637 } // if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) 00638 } else { 00639 // Operation is not allowed. 00640 tr_error("M2MObjectInstance::handle_put_request() - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED"); 00641 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00642 } 00643 } else { 00644 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00645 } 00646 if(coap_response) { 00647 coap_response->msg_code = msg_code; 00648 } 00649 return coap_response; 00650 } 00651 00652 sn_coap_hdr_s* M2MObjectInstance::handle_post_request(nsdl_s *nsdl, 00653 sn_coap_hdr_s *received_coap_header, 00654 M2MObservationHandler *observation_handler, 00655 bool &execute_value_updated, 00656 sn_nsdl_addr_s *) 00657 { 00658 tr_info("M2MObjectInstance::handle_post_request()"); 00659 sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04 00660 sn_coap_hdr_s * coap_response = sn_nsdl_build_response(nsdl, 00661 received_coap_header, 00662 msg_code); 00663 if(received_coap_header) { 00664 if ((operation() & SN_GRS_POST_ALLOWED) != 0) { 00665 uint16_t coap_content_type = 0; 00666 bool content_type_present = false; 00667 if(received_coap_header->content_format != COAP_CT_NONE) { 00668 set_coap_content_type(received_coap_header->content_format); 00669 content_type_present = true; 00670 if(coap_response) { 00671 coap_content_type = received_coap_header->content_format; 00672 } 00673 } 00674 if(!content_type_present && 00675 (M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE || 00676 M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE_OLD)) { 00677 coap_content_type = M2MBase::coap_content_type(); 00678 } 00679 00680 tr_debug("M2MObjectInstance::handle_post_request() - Request Content-type: %d", coap_content_type); 00681 00682 if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type || 00683 COAP_CONTENT_OMA_TLV_TYPE_OLD == coap_content_type) { 00684 set_coap_content_type(coap_content_type); 00685 M2MTLVDeserializer::Error error = M2MTLVDeserializer::None; 00686 error = M2MTLVDeserializer::deserialize_resources( 00687 received_coap_header->payload_ptr, 00688 received_coap_header->payload_len, *this, 00689 M2MTLVDeserializer::Post); 00690 00691 uint16_t instance_id = M2MTLVDeserializer::instance_id(received_coap_header->payload_ptr); 00692 switch(error) { 00693 case M2MTLVDeserializer::None: 00694 if(observation_handler) { 00695 execute_value_updated = true; 00696 } 00697 coap_response->options_list_ptr = sn_nsdl_alloc_options_list(nsdl, coap_response); 00698 00699 if (coap_response->options_list_ptr) { 00700 00701 StringBuffer<MAX_PATH_SIZE_3> obj_name; 00702 if(!build_path(obj_name, _parent.name(), M2MBase::instance_id(), instance_id)) { 00703 msg_code = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR; 00704 break; 00705 } 00706 00707 coap_response->options_list_ptr->location_path_len = obj_name.get_size(); 00708 coap_response->options_list_ptr->location_path_ptr = 00709 alloc_string_copy((uint8_t*)obj_name.c_str(), 00710 coap_response->options_list_ptr->location_path_len); 00711 // todo: handle allocation error 00712 } 00713 msg_code = COAP_MSG_CODE_RESPONSE_CREATED; 00714 break; 00715 case M2MTLVDeserializer::NotAllowed: 00716 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00717 break; 00718 case M2MTLVDeserializer::NotValid: 00719 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 00720 break; 00721 case M2MTLVDeserializer::NotFound: 00722 msg_code = COAP_MSG_CODE_RESPONSE_NOT_FOUND; 00723 break; 00724 case M2MTLVDeserializer::OutOfMemory: 00725 msg_code = COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE; 00726 break; 00727 default: 00728 break; 00729 } 00730 } else { 00731 msg_code =COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT; 00732 } // if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) 00733 } else { 00734 // Operation is not allowed. 00735 tr_error("M2MObjectInstance::handle_post_request() - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED"); 00736 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00737 } 00738 } else { 00739 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00740 } 00741 if(coap_response) { 00742 coap_response->msg_code = msg_code; 00743 } 00744 return coap_response; 00745 } 00746 00747 void M2MObjectInstance::notification_update(M2MBase::Observation observation_level) 00748 { 00749 tr_debug("M2MObjectInstance::notification_update() - level(%d)", observation_level); 00750 if((M2MBase::O_Attribute & observation_level) == M2MBase::O_Attribute) { 00751 tr_debug("M2MObjectInstance::notification_update() - object callback"); 00752 _parent.notification_update(instance_id()); 00753 } 00754 if((M2MBase::OI_Attribute & observation_level) == M2MBase::OI_Attribute) { 00755 tr_debug("M2MObjectInstance::notification_update() - object instance callback"); 00756 M2MReportHandler *report_handler = M2MBase::report_handler(); 00757 if(report_handler && is_under_observation()) { 00758 report_handler->set_notification_trigger(); 00759 } 00760 00761 } 00762 } 00763 00764 M2MBase *M2MObjectInstance::get_parent() const 00765 { 00766 return (M2MBase *) &get_parent_object(); 00767 } 00768 00769 M2MBase::DataType M2MObjectInstance::convert_resource_type(M2MResourceInstance::ResourceType type) 00770 { 00771 M2MBase::DataType data_type = M2MBase::OBJLINK; 00772 switch(type) { 00773 case M2MResourceInstance::STRING: 00774 data_type = M2MBase::STRING; 00775 break; 00776 case M2MResourceInstance::INTEGER: 00777 data_type = M2MBase::INTEGER; 00778 break; 00779 case M2MResourceInstance::FLOAT: 00780 data_type = M2MBase::FLOAT; 00781 break; 00782 case M2MResourceInstance::OPAQUE: 00783 data_type = M2MBase::OPAQUE; 00784 break; 00785 case M2MResourceInstance::BOOLEAN: 00786 data_type = M2MBase::BOOLEAN; 00787 break; 00788 case M2MResourceInstance::TIME: 00789 data_type = M2MBase::TIME; 00790 break; 00791 case M2MResourceInstance::OBJLINK: 00792 data_type = M2MBase::OBJLINK; 00793 break; 00794 } 00795 return data_type; 00796 }
Generated on Tue Jul 12 2022 16:24:15 by
1.7.2