Simulated product dispenser
Fork of mbed-cloud-workshop-connect-HTS221 by
m2mobjectinstance.cpp
00001 /* 00002 * Copyright (c) 2015 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "mbed-client/m2mobjectinstance.h" 00017 #include "mbed-client/m2mobject.h" 00018 #include "mbed-client/m2mconstants.h" 00019 #include "mbed-client/m2mresource.h" 00020 #include "mbed-client/m2mresource.h" 00021 #include "mbed-client/m2mobservationhandler.h" 00022 #include "mbed-client/m2mstring.h" 00023 #include "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 19:12:13 by 1.7.2