Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
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