mbed client lightswitch demo
Dependencies: mbed Socket lwip-eth lwip-sys lwip
Fork of mbed-client-classic-example-lwip 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 "include/m2mtlvserializer.h" 00023 #include "include/m2mtlvdeserializer.h" 00024 #include "include/nsdllinker.h" 00025 #include "include/m2mreporthandler.h" 00026 #include "ns_trace.h" 00027 00028 M2MObjectInstance& M2MObjectInstance::operator=(const M2MObjectInstance& other) 00029 { 00030 if (this != &other) { // protect against invalid self-assignment 00031 if(!other._resource_list.empty()){ 00032 M2MResource* ins = NULL; 00033 M2MResourceList::const_iterator it; 00034 it = other._resource_list.begin(); 00035 for (; it!=other._resource_list.end(); it++ ) { 00036 ins = *it; 00037 _resource_list.push_back(new M2MResource(*ins)); 00038 } 00039 } 00040 } 00041 return *this; 00042 } 00043 00044 M2MObjectInstance::M2MObjectInstance(const M2MObjectInstance& other) 00045 : M2MBase(other), 00046 _object_callback(other._object_callback) 00047 { 00048 this->operator=(other); 00049 } 00050 00051 M2MObjectInstance::M2MObjectInstance(const String &object_name, 00052 M2MObjectCallback &object_callback) 00053 : M2MBase(object_name,M2MBase::Dynamic), 00054 _object_callback(object_callback) 00055 { 00056 M2MBase::set_base_type(M2MBase::ObjectInstance); 00057 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 res = NULL; 00071 } 00072 _resource_list.clear(); 00073 } 00074 } 00075 00076 M2MResource* M2MObjectInstance::create_static_resource(const String &resource_name, 00077 const String &resource_type, 00078 M2MResourceInstance::ResourceType type, 00079 const uint8_t *value, 00080 const uint8_t value_length, 00081 bool multiple_instance) 00082 { 00083 tr_debug("M2MObjectInstance::create_static_resource(resource_name %s)",resource_name.c_str()); 00084 M2MResource *res = NULL; 00085 if( resource_name.empty() || resource_name.size() > MAX_ALLOWED_STRING_LENGTH){ 00086 return res; 00087 } 00088 res = new M2MResource(*this,resource_name, resource_type, type, 00089 value, value_length, multiple_instance); 00090 if(res) { 00091 _resource_list.push_back(res); 00092 if(M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE) { 00093 res->set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE); 00094 } 00095 } 00096 return res; 00097 } 00098 00099 M2MResource* M2MObjectInstance::create_dynamic_resource(const String &resource_name, 00100 const String &resource_type, 00101 M2MResourceInstance::ResourceType type, 00102 bool observable, 00103 bool multiple_instance) 00104 { 00105 tr_debug("M2MObjectInstance::create_dynamic_resource(resource_name %s)",resource_name.c_str()); 00106 M2MResource *res = NULL; 00107 if( resource_name.empty() || resource_name.size() > MAX_ALLOWED_STRING_LENGTH){ 00108 return res; 00109 } 00110 res = new M2MResource(*this,resource_name, resource_type, type, 00111 observable, multiple_instance); 00112 if(res) { 00113 _resource_list.push_back(res); 00114 if(M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE) { 00115 res->set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE); 00116 } 00117 } 00118 return res; 00119 } 00120 00121 M2MResourceInstance* M2MObjectInstance::create_static_resource_instance(const String &resource_name, 00122 const String &resource_type, 00123 M2MResourceInstance::ResourceType type, 00124 const uint8_t *value, 00125 const uint8_t value_length, 00126 uint16_t instance_id) 00127 { 00128 tr_debug("M2MObjectInstance::create_static_resource_instance(resource_name %s)",resource_name.c_str()); 00129 M2MResourceInstance *instance = NULL; 00130 if(resource_name.empty() || resource_name.size() > MAX_ALLOWED_STRING_LENGTH){ 00131 return instance; 00132 } 00133 M2MResource *res = resource(resource_name); 00134 if(!res) { 00135 res = new M2MResource(*this,resource_name, resource_type, type, 00136 value, value_length, true); 00137 _resource_list.push_back(res); 00138 res->set_operation(M2MBase::GET_ALLOWED); 00139 res->set_observable(false); 00140 if(M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE) { 00141 res->set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE); 00142 } 00143 } 00144 if(res->supports_multiple_instances()&& (res->resource_instance(instance_id) == NULL)) { 00145 instance = new M2MResourceInstance(resource_name, resource_type, type, 00146 value, value_length,*this); 00147 if(instance) { 00148 instance->set_operation(M2MBase::GET_ALLOWED); 00149 instance->set_observable(false); 00150 instance->set_instance_id(instance_id); 00151 if(M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE) { 00152 instance->set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE); 00153 } 00154 res->add_resource_instance(instance); 00155 } 00156 } 00157 return instance; 00158 } 00159 00160 M2MResourceInstance* M2MObjectInstance::create_dynamic_resource_instance(const String &resource_name, 00161 const String &resource_type, 00162 M2MResourceInstance::ResourceType type, 00163 bool observable, 00164 uint16_t instance_id) 00165 { 00166 tr_debug("M2MObjectInstance::create_dynamic_resource_instance(resource_name %s)",resource_name.c_str()); 00167 M2MResourceInstance *instance = NULL; 00168 if(resource_name.empty() || resource_name.size() > MAX_ALLOWED_STRING_LENGTH){ 00169 return instance; 00170 } 00171 M2MResource *res = resource(resource_name); 00172 if(!res) { 00173 res = new M2MResource(*this,resource_name, resource_type, type, 00174 observable, true); 00175 _resource_list.push_back(res); 00176 res->set_operation(M2MBase::GET_PUT_ALLOWED); 00177 res->set_observable(false); 00178 if(M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE) { 00179 res->set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE); 00180 } 00181 } 00182 if(res->supports_multiple_instances() && (res->resource_instance(instance_id) == NULL)) { 00183 instance = new M2MResourceInstance(resource_name, resource_type, type,*this); 00184 if(instance) { 00185 instance->set_operation(M2MBase::GET_PUT_ALLOWED); 00186 instance->set_observable(observable); 00187 instance->set_instance_id(instance_id); 00188 if(M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE) { 00189 instance->set_coap_content_type(COAP_CONTENT_OMA_TLV_TYPE); 00190 } 00191 res->add_resource_instance(instance); 00192 } 00193 } 00194 return instance; 00195 } 00196 00197 bool M2MObjectInstance::remove_resource(const String &resource_name) 00198 { 00199 tr_debug("M2MObjectInstance::remove_resource(resource_name %s)", 00200 resource_name.c_str()); 00201 bool success = false; 00202 if(!_resource_list.empty()) { 00203 M2MResource* res = NULL; 00204 M2MResourceList::const_iterator it; 00205 it = _resource_list.begin(); 00206 int pos = 0; 00207 for ( ; it != _resource_list.end(); it++, pos++ ) { 00208 if(((*it)->name() == resource_name)) { 00209 // Resource found and deleted. 00210 res = *it; 00211 00212 char *obj_inst_id = (char*)malloc(20); 00213 if(obj_inst_id) { 00214 snprintf(obj_inst_id, 20,"%d",instance_id()); 00215 00216 String obj_name = name(); 00217 obj_name += String("/"); 00218 obj_name += String(obj_inst_id); 00219 obj_name += String("/"); 00220 obj_name += (*it)->name(); 00221 00222 free(obj_inst_id); 00223 00224 00225 remove_resource_from_coap(obj_name); 00226 delete res; 00227 res = NULL; 00228 _resource_list.erase(pos); 00229 success = true; 00230 } 00231 break; 00232 } 00233 } 00234 } 00235 return success; 00236 } 00237 00238 bool M2MObjectInstance::remove_resource_instance(const String &resource_name, 00239 uint16_t inst_id) 00240 { 00241 tr_debug("M2MObjectInstance::remove_resource_instance(resource_name %s inst_id %d)", 00242 resource_name.c_str(), inst_id); 00243 bool success = false; 00244 M2MResource *res = resource(resource_name); 00245 if(res) { 00246 M2MResourceInstanceList list = res->resource_instances(); 00247 M2MResourceInstanceList::const_iterator it; 00248 it = list.begin(); 00249 for ( ; it != list.end(); it++) { 00250 if((*it)->instance_id() == inst_id) { 00251 char *obj_inst_id = (char*)malloc(20); 00252 if(obj_inst_id) { 00253 snprintf(obj_inst_id, 20,"%d",instance_id()); 00254 00255 String obj_name = name(); 00256 obj_name += String("/"); 00257 obj_name += String(obj_inst_id); 00258 obj_name += String("/"); 00259 obj_name += resource_name; 00260 00261 free(obj_inst_id); 00262 00263 char *res_inst_id = (char*)malloc(20); 00264 if(res_inst_id) { 00265 snprintf(res_inst_id, 20,"%d",inst_id); 00266 obj_name += String("/"); 00267 obj_name += String(res_inst_id); 00268 00269 free(res_inst_id); 00270 00271 remove_resource_from_coap(obj_name); 00272 success = res->remove_resource_instance(inst_id); 00273 if(res->resource_instance_count() == 0) { 00274 M2MResourceList::const_iterator itr; 00275 itr = _resource_list.begin(); 00276 int pos = 0; 00277 for ( ; itr != _resource_list.end(); itr++, pos++ ) { 00278 if(((*itr)->name() == resource_name)) { 00279 delete res; 00280 res = NULL; 00281 _resource_list.erase(pos); 00282 break; 00283 } 00284 } 00285 } 00286 } 00287 } 00288 break; 00289 } 00290 } 00291 } 00292 return success; 00293 } 00294 00295 M2MResource* M2MObjectInstance::resource(const String &resource) const 00296 { 00297 M2MResource *res = NULL; 00298 if(!_resource_list.empty()) { 00299 M2MResourceList::const_iterator it; 00300 it = _resource_list.begin(); 00301 for (; it!=_resource_list.end(); it++ ) { 00302 if((*it)->name() == resource) { 00303 res = *it; 00304 break; 00305 } 00306 } 00307 } 00308 return res; 00309 } 00310 00311 const M2MResourceList& M2MObjectInstance::resources() const 00312 { 00313 return _resource_list; 00314 } 00315 00316 uint16_t M2MObjectInstance::resource_count() const 00317 { 00318 uint16_t count = 0; 00319 if(!_resource_list.empty()) { 00320 M2MResourceList::const_iterator it; 00321 it = _resource_list.begin(); 00322 for ( ; it != _resource_list.end(); it++ ) { 00323 if((*it)->supports_multiple_instances()) { 00324 count += (*it)->resource_instance_count(); 00325 } else { 00326 count++; 00327 } 00328 } 00329 } 00330 return count; 00331 } 00332 00333 uint16_t M2MObjectInstance::resource_count(const String& resource) const 00334 { 00335 uint16_t count = 0; 00336 if(!_resource_list.empty()) { 00337 M2MResourceList::const_iterator it; 00338 it = _resource_list.begin(); 00339 for ( ; it != _resource_list.end(); it++ ) { 00340 if((*it)->name() == resource) { 00341 if((*it)->supports_multiple_instances()) { 00342 count += (*it)->resource_instance_count(); 00343 } else { 00344 count++; 00345 } 00346 } 00347 } 00348 } 00349 return count; 00350 } 00351 00352 M2MBase::BaseType M2MObjectInstance::base_type() const 00353 { 00354 return M2MBase::base_type(); 00355 } 00356 00357 void M2MObjectInstance::add_observation_level(M2MBase::Observation observation_level) 00358 { 00359 M2MBase::add_observation_level(observation_level); 00360 if(!_resource_list.empty()) { 00361 M2MResourceList::const_iterator it; 00362 it = _resource_list.begin(); 00363 for ( ; it != _resource_list.end(); it++ ) { 00364 (*it)->add_observation_level(observation_level); 00365 } 00366 } 00367 } 00368 00369 void M2MObjectInstance::remove_observation_level(M2MBase::Observation observation_level) 00370 { 00371 M2MBase::remove_observation_level(observation_level); 00372 if(!_resource_list.empty()) { 00373 M2MResourceList::const_iterator it; 00374 it = _resource_list.begin(); 00375 for ( ; it != _resource_list.end(); it++ ) { 00376 (*it)->remove_observation_level(observation_level); 00377 } 00378 } 00379 } 00380 00381 sn_coap_hdr_s* M2MObjectInstance::handle_get_request(nsdl_s *nsdl, 00382 sn_coap_hdr_s *received_coap_header, 00383 M2MObservationHandler *observation_handler) 00384 { 00385 tr_debug("M2MObjectInstance::handle_get_request()"); 00386 sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CONTENT; 00387 sn_coap_hdr_s * coap_response = sn_nsdl_build_response(nsdl, 00388 received_coap_header, 00389 msg_code); 00390 uint8_t * data = NULL; 00391 uint32_t data_length = 0; 00392 //TODO: GET for Object is not yet implemented. 00393 // Need to first fix C library and then implement on C++ side. 00394 if(received_coap_header) { 00395 // process the GET if we have registered a callback for it 00396 if ((operation() & SN_GRS_GET_ALLOWED) != 0) { 00397 if(coap_response) { 00398 uint16_t coap_content_type = 0; 00399 bool content_type_present = false; 00400 if(received_coap_header->content_type_ptr) { 00401 content_type_present = true; 00402 coap_response->content_type_ptr = (uint8_t*)malloc(received_coap_header->content_type_len); 00403 if(coap_response->content_type_ptr) { 00404 memset(coap_response->content_type_ptr, 0, received_coap_header->content_type_len); 00405 memcpy(coap_response->content_type_ptr, 00406 received_coap_header->content_type_ptr, 00407 received_coap_header->content_type_len); 00408 coap_response->content_type_len = received_coap_header->content_type_len; 00409 for(uint8_t i = 0; i < coap_response->content_type_len; i++) { 00410 coap_content_type = (coap_content_type << 8) + (coap_response->content_type_ptr[i] & 0xFF); 00411 } 00412 } 00413 } 00414 if(!content_type_present && 00415 M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE) { 00416 coap_content_type = COAP_CONTENT_OMA_TLV_TYPE; 00417 } 00418 00419 tr_debug("M2MObjectInstance::handle_get_request() - Request Content-Type %d", coap_content_type); 00420 00421 // fill in the CoAP response payload 00422 if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) { 00423 M2MTLVSerializer *serializer = new M2MTLVSerializer(); 00424 if(serializer) { 00425 data = serializer->serialize(_resource_list, data_length); 00426 delete serializer; 00427 } 00428 } else { 00429 msg_code = COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT; // Content format not supported 00430 } 00431 00432 coap_response->payload_len = data_length; 00433 coap_response->payload_ptr = data; 00434 00435 if(data) { 00436 coap_response->options_list_ptr = (sn_coap_options_list_s*)malloc(sizeof(sn_coap_options_list_s)); 00437 memset(coap_response->options_list_ptr, 0, sizeof(sn_coap_options_list_s)); 00438 00439 coap_response->options_list_ptr->max_age_ptr = (uint8_t*)malloc(1); 00440 memset(coap_response->options_list_ptr->max_age_ptr,0,1); 00441 coap_response->options_list_ptr->max_age_len = 1; 00442 00443 00444 if(received_coap_header->token_ptr) { 00445 tr_debug("M2MObjectInstance::handle_get_request - Sets Observation Token to resource"); 00446 set_observation_token(received_coap_header->token_ptr, 00447 received_coap_header->token_len); 00448 } 00449 if(received_coap_header->options_list_ptr) { 00450 if(received_coap_header->options_list_ptr->observe) { 00451 if (is_observable()) { 00452 uint32_t number = 0; 00453 uint8_t observe_option = 0; 00454 if(received_coap_header->options_list_ptr->observe_ptr) { 00455 observe_option = *received_coap_header->options_list_ptr->observe_ptr; 00456 } 00457 if(START_OBSERVATION == observe_option) { 00458 tr_debug("M2MObjectInstance::handle_get_request - Starts Observation"); 00459 // If the observe length is 0 means register for observation. 00460 if(received_coap_header->options_list_ptr->observe_len != 0) { 00461 for(int i=0;i < received_coap_header->options_list_ptr->observe_len; i++) { 00462 number = (*(received_coap_header->options_list_ptr->observe_ptr + i) & 0xff) << 00463 8*(received_coap_header->options_list_ptr->observe_len- 1 - i); 00464 } 00465 } 00466 // If the observe value is 0 means register for observation. 00467 if(number == 0) { 00468 tr_debug("M2MObjectInstance::handle_get_request - Put Resource under Observation"); 00469 set_under_observation(true,observation_handler); 00470 add_observation_level(M2MBase::OI_Attribute); 00471 00472 uint8_t *obs_number = (uint8_t*)malloc(3); 00473 memset(obs_number,0,3); 00474 uint8_t observation_number_length = 1; 00475 00476 uint16_t number = observation_number(); 00477 00478 tr_debug("M2MObjectInstance::handle_get_request - Observation Number %d", number); 00479 obs_number[0] = ((number>>8) & 0xFF); 00480 obs_number[1] = (number & 0xFF); 00481 00482 if(number > 0xFF) { 00483 observation_number_length = 2; 00484 } 00485 coap_response->options_list_ptr->observe_ptr = obs_number; 00486 coap_response->options_list_ptr->observe_len = observation_number_length; 00487 } 00488 } else if (STOP_OBSERVATION == observe_option) { 00489 tr_debug("M2MObjectInstance::handle_get_request - Stops Observation"); 00490 set_under_observation(false,NULL); 00491 remove_observation_level(M2MBase::OI_Attribute); 00492 00493 } 00494 msg_code = COAP_MSG_CODE_RESPONSE_CONTENT; 00495 } 00496 else { 00497 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00498 } 00499 } 00500 } 00501 } else { 00502 msg_code = COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT; // Content format not supported 00503 } 00504 } 00505 }else { 00506 tr_error("M2MObjectInstance::handle_get_request - Return COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED"); 00507 // Operation is not allowed. 00508 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00509 } 00510 } else { 00511 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00512 } 00513 if(coap_response) { 00514 coap_response->msg_code = msg_code; 00515 } 00516 return coap_response; 00517 } 00518 00519 sn_coap_hdr_s* M2MObjectInstance::handle_put_request(nsdl_s *nsdl, 00520 sn_coap_hdr_s *received_coap_header, 00521 M2MObservationHandler *observation_handler) 00522 { 00523 tr_debug("M2MObjectInstance::handle_put_request()"); 00524 sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04 00525 sn_coap_hdr_s * coap_response = sn_nsdl_build_response(nsdl, 00526 received_coap_header, 00527 msg_code);; 00528 if(received_coap_header) { 00529 if ((operation() & SN_GRS_PUT_ALLOWED) != 0) { 00530 uint16_t coap_content_type = 0; 00531 bool content_type_present = false; 00532 if(received_coap_header->content_type_ptr) { 00533 content_type_present = true; 00534 if(coap_response) { 00535 coap_response->content_type_ptr = (uint8_t*)malloc(received_coap_header->content_type_len); 00536 if(coap_response->content_type_ptr) { 00537 memset(coap_response->content_type_ptr, 0, received_coap_header->content_type_len); 00538 memcpy(coap_response->content_type_ptr, 00539 received_coap_header->content_type_ptr, 00540 received_coap_header->content_type_len); 00541 coap_response->content_type_len = received_coap_header->content_type_len; 00542 for(uint8_t i = 0; i < coap_response->content_type_len; i++) { 00543 coap_content_type = (coap_content_type << 8) + (coap_response->content_type_ptr[i] & 0xFF); 00544 } 00545 } 00546 } 00547 } 00548 if(!content_type_present && 00549 M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE) { 00550 coap_content_type = COAP_CONTENT_OMA_TLV_TYPE; 00551 } 00552 00553 tr_debug("M2MObjectInstance::handle_put_request() - Request Content-Type %d", coap_content_type); 00554 00555 if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) { 00556 M2MTLVDeserializer::Error error = M2MTLVDeserializer::None; 00557 M2MTLVDeserializer *deserializer = new M2MTLVDeserializer(); 00558 if(deserializer && received_coap_header->payload_ptr) { 00559 error = deserializer->deserialize_resources(received_coap_header->payload_ptr, 00560 received_coap_header->payload_len, 00561 *this, 00562 M2MTLVDeserializer::Put); 00563 switch(error) { 00564 case M2MTLVDeserializer::None: 00565 if(observation_handler) { 00566 observation_handler->value_updated(this); 00567 } 00568 msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; 00569 break; 00570 case M2MTLVDeserializer::NotFound: 00571 msg_code = COAP_MSG_CODE_RESPONSE_NOT_FOUND; 00572 break; 00573 case M2MTLVDeserializer::NotAllowed: 00574 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00575 break; 00576 case M2MTLVDeserializer::NotValid: 00577 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 00578 break; 00579 } 00580 delete deserializer; 00581 } 00582 } else { 00583 msg_code =COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT; 00584 } // if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) 00585 if(!received_coap_header->payload_ptr && 00586 received_coap_header->options_list_ptr && 00587 received_coap_header->options_list_ptr->uri_query_ptr) { 00588 char *query = (char*)malloc(received_coap_header->options_list_ptr->uri_query_len+1); 00589 if (query){ 00590 memset(query, 0, received_coap_header->options_list_ptr->uri_query_len+1); 00591 memcpy(query, 00592 received_coap_header->options_list_ptr->uri_query_ptr, 00593 received_coap_header->options_list_ptr->uri_query_len); 00594 memset(query + received_coap_header->options_list_ptr->uri_query_len,'\0',1);//String terminator 00595 tr_debug("M2MObjectInstance::handle_put_request() - Query %s", query); 00596 // if anything was updated, re-initialize the stored notification attributes 00597 if (!handle_observation_attribute(query)){ 00598 tr_debug("M2MObjectInstance::handle_put_request() - Invalid query"); 00599 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // 4.00 00600 } else { 00601 msg_code =COAP_MSG_CODE_RESPONSE_CHANGED; 00602 } 00603 free(query); 00604 } 00605 } 00606 } else { 00607 // Operation is not allowed. 00608 tr_error("M2MObjectInstance::handle_put_request() - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED"); 00609 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00610 } 00611 } else { 00612 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00613 } 00614 if(coap_response) { 00615 coap_response->msg_code = msg_code; 00616 } 00617 return coap_response; 00618 } 00619 00620 sn_coap_hdr_s* M2MObjectInstance::handle_post_request(nsdl_s *nsdl, 00621 sn_coap_hdr_s *received_coap_header, 00622 M2MObservationHandler *observation_handler) 00623 { 00624 tr_debug("M2MObjectInstance::handle_post_request()"); 00625 sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04 00626 sn_coap_hdr_s * coap_response = sn_nsdl_build_response(nsdl, 00627 received_coap_header, 00628 msg_code); 00629 if(received_coap_header) { 00630 if ((operation() & SN_GRS_POST_ALLOWED) != 0) { 00631 uint16_t coap_content_type = 0; 00632 bool content_type_present = false; 00633 if(received_coap_header->content_type_ptr) { 00634 content_type_present = true; 00635 if(coap_response) { 00636 coap_response->content_type_ptr = (uint8_t*)malloc(received_coap_header->content_type_len); 00637 if(coap_response->content_type_ptr) { 00638 memset(coap_response->content_type_ptr, 0, received_coap_header->content_type_len); 00639 memcpy(coap_response->content_type_ptr, 00640 received_coap_header->content_type_ptr, 00641 received_coap_header->content_type_len); 00642 coap_response->content_type_len = received_coap_header->content_type_len; 00643 for(uint8_t i = 0; i < coap_response->content_type_len; i++) { 00644 coap_content_type = (coap_content_type << 8) + (coap_response->content_type_ptr[i] & 0xFF); 00645 } 00646 } 00647 } 00648 } 00649 if(!content_type_present && 00650 M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE) { 00651 coap_content_type = COAP_CONTENT_OMA_TLV_TYPE; 00652 } 00653 00654 tr_debug("M2MObjectInstance::handle_post_request() - Request Content-Type %d", coap_content_type); 00655 00656 if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) { 00657 M2MTLVDeserializer *deserializer = new M2MTLVDeserializer(); 00658 if(deserializer) { 00659 String obj_name = ""; 00660 char *obj_inst_id = NULL; 00661 char *resource_id = NULL; 00662 M2MTLVDeserializer::Error error = M2MTLVDeserializer::None; 00663 error = deserializer->deserialize_resources(received_coap_header->payload_ptr, 00664 received_coap_header->payload_len, 00665 *this, 00666 M2MTLVDeserializer::Post); 00667 00668 uint16_t instance_id = deserializer->instance_id(received_coap_header->payload_ptr); 00669 switch(error) { 00670 case M2MTLVDeserializer::None: 00671 if(observation_handler) { 00672 observation_handler->value_updated(this); 00673 } 00674 coap_response->options_list_ptr = (sn_coap_options_list_s*)malloc(sizeof(sn_coap_options_list_s)); 00675 if (coap_response->options_list_ptr) { 00676 memset(coap_response->options_list_ptr, 0, sizeof(sn_coap_options_list_s)); 00677 00678 resource_id = (char*)malloc(10); 00679 obj_inst_id = (char*)malloc(10); 00680 snprintf(resource_id, 10, "%d",instance_id); 00681 snprintf(obj_inst_id, 10, "%d",M2MBase::instance_id()); 00682 00683 obj_name += M2MBase::name(); 00684 obj_name += "/"; 00685 obj_name += obj_inst_id; 00686 obj_name += "/"; 00687 obj_name += resource_id; 00688 00689 coap_response->options_list_ptr->location_path_len = obj_name.length(); 00690 if (coap_response->options_list_ptr->location_path_len != 0) { 00691 coap_response->options_list_ptr->location_path_ptr = 00692 (uint8_t*)malloc(coap_response->options_list_ptr->location_path_len); 00693 if (coap_response->options_list_ptr->location_path_ptr) { 00694 memcpy(coap_response->options_list_ptr->location_path_ptr, 00695 obj_name.c_str(), 00696 coap_response->options_list_ptr->location_path_len); 00697 } 00698 } 00699 00700 free(obj_inst_id); 00701 free(resource_id); 00702 } 00703 msg_code = COAP_MSG_CODE_RESPONSE_CREATED; 00704 break; 00705 case M2MTLVDeserializer::NotAllowed: 00706 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00707 break; 00708 case M2MTLVDeserializer::NotValid: 00709 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; 00710 break; 00711 default: 00712 break; 00713 } 00714 delete deserializer; 00715 } 00716 } else { 00717 msg_code =COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT; 00718 } // if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) 00719 } else { 00720 // Operation is not allowed. 00721 tr_error("M2MObjectInstance::handle_post_request() - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED"); 00722 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00723 } 00724 } else { 00725 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00726 } 00727 if(coap_response) { 00728 coap_response->msg_code = msg_code; 00729 } 00730 return coap_response; 00731 } 00732 00733 void M2MObjectInstance::notification_update(M2MBase::Observation observation_level) 00734 { 00735 if(M2MBase::O_Attribute == observation_level) { 00736 _object_callback.notification_update(); 00737 } else { 00738 M2MReportHandler *report_handler = M2MBase::report_handler(); 00739 if(report_handler && is_observable()) { 00740 report_handler->set_notification_trigger(); 00741 } 00742 } 00743 }
Generated on Tue Jul 12 2022 18:27:24 by 1.7.2