Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
m2mresource.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/m2mconstants.h" 00017 #include "mbed-client/m2mresource.h" 00018 #include "mbed-client/m2mobservationhandler.h" 00019 #include "include/m2mreporthandler.h" 00020 #include "include/m2mtlvserializer.h" 00021 #include "include/m2mtlvdeserializer.h" 00022 #include "mbed-trace/mbed_trace.h" 00023 00024 #include <stdlib.h> 00025 00026 #define TRACE_GROUP "mClt" 00027 00028 M2MResource::M2MResource(M2MObjectInstance &parent, 00029 const String &resource_name, 00030 M2MBase::Mode resource_mode, 00031 const String &resource_type, 00032 M2MBase::DataType type, 00033 const uint8_t *value, 00034 const uint8_t value_length, 00035 char *path, 00036 bool multiple_instance, 00037 bool external_blockwise_store) 00038 : M2MResourceBase(resource_name, resource_mode, resource_type, type, value, value_length, 00039 path, external_blockwise_store, multiple_instance), 00040 _parent(parent) 00041 #ifndef DISABLE_DELAYED_RESPONSE 00042 ,_delayed_token(NULL), 00043 _delayed_token_len(0), 00044 _delayed_response(false) 00045 #endif 00046 { 00047 M2MBase::set_base_type(M2MBase::Resource); 00048 M2MBase::set_operation(M2MBase::GET_ALLOWED); 00049 M2MBase::set_observable(false); 00050 if (multiple_instance) { 00051 M2MBase::set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE_OLD); 00052 } 00053 00054 } 00055 00056 M2MResource::M2MResource(M2MObjectInstance &parent, 00057 const lwm2m_parameters_s* s, 00058 M2MBase::DataType type) 00059 : M2MResourceBase(s, type), 00060 _parent(parent) 00061 #ifndef DISABLE_DELAYED_RESPONSE 00062 ,_delayed_token(NULL), 00063 _delayed_token_len(0), 00064 _delayed_response(false) 00065 #endif 00066 { 00067 // verify, that the client has hardcoded proper type to the structure 00068 assert(base_type() == M2MBase::Resource); 00069 } 00070 00071 M2MResource::M2MResource(M2MObjectInstance &parent, 00072 const String &resource_name, 00073 M2MBase::Mode resource_mode, 00074 const String &resource_type, 00075 M2MBase::DataType type, 00076 bool observable, 00077 char *path, 00078 bool multiple_instance, 00079 bool external_blockwise_store) 00080 : M2MResourceBase(resource_name, resource_mode, resource_type, type, 00081 path, 00082 external_blockwise_store,multiple_instance), 00083 _parent(parent) 00084 #ifndef DISABLE_DELAYED_RESPONSE 00085 ,_delayed_token(NULL), 00086 _delayed_token_len(0), 00087 _delayed_response(false) 00088 #endif 00089 { 00090 M2MBase::set_base_type(M2MBase::Resource); 00091 M2MBase::set_operation(M2MBase::GET_PUT_ALLOWED); 00092 M2MBase::set_observable(observable); 00093 if (multiple_instance) { 00094 M2MBase::set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE_OLD); 00095 } 00096 } 00097 00098 00099 M2MResource::~M2MResource() 00100 { 00101 if(!_resource_instance_list.empty()) { 00102 M2MResourceInstance* res = NULL; 00103 M2MResourceInstanceList::const_iterator it; 00104 it = _resource_instance_list.begin(); 00105 for (; it!=_resource_instance_list.end(); it++ ) { 00106 //Free allocated memory for resources. 00107 res = *it; 00108 delete res; 00109 } 00110 _resource_instance_list.clear(); 00111 } 00112 #ifndef DISABLE_DELAYED_RESPONSE 00113 free(_delayed_token); 00114 #endif 00115 00116 free_resources(); 00117 } 00118 00119 bool M2MResource::supports_multiple_instances() const 00120 { 00121 M2MBase::lwm2m_parameters_s* param = M2MBase::get_lwm2m_parameters(); 00122 return param->multiple_instance; 00123 } 00124 00125 #ifndef DISABLE_DELAYED_RESPONSE 00126 void M2MResource::set_delayed_response(bool delayed_response) 00127 { 00128 _delayed_response = delayed_response; 00129 } 00130 00131 bool M2MResource::send_delayed_post_response() 00132 { 00133 bool success = false; 00134 if(_delayed_response) { 00135 success = true; 00136 // At least on some unit tests the resource object is not fully constructed, which would 00137 // cause issues if the observation_handler is NULL. So do the check before dereferencing pointer. 00138 M2MObservationHandler* obs = observation_handler(); 00139 if (obs) { 00140 obs->send_delayed_response(this); 00141 } 00142 } 00143 return success; 00144 } 00145 00146 void M2MResource::get_delayed_token(uint8_t *&token, uint8_t &token_length) 00147 { 00148 token_length = 0; 00149 if(token) { 00150 free(token); 00151 token = NULL; 00152 } 00153 if(_delayed_token && _delayed_token_len > 0) { 00154 token = alloc_copy(_delayed_token, _delayed_token_len); 00155 if(token) { 00156 token_length = _delayed_token_len; 00157 } 00158 } 00159 } 00160 #endif 00161 00162 bool M2MResource::remove_resource_instance(uint16_t inst_id) 00163 { 00164 tr_debug("M2MResource::remove_resource(inst_id %d)", inst_id); 00165 bool success = false; 00166 if(!_resource_instance_list.empty()) { 00167 M2MResourceInstance* res = NULL; 00168 M2MResourceInstanceList::const_iterator it; 00169 it = _resource_instance_list.begin(); 00170 int pos = 0; 00171 for ( ; it != _resource_instance_list.end(); it++, pos++ ) { 00172 if(((*it)->instance_id() == inst_id)) { 00173 // Resource found and deleted. 00174 res = *it; 00175 delete res; 00176 _resource_instance_list.erase(pos); 00177 success = true; 00178 break; 00179 } 00180 } 00181 } 00182 return success; 00183 } 00184 00185 M2MResourceInstance* M2MResource::resource_instance(uint16_t inst_id) const 00186 { 00187 tr_debug("M2MResource::resource(resource_name inst_id %d)", inst_id); 00188 M2MResourceInstance *res = NULL; 00189 if(!_resource_instance_list.empty()) { 00190 M2MResourceInstanceList::const_iterator it; 00191 it = _resource_instance_list.begin(); 00192 for ( ; it != _resource_instance_list.end(); it++ ) { 00193 if(((*it)->instance_id() == inst_id)) { 00194 // Resource found. 00195 res = *it; 00196 break; 00197 } 00198 } 00199 } 00200 return res; 00201 } 00202 00203 const M2MResourceInstanceList& M2MResource::resource_instances() const 00204 { 00205 return _resource_instance_list; 00206 } 00207 00208 uint16_t M2MResource::resource_instance_count() const 00209 { 00210 return (uint16_t)_resource_instance_list.size(); 00211 } 00212 00213 #ifndef DISABLE_DELAYED_RESPONSE 00214 bool M2MResource::delayed_response() const 00215 { 00216 return _delayed_response; 00217 } 00218 #endif 00219 00220 M2MObservationHandler* M2MResource::observation_handler() const 00221 { 00222 const M2MObjectInstance& parent_object_instance = get_parent_object_instance(); 00223 00224 // XXX: need to check the flag too 00225 return parent_object_instance.observation_handler(); 00226 } 00227 00228 void M2MResource::set_observation_handler(M2MObservationHandler *handler) 00229 { 00230 M2MObjectInstance& parent_object_instance = get_parent_object_instance(); 00231 00232 // XXX: need to set the flag too 00233 parent_object_instance.set_observation_handler(handler); 00234 } 00235 00236 bool M2MResource::handle_observation_attribute(const char *query) 00237 { 00238 tr_debug("M2MResource::handle_observation_attribute - is_under_observation(%d)", is_under_observation()); 00239 bool success = false; 00240 M2MReportHandler *handler = M2MBase::report_handler(); 00241 if (!handler) { 00242 handler = M2MBase::create_report_handler(); 00243 } 00244 00245 if (handler) { 00246 success = handler->parse_notification_attribute(query, 00247 M2MBase::base_type(), resource_instance_type()); 00248 if (success) { 00249 if (is_under_observation()) { 00250 handler->set_under_observation(true); 00251 } 00252 } 00253 else { 00254 handler->set_default_values(); 00255 } 00256 00257 if (success) { 00258 if(!_resource_instance_list.empty()) { 00259 M2MResourceInstanceList::const_iterator it; 00260 it = _resource_instance_list.begin(); 00261 for ( ; it != _resource_instance_list.end(); it++ ) { 00262 M2MReportHandler *report_handler = (*it)->report_handler(); 00263 if(report_handler && is_under_observation()) { 00264 report_handler->set_notification_trigger(); 00265 } 00266 } 00267 } 00268 } 00269 } 00270 return success; 00271 } 00272 00273 void M2MResource::add_observation_level(M2MBase::Observation observation_level) 00274 { 00275 M2MBase::add_observation_level(observation_level); 00276 if(!_resource_instance_list.empty()) { 00277 M2MResourceInstanceList::const_iterator inst; 00278 inst = _resource_instance_list.begin(); 00279 for ( ; inst != _resource_instance_list.end(); inst++ ) { 00280 (*inst)->add_observation_level(observation_level); 00281 } 00282 } 00283 } 00284 00285 void M2MResource::remove_observation_level(M2MBase::Observation observation_level) 00286 { 00287 M2MBase::remove_observation_level(observation_level); 00288 if(!_resource_instance_list.empty()) { 00289 M2MResourceInstanceList::const_iterator inst; 00290 inst = _resource_instance_list.begin(); 00291 for ( ; inst != _resource_instance_list.end(); inst++ ) { 00292 (*inst)->remove_observation_level(observation_level); 00293 } 00294 } 00295 } 00296 00297 void M2MResource::add_resource_instance(M2MResourceInstance *res) 00298 { 00299 tr_debug("M2MResource::add_resource_instance()"); 00300 if(res) { 00301 _resource_instance_list.push_back(res); 00302 } 00303 } 00304 00305 sn_coap_hdr_s* M2MResource::handle_get_request(nsdl_s *nsdl, 00306 sn_coap_hdr_s *received_coap_header, 00307 M2MObservationHandler *observation_handler) 00308 { 00309 tr_info("M2MResource::handle_get_request()"); 00310 sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CONTENT; 00311 sn_coap_hdr_s * coap_response = NULL; 00312 if(supports_multiple_instances()) { 00313 coap_response = sn_nsdl_build_response(nsdl, 00314 received_coap_header, 00315 msg_code); 00316 if(received_coap_header) { 00317 // process the GET if we have registered a callback for it 00318 if ((operation() & SN_GRS_GET_ALLOWED) != 0) { 00319 if(coap_response) { 00320 bool content_type_present = false; 00321 bool is_content_type_supported = true; 00322 00323 if (received_coap_header->options_list_ptr && 00324 received_coap_header->options_list_ptr->accept != COAP_CT_NONE) { 00325 content_type_present = true; 00326 coap_response->content_format = received_coap_header->options_list_ptr->accept; 00327 } 00328 00329 // Check if preferred content type is supported 00330 if (content_type_present) { 00331 if (coap_response->content_format != COAP_CONTENT_OMA_TLV_TYPE_OLD && 00332 coap_response->content_format != COAP_CONTENT_OMA_TLV_TYPE) { 00333 is_content_type_supported = false; 00334 } 00335 } 00336 00337 if (is_content_type_supported) { 00338 if(!content_type_present && 00339 (M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE || 00340 M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE_OLD)) { 00341 coap_response->content_format = sn_coap_content_format_e(M2MBase::coap_content_type()); 00342 } 00343 00344 tr_debug("M2MResource::handle_get_request() - Request Content-type: %d", coap_response->content_format); 00345 00346 uint8_t *data = NULL; 00347 uint32_t data_length = 0; 00348 // fill in the CoAP response payload 00349 if(COAP_CONTENT_OMA_TLV_TYPE == coap_response->content_format || 00350 COAP_CONTENT_OMA_TLV_TYPE_OLD == coap_response->content_format) { 00351 set_coap_content_type(coap_response->content_format); 00352 data = M2MTLVSerializer::serialize(this, data_length); 00353 } 00354 00355 coap_response->payload_len = data_length; 00356 coap_response->payload_ptr = data; 00357 00358 coap_response->options_list_ptr = sn_nsdl_alloc_options_list(nsdl, coap_response); 00359 if (coap_response->options_list_ptr) { 00360 coap_response->options_list_ptr->max_age = max_age(); 00361 } 00362 00363 if(received_coap_header->options_list_ptr) { 00364 if(received_coap_header->options_list_ptr->observe != -1) { 00365 if (is_observable()) { 00366 uint32_t number = 0; 00367 uint8_t observe_option = 0; 00368 observe_option = received_coap_header->options_list_ptr->observe; 00369 if(START_OBSERVATION == observe_option) { 00370 // If the observe length is 0 means register for observation. 00371 if(received_coap_header->options_list_ptr->observe != -1) { 00372 number = received_coap_header->options_list_ptr->observe; 00373 } 00374 00375 // If the observe value is 0 means register for observation. 00376 if(number == 0) { 00377 tr_info("M2MResource::handle_get_request - put resource under observation"); 00378 M2MResourceInstanceList::const_iterator it; 00379 it = _resource_instance_list.begin(); 00380 for (; it!=_resource_instance_list.end(); it++ ) { 00381 (*it)->add_observation_level(M2MBase::R_Attribute); 00382 } 00383 set_under_observation(true,observation_handler); 00384 M2MBase::add_observation_level(M2MBase::R_Attribute); 00385 send_notification_delivery_status(*this, NOTIFICATION_STATUS_SUBSCRIBED); 00386 if (coap_response->options_list_ptr) { 00387 coap_response->options_list_ptr->observe = observation_number(); 00388 } 00389 } 00390 00391 if(received_coap_header->token_ptr) { 00392 set_observation_token(received_coap_header->token_ptr, 00393 received_coap_header->token_len); 00394 } 00395 00396 } else if (STOP_OBSERVATION == observe_option) { 00397 tr_info("M2MResource::handle_get_request - stops observation"); 00398 set_under_observation(false,NULL); 00399 M2MBase::remove_observation_level(M2MBase::R_Attribute); 00400 send_notification_delivery_status(*this,NOTIFICATION_STATUS_UNSUBSCRIBED); 00401 M2MResourceInstanceList::const_iterator it; 00402 it = _resource_instance_list.begin(); 00403 for (; it!=_resource_instance_list.end(); it++ ) { 00404 (*it)->remove_observation_level(M2MBase::R_Attribute); 00405 } 00406 } 00407 msg_code = COAP_MSG_CODE_RESPONSE_CONTENT; 00408 } else { 00409 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00410 } 00411 } 00412 } 00413 } else { 00414 tr_error("M2MResource::handle_get_request() - Content-Type %d not supported", coap_response->content_format); 00415 msg_code = COAP_MSG_CODE_RESPONSE_NOT_ACCEPTABLE; 00416 } 00417 } 00418 } else { 00419 tr_error("M2MResource::handle_get_request - Return COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED"); 00420 // Operation is not allowed. 00421 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00422 } 00423 } 00424 if(coap_response) { 00425 coap_response->msg_code = msg_code; 00426 } 00427 } else { 00428 coap_response = M2MResourceBase::handle_get_request(nsdl, 00429 received_coap_header, 00430 observation_handler); 00431 } 00432 return coap_response; 00433 } 00434 00435 sn_coap_hdr_s* M2MResource::handle_put_request(nsdl_s *nsdl, 00436 sn_coap_hdr_s *received_coap_header, 00437 M2MObservationHandler *observation_handler, 00438 bool &execute_value_updated) 00439 { 00440 tr_info("M2MResource::handle_put_request()"); 00441 sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04 00442 sn_coap_hdr_s * coap_response = NULL; 00443 if(supports_multiple_instances()) { 00444 coap_response = sn_nsdl_build_response(nsdl, 00445 received_coap_header, 00446 msg_code); 00447 // process the PUT if we have registered a callback for it 00448 if(received_coap_header) { 00449 uint16_t coap_content_type = 0; 00450 bool content_type_present = false; 00451 if(received_coap_header->content_format != COAP_CT_NONE && coap_response) { 00452 content_type_present = true; 00453 coap_content_type = received_coap_header->content_format; 00454 } 00455 if(received_coap_header->options_list_ptr && 00456 received_coap_header->options_list_ptr->uri_query_ptr) { 00457 char *query = (char*)alloc_string_copy(received_coap_header->options_list_ptr->uri_query_ptr, 00458 received_coap_header->options_list_ptr->uri_query_len); 00459 if (query){ 00460 msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; 00461 tr_info("M2MResource::handle_put_request() - query %s", query); 00462 // if anything was updated, re-initialize the stored notification attributes 00463 if (!handle_observation_attribute(query)){ 00464 tr_debug("M2MResource::handle_put_request() - Invalid query"); 00465 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // 4.00 00466 } 00467 free(query); 00468 } 00469 } else if ((operation() & SN_GRS_PUT_ALLOWED) != 0) { 00470 if(!content_type_present && 00471 (M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE || 00472 M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE_OLD)) { 00473 coap_content_type = COAP_CONTENT_OMA_TLV_TYPE; 00474 } 00475 00476 tr_debug("M2MResource::handle_put_request() - Request Content-type: %d", coap_content_type); 00477 00478 if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type || 00479 COAP_CONTENT_OMA_TLV_TYPE_OLD == coap_content_type) { 00480 set_coap_content_type(coap_content_type); 00481 M2MTLVDeserializer::Error error = M2MTLVDeserializer::None; 00482 error = M2MTLVDeserializer::deserialize_resource_instances(received_coap_header->payload_ptr, 00483 received_coap_header->payload_len, 00484 *this, 00485 M2MTLVDeserializer::Put); 00486 switch(error) { 00487 case M2MTLVDeserializer::None: 00488 if(observation_handler) { 00489 String value = ""; 00490 if (received_coap_header->uri_path_ptr != NULL && 00491 received_coap_header->uri_path_len > 0) { 00492 00493 value.append_raw((char*)received_coap_header->uri_path_ptr,received_coap_header->uri_path_len); 00494 } 00495 execute_value_updated = true; 00496 } 00497 msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; 00498 break; 00499 case M2MTLVDeserializer::NotFound: 00500 msg_code = COAP_MSG_CODE_RESPONSE_NOT_FOUND; 00501 break; 00502 case M2MTLVDeserializer::NotAllowed: 00503 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00504 break; 00505 case M2MTLVDeserializer::NotValid: 00506 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 00507 break; 00508 case M2MTLVDeserializer::OutOfMemory: 00509 msg_code = COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE; 00510 break; 00511 } 00512 } else { 00513 msg_code =COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT; 00514 } // if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) 00515 } else { 00516 // Operation is not allowed. 00517 tr_error("M2MResource::handle_put_request() - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED"); 00518 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00519 } 00520 } else { 00521 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00522 } 00523 if(coap_response) { 00524 coap_response->msg_code = msg_code; 00525 } 00526 } else { 00527 coap_response = M2MResourceBase::handle_put_request(nsdl, 00528 received_coap_header, 00529 observation_handler, 00530 execute_value_updated); 00531 } 00532 return coap_response; 00533 } 00534 00535 00536 sn_coap_hdr_s* M2MResource::handle_post_request(nsdl_s *nsdl, 00537 sn_coap_hdr_s *received_coap_header, 00538 M2MObservationHandler */*observation_handler*/, 00539 bool &/*execute_value_updated*/, 00540 sn_nsdl_addr_s *address) 00541 { 00542 tr_info("M2MResource::handle_post_request()"); 00543 sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04 00544 sn_coap_hdr_s * coap_response = sn_nsdl_build_response(nsdl, 00545 received_coap_header, 00546 msg_code); 00547 00548 // process the POST if we have registered a callback for it 00549 if(received_coap_header) { 00550 if ((operation() & SN_GRS_POST_ALLOWED) != 0) { 00551 M2MResource::M2MExecuteParameter exec_params(object_name(), name(), object_instance_id()); 00552 00553 uint16_t coap_content_type = 0; 00554 if(received_coap_header->payload_ptr) { 00555 if(received_coap_header->content_format != COAP_CT_NONE) { 00556 coap_content_type = received_coap_header->content_format; 00557 } 00558 00559 if(coap_content_type == COAP_CT_TEXT_PLAIN) { 00560 exec_params._value = received_coap_header->payload_ptr; 00561 if (exec_params._value) { 00562 exec_params._value_length = received_coap_header->payload_len; 00563 } 00564 } else { 00565 msg_code = COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT; 00566 } 00567 } 00568 if(COAP_MSG_CODE_RESPONSE_CHANGED == msg_code) { 00569 tr_debug("M2MResource::handle_post_request - Execute resource function"); 00570 #ifndef DISABLE_DELAYED_RESPONSE 00571 if (coap_response) { 00572 if(_delayed_response) { 00573 if(received_coap_header->token_len) { 00574 free(_delayed_token); 00575 _delayed_token = NULL; 00576 _delayed_token_len = 0; 00577 _delayed_token = alloc_copy(received_coap_header->token_ptr, received_coap_header->token_len); 00578 if(_delayed_token) { 00579 _delayed_token_len = received_coap_header->token_len; 00580 } 00581 } 00582 } else { 00583 #endif 00584 uint32_t length = 0; 00585 get_value(coap_response->payload_ptr, length); 00586 coap_response->payload_len = length; 00587 #ifndef DISABLE_DELAYED_RESPONSE 00588 } 00589 } 00590 #endif 00591 execute(&exec_params); 00592 } 00593 00594 } else { // if ((object->operation() & SN_GRS_POST_ALLOWED) != 0) 00595 tr_error("M2MResource::handle_post_request - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED"); 00596 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; // 4.05 00597 } 00598 } else { //if(object && received_coap_header) 00599 tr_error("M2MResource::handle_post_request - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED"); 00600 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; // 4.01 00601 } 00602 if(coap_response) { 00603 coap_response->msg_code = msg_code; 00604 } 00605 return coap_response; 00606 } 00607 00608 M2MObjectInstance& M2MResource::get_parent_object_instance() const 00609 { 00610 return _parent; 00611 } 00612 00613 uint16_t M2MResource::object_instance_id() const 00614 { 00615 const M2MObjectInstance& parent_object_instance = get_parent_object_instance(); 00616 return parent_object_instance.instance_id(); 00617 } 00618 00619 M2MResource& M2MResource::get_parent_resource() const 00620 { 00621 return (M2MResource&)*this; 00622 } 00623 00624 const char* M2MResource::object_name() const 00625 { 00626 const M2MObjectInstance& parent_object_instance = _parent; 00627 const M2MObject& parent_object = parent_object_instance.get_parent_object(); 00628 00629 return parent_object.name(); 00630 } 00631 00632 #ifdef MEMORY_OPTIMIZED_API 00633 M2MResource::M2MExecuteParameter::M2MExecuteParameter(const char *object_name, const char *resource_name, 00634 uint16_t object_instance_id) : 00635 _object_name(object_name), 00636 _resource_name(resource_name), 00637 _value(NULL), 00638 _value_length(0), 00639 _object_instance_id(object_instance_id) 00640 { 00641 } 00642 #else 00643 M2MResource::M2MExecuteParameter::M2MExecuteParameter(const String &object_name, const String &resource_name, 00644 uint16_t object_instance_id) : 00645 _object_name(object_name), 00646 _resource_name(resource_name), 00647 _value(NULL), 00648 _value_length(0), 00649 _object_instance_id(object_instance_id) 00650 { 00651 } 00652 #endif 00653 00654 // These could be actually changed to be inline ones, as it would likely generate 00655 // smaller code at application side. 00656 00657 const uint8_t *M2MResource::M2MExecuteParameter::get_argument_value() const 00658 { 00659 return _value; 00660 } 00661 00662 uint16_t M2MResource::M2MExecuteParameter::get_argument_value_length() const 00663 { 00664 return _value_length; 00665 } 00666 00667 #ifdef MEMORY_OPTIMIZED_API 00668 const char* M2MResource::M2MExecuteParameter::get_argument_object_name() const 00669 { 00670 return _object_name; 00671 } 00672 00673 const char* M2MResource::M2MExecuteParameter::get_argument_resource_name() const 00674 { 00675 return _resource_name; 00676 } 00677 #else 00678 const String& M2MResource::M2MExecuteParameter::get_argument_object_name() const 00679 { 00680 return _object_name; 00681 } 00682 00683 const String& M2MResource::M2MExecuteParameter::get_argument_resource_name() const 00684 { 00685 return _resource_name; 00686 } 00687 #endif 00688 00689 uint16_t M2MResource::M2MExecuteParameter::get_argument_object_instance_id() const 00690 { 00691 return _object_instance_id; 00692 }
Generated on Tue Jul 12 2022 19:01:35 by 1.7.2