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