A metronome using the FRDM K64F board

Committer:
ram54288
Date:
Sun May 14 18:40:18 2017 +0000
Revision:
0:a7a43371b306
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ram54288 0:a7a43371b306 1 /*
ram54288 0:a7a43371b306 2 * Copyright (c) 2015 ARM Limited. All rights reserved.
ram54288 0:a7a43371b306 3 * SPDX-License-Identifier: Apache-2.0
ram54288 0:a7a43371b306 4 * Licensed under the Apache License, Version 2.0 (the License); you may
ram54288 0:a7a43371b306 5 * not use this file except in compliance with the License.
ram54288 0:a7a43371b306 6 * You may obtain a copy of the License at
ram54288 0:a7a43371b306 7 *
ram54288 0:a7a43371b306 8 * http://www.apache.org/licenses/LICENSE-2.0
ram54288 0:a7a43371b306 9 *
ram54288 0:a7a43371b306 10 * Unless required by applicable law or agreed to in writing, software
ram54288 0:a7a43371b306 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
ram54288 0:a7a43371b306 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ram54288 0:a7a43371b306 13 * See the License for the specific language governing permissions and
ram54288 0:a7a43371b306 14 * limitations under the License.
ram54288 0:a7a43371b306 15 */
ram54288 0:a7a43371b306 16 #include "mbed-client/m2mconstants.h"
ram54288 0:a7a43371b306 17 #include "mbed-client/m2mresource.h"
ram54288 0:a7a43371b306 18 #include "mbed-client/m2mobservationhandler.h"
ram54288 0:a7a43371b306 19 #include "include/m2mreporthandler.h"
ram54288 0:a7a43371b306 20 #include "include/m2mtlvserializer.h"
ram54288 0:a7a43371b306 21 #include "include/m2mtlvdeserializer.h"
ram54288 0:a7a43371b306 22 #include "mbed-trace/mbed_trace.h"
ram54288 0:a7a43371b306 23
ram54288 0:a7a43371b306 24 #include <stdlib.h>
ram54288 0:a7a43371b306 25
ram54288 0:a7a43371b306 26 #define TRACE_GROUP "mClt"
ram54288 0:a7a43371b306 27
ram54288 0:a7a43371b306 28 M2MResource::M2MResource(M2MObjectInstance &parent,
ram54288 0:a7a43371b306 29 const String &resource_name,
ram54288 0:a7a43371b306 30 const String &resource_type,
ram54288 0:a7a43371b306 31 M2MResourceInstance::ResourceType type,
ram54288 0:a7a43371b306 32 const uint8_t *value,
ram54288 0:a7a43371b306 33 const uint8_t value_length,
ram54288 0:a7a43371b306 34 char *path,
ram54288 0:a7a43371b306 35 const uint16_t object_instance_id,
ram54288 0:a7a43371b306 36 bool multiple_instance,
ram54288 0:a7a43371b306 37 bool external_blockwise_store)
ram54288 0:a7a43371b306 38 : M2MResourceInstance(*this, resource_name, resource_type, type, value, value_length,
ram54288 0:a7a43371b306 39 object_instance_id,
ram54288 0:a7a43371b306 40 path, external_blockwise_store),
ram54288 0:a7a43371b306 41 _parent(parent),
ram54288 0:a7a43371b306 42 _delayed_token(NULL),
ram54288 0:a7a43371b306 43 _delayed_token_len(0),
ram54288 0:a7a43371b306 44 _has_multiple_instances(multiple_instance),
ram54288 0:a7a43371b306 45 _delayed_response(false)
ram54288 0:a7a43371b306 46 {
ram54288 0:a7a43371b306 47 M2MBase::set_base_type(M2MBase::Resource);
ram54288 0:a7a43371b306 48 M2MBase::set_operation(M2MBase::GET_ALLOWED);
ram54288 0:a7a43371b306 49 M2MBase::set_observable(false);
ram54288 0:a7a43371b306 50
ram54288 0:a7a43371b306 51 }
ram54288 0:a7a43371b306 52
ram54288 0:a7a43371b306 53 M2MResource::M2MResource(M2MObjectInstance &parent,
ram54288 0:a7a43371b306 54 const lwm2m_parameters_s* s,
ram54288 0:a7a43371b306 55 M2MResourceInstance::ResourceType type,
ram54288 0:a7a43371b306 56 const uint16_t object_instance_id)
ram54288 0:a7a43371b306 57 : M2MResourceInstance(*this, s, type, object_instance_id),
ram54288 0:a7a43371b306 58 _parent(parent),
ram54288 0:a7a43371b306 59 _delayed_token(NULL),
ram54288 0:a7a43371b306 60 _delayed_token_len(0),
ram54288 0:a7a43371b306 61 _has_multiple_instances(false),
ram54288 0:a7a43371b306 62 _delayed_response(false)
ram54288 0:a7a43371b306 63 {
ram54288 0:a7a43371b306 64 // tbd: _has_multiple_instances could be in flash, but no real benefit, because of current alignment.
ram54288 0:a7a43371b306 65 }
ram54288 0:a7a43371b306 66
ram54288 0:a7a43371b306 67 M2MResource::M2MResource(M2MObjectInstance &parent,
ram54288 0:a7a43371b306 68 const String &resource_name,
ram54288 0:a7a43371b306 69 const String &resource_type,
ram54288 0:a7a43371b306 70 M2MResourceInstance::ResourceType type,
ram54288 0:a7a43371b306 71 bool observable,
ram54288 0:a7a43371b306 72 char *path,
ram54288 0:a7a43371b306 73 const uint16_t object_instance_id,
ram54288 0:a7a43371b306 74 bool multiple_instance,
ram54288 0:a7a43371b306 75 bool external_blockwise_store)
ram54288 0:a7a43371b306 76 : M2MResourceInstance(*this, resource_name, resource_type, type,
ram54288 0:a7a43371b306 77 object_instance_id,
ram54288 0:a7a43371b306 78 path,
ram54288 0:a7a43371b306 79 external_blockwise_store),
ram54288 0:a7a43371b306 80 _parent(parent),
ram54288 0:a7a43371b306 81 _delayed_token(NULL),
ram54288 0:a7a43371b306 82 _delayed_token_len(0),
ram54288 0:a7a43371b306 83 _has_multiple_instances(multiple_instance),
ram54288 0:a7a43371b306 84 _delayed_response(false)
ram54288 0:a7a43371b306 85 {
ram54288 0:a7a43371b306 86 M2MBase::set_base_type(M2MBase::Resource);
ram54288 0:a7a43371b306 87 M2MBase::set_operation(M2MBase::GET_PUT_ALLOWED);
ram54288 0:a7a43371b306 88 M2MBase::set_observable(observable);
ram54288 0:a7a43371b306 89 }
ram54288 0:a7a43371b306 90
ram54288 0:a7a43371b306 91
ram54288 0:a7a43371b306 92 M2MResource::~M2MResource()
ram54288 0:a7a43371b306 93 {
ram54288 0:a7a43371b306 94 if(!_resource_instance_list.empty()) {
ram54288 0:a7a43371b306 95 M2MResourceInstance* res = NULL;
ram54288 0:a7a43371b306 96 M2MResourceInstanceList::const_iterator it;
ram54288 0:a7a43371b306 97 it = _resource_instance_list.begin();
ram54288 0:a7a43371b306 98 for (; it!=_resource_instance_list.end(); it++ ) {
ram54288 0:a7a43371b306 99 //Free allocated memory for resources.
ram54288 0:a7a43371b306 100 res = *it;
ram54288 0:a7a43371b306 101 delete res;
ram54288 0:a7a43371b306 102 }
ram54288 0:a7a43371b306 103 _resource_instance_list.clear();
ram54288 0:a7a43371b306 104 }
ram54288 0:a7a43371b306 105 free(_delayed_token);
ram54288 0:a7a43371b306 106 }
ram54288 0:a7a43371b306 107
ram54288 0:a7a43371b306 108 bool M2MResource::supports_multiple_instances() const
ram54288 0:a7a43371b306 109 {
ram54288 0:a7a43371b306 110 return _has_multiple_instances;
ram54288 0:a7a43371b306 111 }
ram54288 0:a7a43371b306 112
ram54288 0:a7a43371b306 113 void M2MResource::set_delayed_response(bool delayed_response)
ram54288 0:a7a43371b306 114 {
ram54288 0:a7a43371b306 115 _delayed_response = delayed_response;
ram54288 0:a7a43371b306 116 }
ram54288 0:a7a43371b306 117
ram54288 0:a7a43371b306 118 bool M2MResource::send_delayed_post_response()
ram54288 0:a7a43371b306 119 {
ram54288 0:a7a43371b306 120 bool success = false;
ram54288 0:a7a43371b306 121 if(_delayed_response) {
ram54288 0:a7a43371b306 122 success = true;
ram54288 0:a7a43371b306 123 observation_handler()->send_delayed_response(this);
ram54288 0:a7a43371b306 124 }
ram54288 0:a7a43371b306 125 return success;
ram54288 0:a7a43371b306 126 }
ram54288 0:a7a43371b306 127
ram54288 0:a7a43371b306 128 void M2MResource::get_delayed_token(uint8_t *&token, uint8_t &token_length)
ram54288 0:a7a43371b306 129 {
ram54288 0:a7a43371b306 130 token_length = 0;
ram54288 0:a7a43371b306 131 if(token) {
ram54288 0:a7a43371b306 132 free(token);
ram54288 0:a7a43371b306 133 token = NULL;
ram54288 0:a7a43371b306 134 }
ram54288 0:a7a43371b306 135 if(_delayed_token && _delayed_token_len > 0) {
ram54288 0:a7a43371b306 136 token = alloc_copy(_delayed_token, _delayed_token_len);
ram54288 0:a7a43371b306 137 if(token) {
ram54288 0:a7a43371b306 138 token_length = _delayed_token_len;
ram54288 0:a7a43371b306 139 }
ram54288 0:a7a43371b306 140 }
ram54288 0:a7a43371b306 141 }
ram54288 0:a7a43371b306 142
ram54288 0:a7a43371b306 143 bool M2MResource::remove_resource_instance(uint16_t inst_id)
ram54288 0:a7a43371b306 144 {
ram54288 0:a7a43371b306 145 tr_debug("M2MResource::remove_resource(inst_id %d)", inst_id);
ram54288 0:a7a43371b306 146 bool success = false;
ram54288 0:a7a43371b306 147 if(!_resource_instance_list.empty()) {
ram54288 0:a7a43371b306 148 M2MResourceInstance* res = NULL;
ram54288 0:a7a43371b306 149 M2MResourceInstanceList::const_iterator it;
ram54288 0:a7a43371b306 150 it = _resource_instance_list.begin();
ram54288 0:a7a43371b306 151 int pos = 0;
ram54288 0:a7a43371b306 152 for ( ; it != _resource_instance_list.end(); it++, pos++ ) {
ram54288 0:a7a43371b306 153 if(((*it)->instance_id() == inst_id)) {
ram54288 0:a7a43371b306 154 // Resource found and deleted.
ram54288 0:a7a43371b306 155 res = *it;
ram54288 0:a7a43371b306 156 delete res;
ram54288 0:a7a43371b306 157 _resource_instance_list.erase(pos);
ram54288 0:a7a43371b306 158 success = true;
ram54288 0:a7a43371b306 159 break;
ram54288 0:a7a43371b306 160 }
ram54288 0:a7a43371b306 161 }
ram54288 0:a7a43371b306 162 }
ram54288 0:a7a43371b306 163 return success;
ram54288 0:a7a43371b306 164 }
ram54288 0:a7a43371b306 165
ram54288 0:a7a43371b306 166 M2MResourceInstance* M2MResource::resource_instance(uint16_t inst_id) const
ram54288 0:a7a43371b306 167 {
ram54288 0:a7a43371b306 168 tr_debug("M2MResource::resource(resource_name inst_id %d)", inst_id);
ram54288 0:a7a43371b306 169 M2MResourceInstance *res = NULL;
ram54288 0:a7a43371b306 170 if(!_resource_instance_list.empty()) {
ram54288 0:a7a43371b306 171 M2MResourceInstanceList::const_iterator it;
ram54288 0:a7a43371b306 172 it = _resource_instance_list.begin();
ram54288 0:a7a43371b306 173 for ( ; it != _resource_instance_list.end(); it++ ) {
ram54288 0:a7a43371b306 174 if(((*it)->instance_id() == inst_id)) {
ram54288 0:a7a43371b306 175 // Resource found.
ram54288 0:a7a43371b306 176 res = *it;
ram54288 0:a7a43371b306 177 break;
ram54288 0:a7a43371b306 178 }
ram54288 0:a7a43371b306 179 }
ram54288 0:a7a43371b306 180 }
ram54288 0:a7a43371b306 181 return res;
ram54288 0:a7a43371b306 182 }
ram54288 0:a7a43371b306 183
ram54288 0:a7a43371b306 184 const M2MResourceInstanceList& M2MResource::resource_instances() const
ram54288 0:a7a43371b306 185 {
ram54288 0:a7a43371b306 186 return _resource_instance_list;
ram54288 0:a7a43371b306 187 }
ram54288 0:a7a43371b306 188
ram54288 0:a7a43371b306 189 uint16_t M2MResource::resource_instance_count() const
ram54288 0:a7a43371b306 190 {
ram54288 0:a7a43371b306 191 return (uint16_t)_resource_instance_list.size();
ram54288 0:a7a43371b306 192 }
ram54288 0:a7a43371b306 193
ram54288 0:a7a43371b306 194 bool M2MResource::delayed_response() const
ram54288 0:a7a43371b306 195 {
ram54288 0:a7a43371b306 196 return _delayed_response;
ram54288 0:a7a43371b306 197 }
ram54288 0:a7a43371b306 198
ram54288 0:a7a43371b306 199 bool M2MResource::handle_observation_attribute(const char *query)
ram54288 0:a7a43371b306 200 {
ram54288 0:a7a43371b306 201 tr_debug("M2MResource::handle_observation_attribute - is_under_observation(%d)", is_under_observation());
ram54288 0:a7a43371b306 202 bool success = false;
ram54288 0:a7a43371b306 203 M2MReportHandler *handler = M2MBase::report_handler();
ram54288 0:a7a43371b306 204 if (!handler) {
ram54288 0:a7a43371b306 205 handler = M2MBase::create_report_handler();
ram54288 0:a7a43371b306 206 }
ram54288 0:a7a43371b306 207
ram54288 0:a7a43371b306 208 if (handler) {
ram54288 0:a7a43371b306 209 success = handler->parse_notification_attribute(query,
ram54288 0:a7a43371b306 210 M2MBase::base_type(), _resource_type);
ram54288 0:a7a43371b306 211 if (success) {
ram54288 0:a7a43371b306 212 if (is_under_observation()) {
ram54288 0:a7a43371b306 213 handler->set_under_observation(true);
ram54288 0:a7a43371b306 214 }
ram54288 0:a7a43371b306 215 }
ram54288 0:a7a43371b306 216 else {
ram54288 0:a7a43371b306 217 handler->set_default_values();
ram54288 0:a7a43371b306 218 }
ram54288 0:a7a43371b306 219
ram54288 0:a7a43371b306 220 if (success) {
ram54288 0:a7a43371b306 221 if(!_resource_instance_list.empty()) {
ram54288 0:a7a43371b306 222 M2MResourceInstanceList::const_iterator it;
ram54288 0:a7a43371b306 223 it = _resource_instance_list.begin();
ram54288 0:a7a43371b306 224 for ( ; it != _resource_instance_list.end(); it++ ) {
ram54288 0:a7a43371b306 225 M2MReportHandler *report_handler = (*it)->report_handler();
ram54288 0:a7a43371b306 226 if(report_handler && is_under_observation()) {
ram54288 0:a7a43371b306 227 report_handler->set_notification_trigger();
ram54288 0:a7a43371b306 228 }
ram54288 0:a7a43371b306 229 }
ram54288 0:a7a43371b306 230 }
ram54288 0:a7a43371b306 231 }
ram54288 0:a7a43371b306 232 }
ram54288 0:a7a43371b306 233 return success;
ram54288 0:a7a43371b306 234 }
ram54288 0:a7a43371b306 235
ram54288 0:a7a43371b306 236 void M2MResource::add_observation_level(M2MBase::Observation observation_level)
ram54288 0:a7a43371b306 237 {
ram54288 0:a7a43371b306 238 M2MBase::add_observation_level(observation_level);
ram54288 0:a7a43371b306 239 if(!_resource_instance_list.empty()) {
ram54288 0:a7a43371b306 240 M2MResourceInstanceList::const_iterator inst;
ram54288 0:a7a43371b306 241 inst = _resource_instance_list.begin();
ram54288 0:a7a43371b306 242 for ( ; inst != _resource_instance_list.end(); inst++ ) {
ram54288 0:a7a43371b306 243 (*inst)->add_observation_level(observation_level);
ram54288 0:a7a43371b306 244 }
ram54288 0:a7a43371b306 245 }
ram54288 0:a7a43371b306 246 }
ram54288 0:a7a43371b306 247
ram54288 0:a7a43371b306 248 void M2MResource::remove_observation_level(M2MBase::Observation observation_level)
ram54288 0:a7a43371b306 249 {
ram54288 0:a7a43371b306 250 M2MBase::remove_observation_level(observation_level);
ram54288 0:a7a43371b306 251 if(!_resource_instance_list.empty()) {
ram54288 0:a7a43371b306 252 M2MResourceInstanceList::const_iterator inst;
ram54288 0:a7a43371b306 253 inst = _resource_instance_list.begin();
ram54288 0:a7a43371b306 254 for ( ; inst != _resource_instance_list.end(); inst++ ) {
ram54288 0:a7a43371b306 255 (*inst)->remove_observation_level(observation_level);
ram54288 0:a7a43371b306 256 }
ram54288 0:a7a43371b306 257 }
ram54288 0:a7a43371b306 258 }
ram54288 0:a7a43371b306 259
ram54288 0:a7a43371b306 260 void M2MResource::add_resource_instance(M2MResourceInstance *res)
ram54288 0:a7a43371b306 261 {
ram54288 0:a7a43371b306 262 tr_debug("M2MResource::add_resource_instance()");
ram54288 0:a7a43371b306 263 if(res) {
ram54288 0:a7a43371b306 264 _resource_instance_list.push_back(res);
ram54288 0:a7a43371b306 265 }
ram54288 0:a7a43371b306 266 }
ram54288 0:a7a43371b306 267
ram54288 0:a7a43371b306 268 sn_coap_hdr_s* M2MResource::handle_get_request(nsdl_s *nsdl,
ram54288 0:a7a43371b306 269 sn_coap_hdr_s *received_coap_header,
ram54288 0:a7a43371b306 270 M2MObservationHandler *observation_handler)
ram54288 0:a7a43371b306 271 {
ram54288 0:a7a43371b306 272 tr_debug("M2MResource::handle_get_request()");
ram54288 0:a7a43371b306 273 sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CONTENT;
ram54288 0:a7a43371b306 274 sn_coap_hdr_s * coap_response = NULL;
ram54288 0:a7a43371b306 275 if(_has_multiple_instances) {
ram54288 0:a7a43371b306 276 coap_response = sn_nsdl_build_response(nsdl,
ram54288 0:a7a43371b306 277 received_coap_header,
ram54288 0:a7a43371b306 278 msg_code);
ram54288 0:a7a43371b306 279 if(received_coap_header) {
ram54288 0:a7a43371b306 280 // process the GET if we have registered a callback for it
ram54288 0:a7a43371b306 281 if ((operation() & SN_GRS_GET_ALLOWED) != 0) {
ram54288 0:a7a43371b306 282 if(coap_response) {
ram54288 0:a7a43371b306 283 uint16_t coap_content_type = 0;
ram54288 0:a7a43371b306 284 bool content_type_present = false;
ram54288 0:a7a43371b306 285 if(received_coap_header->content_format != COAP_CT_NONE){
ram54288 0:a7a43371b306 286 content_type_present = true;
ram54288 0:a7a43371b306 287 coap_content_type = received_coap_header->content_format;
ram54288 0:a7a43371b306 288 }
ram54288 0:a7a43371b306 289
ram54288 0:a7a43371b306 290 if(!content_type_present &&
ram54288 0:a7a43371b306 291 M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE) {
ram54288 0:a7a43371b306 292 coap_content_type = COAP_CONTENT_OMA_TLV_TYPE;
ram54288 0:a7a43371b306 293 }
ram54288 0:a7a43371b306 294
ram54288 0:a7a43371b306 295 tr_debug("M2MResource::handle_get_request() - Request Content-Type %d", coap_content_type);
ram54288 0:a7a43371b306 296 if (coap_response->content_format == COAP_CT_NONE) {
ram54288 0:a7a43371b306 297 coap_response->content_format = sn_coap_content_format_e(coap_content_type);
ram54288 0:a7a43371b306 298 if (coap_response->content_format != COAP_CT_NONE) {
ram54288 0:a7a43371b306 299 set_coap_content_type(coap_content_type);
ram54288 0:a7a43371b306 300 }
ram54288 0:a7a43371b306 301 }
ram54288 0:a7a43371b306 302 uint8_t *data = NULL;
ram54288 0:a7a43371b306 303 uint32_t data_length = 0;
ram54288 0:a7a43371b306 304 // fill in the CoAP response payload
ram54288 0:a7a43371b306 305 if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) {
ram54288 0:a7a43371b306 306 M2MTLVSerializer serializer;
ram54288 0:a7a43371b306 307 data = serializer.serialize(this, data_length);
ram54288 0:a7a43371b306 308 } else {
ram54288 0:a7a43371b306 309 msg_code = COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT; // Content format not supported
ram54288 0:a7a43371b306 310 }
ram54288 0:a7a43371b306 311
ram54288 0:a7a43371b306 312 coap_response->payload_len = data_length;
ram54288 0:a7a43371b306 313 coap_response->payload_ptr = data;
ram54288 0:a7a43371b306 314
ram54288 0:a7a43371b306 315 coap_response->options_list_ptr = sn_nsdl_alloc_options_list(nsdl, coap_response);
ram54288 0:a7a43371b306 316
ram54288 0:a7a43371b306 317 coap_response->options_list_ptr->max_age = max_age();
ram54288 0:a7a43371b306 318
ram54288 0:a7a43371b306 319 if(received_coap_header->options_list_ptr) {
ram54288 0:a7a43371b306 320 if(received_coap_header->options_list_ptr->observe != -1) {
ram54288 0:a7a43371b306 321 if (is_observable()) {
ram54288 0:a7a43371b306 322 uint32_t number = 0;
ram54288 0:a7a43371b306 323 uint8_t observe_option = 0;
ram54288 0:a7a43371b306 324 observe_option = received_coap_header->options_list_ptr->observe;
ram54288 0:a7a43371b306 325 if(START_OBSERVATION == observe_option) {
ram54288 0:a7a43371b306 326 tr_debug("M2MResource::handle_get_request - Starts Observation");
ram54288 0:a7a43371b306 327 // If the observe length is 0 means register for observation.
ram54288 0:a7a43371b306 328 if(received_coap_header->options_list_ptr->observe != -1) {
ram54288 0:a7a43371b306 329 number = received_coap_header->options_list_ptr->observe;
ram54288 0:a7a43371b306 330 }
ram54288 0:a7a43371b306 331 if(received_coap_header->token_ptr) {
ram54288 0:a7a43371b306 332 tr_debug("M2MResource::handle_get_request - Sets Observation Token to resource");
ram54288 0:a7a43371b306 333 set_observation_token(received_coap_header->token_ptr,
ram54288 0:a7a43371b306 334 received_coap_header->token_len);
ram54288 0:a7a43371b306 335 }
ram54288 0:a7a43371b306 336
ram54288 0:a7a43371b306 337 // If the observe value is 0 means register for observation.
ram54288 0:a7a43371b306 338 if(number == 0) {
ram54288 0:a7a43371b306 339 tr_debug("M2MResource::handle_get_request - Put Resource under Observation");
ram54288 0:a7a43371b306 340 M2MResourceInstanceList::const_iterator it;
ram54288 0:a7a43371b306 341 it = _resource_instance_list.begin();
ram54288 0:a7a43371b306 342 for (; it!=_resource_instance_list.end(); it++ ) {
ram54288 0:a7a43371b306 343 tr_debug("M2MResource::handle_get_request - set_resource_observer");
ram54288 0:a7a43371b306 344 (*it)->set_resource_observer(this);
ram54288 0:a7a43371b306 345 (*it)->add_observation_level(M2MBase::R_Attribute);
ram54288 0:a7a43371b306 346 }
ram54288 0:a7a43371b306 347 set_under_observation(true,observation_handler);
ram54288 0:a7a43371b306 348 M2MBase::add_observation_level(M2MBase::R_Attribute);
ram54288 0:a7a43371b306 349 coap_response->options_list_ptr->observe = observation_number();
ram54288 0:a7a43371b306 350 }
ram54288 0:a7a43371b306 351 } else if (STOP_OBSERVATION == observe_option) {
ram54288 0:a7a43371b306 352 tr_debug("M2MResource::handle_get_request - Stops Observation");
ram54288 0:a7a43371b306 353 set_under_observation(false,NULL);
ram54288 0:a7a43371b306 354 M2MBase::remove_observation_level(M2MBase::R_Attribute);
ram54288 0:a7a43371b306 355 M2MResourceInstanceList::const_iterator it;
ram54288 0:a7a43371b306 356 it = _resource_instance_list.begin();
ram54288 0:a7a43371b306 357 for (; it!=_resource_instance_list.end(); it++ ) {
ram54288 0:a7a43371b306 358 (*it)->set_resource_observer(NULL);
ram54288 0:a7a43371b306 359 }
ram54288 0:a7a43371b306 360 }
ram54288 0:a7a43371b306 361 msg_code = COAP_MSG_CODE_RESPONSE_CONTENT;
ram54288 0:a7a43371b306 362 }
ram54288 0:a7a43371b306 363 else {
ram54288 0:a7a43371b306 364 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
ram54288 0:a7a43371b306 365 }
ram54288 0:a7a43371b306 366 }
ram54288 0:a7a43371b306 367 }
ram54288 0:a7a43371b306 368 }
ram54288 0:a7a43371b306 369 } else {
ram54288 0:a7a43371b306 370 tr_error("M2MResource::handle_get_request - Return COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
ram54288 0:a7a43371b306 371 // Operation is not allowed.
ram54288 0:a7a43371b306 372 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
ram54288 0:a7a43371b306 373 }
ram54288 0:a7a43371b306 374 }
ram54288 0:a7a43371b306 375 if(coap_response) {
ram54288 0:a7a43371b306 376 coap_response->msg_code = msg_code;
ram54288 0:a7a43371b306 377 }
ram54288 0:a7a43371b306 378 } else {
ram54288 0:a7a43371b306 379 coap_response = M2MResourceInstance::handle_get_request(nsdl,
ram54288 0:a7a43371b306 380 received_coap_header,
ram54288 0:a7a43371b306 381 observation_handler);
ram54288 0:a7a43371b306 382 }
ram54288 0:a7a43371b306 383 return coap_response;
ram54288 0:a7a43371b306 384 }
ram54288 0:a7a43371b306 385
ram54288 0:a7a43371b306 386 sn_coap_hdr_s* M2MResource::handle_put_request(nsdl_s *nsdl,
ram54288 0:a7a43371b306 387 sn_coap_hdr_s *received_coap_header,
ram54288 0:a7a43371b306 388 M2MObservationHandler *observation_handler,
ram54288 0:a7a43371b306 389 bool &execute_value_updated)
ram54288 0:a7a43371b306 390 {
ram54288 0:a7a43371b306 391 tr_debug("M2MResource::handle_put_request()");
ram54288 0:a7a43371b306 392 sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04
ram54288 0:a7a43371b306 393 sn_coap_hdr_s * coap_response = NULL;
ram54288 0:a7a43371b306 394 if(_has_multiple_instances) {
ram54288 0:a7a43371b306 395 coap_response = sn_nsdl_build_response(nsdl,
ram54288 0:a7a43371b306 396 received_coap_header,
ram54288 0:a7a43371b306 397 msg_code);
ram54288 0:a7a43371b306 398 // process the PUT if we have registered a callback for it
ram54288 0:a7a43371b306 399 if(received_coap_header) {
ram54288 0:a7a43371b306 400 uint16_t coap_content_type = 0;
ram54288 0:a7a43371b306 401 bool content_type_present = false;
ram54288 0:a7a43371b306 402 if(received_coap_header->content_format != COAP_CT_NONE && coap_response) {
ram54288 0:a7a43371b306 403 content_type_present = true;
ram54288 0:a7a43371b306 404 coap_content_type = received_coap_header->content_format;
ram54288 0:a7a43371b306 405 }
ram54288 0:a7a43371b306 406 if(received_coap_header->options_list_ptr &&
ram54288 0:a7a43371b306 407 received_coap_header->options_list_ptr->uri_query_ptr) {
ram54288 0:a7a43371b306 408 char *query = (char*)alloc_string_copy(received_coap_header->options_list_ptr->uri_query_ptr,
ram54288 0:a7a43371b306 409 received_coap_header->options_list_ptr->uri_query_len);
ram54288 0:a7a43371b306 410 if (query){
ram54288 0:a7a43371b306 411 msg_code = COAP_MSG_CODE_RESPONSE_CHANGED;
ram54288 0:a7a43371b306 412 tr_debug("M2MResource::handle_put_request() - Query %s", query);
ram54288 0:a7a43371b306 413 // if anything was updated, re-initialize the stored notification attributes
ram54288 0:a7a43371b306 414 if (!handle_observation_attribute(query)){
ram54288 0:a7a43371b306 415 tr_debug("M2MResource::handle_put_request() - Invalid query");
ram54288 0:a7a43371b306 416 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // 4.00
ram54288 0:a7a43371b306 417 }
ram54288 0:a7a43371b306 418 free(query);
ram54288 0:a7a43371b306 419 }
ram54288 0:a7a43371b306 420 } else if ((operation() & SN_GRS_PUT_ALLOWED) != 0) {
ram54288 0:a7a43371b306 421 if(!content_type_present &&
ram54288 0:a7a43371b306 422 M2MBase::coap_content_type() == COAP_CONTENT_OMA_TLV_TYPE) {
ram54288 0:a7a43371b306 423 coap_content_type = COAP_CONTENT_OMA_TLV_TYPE;
ram54288 0:a7a43371b306 424 }
ram54288 0:a7a43371b306 425
ram54288 0:a7a43371b306 426 tr_debug("M2MResource::handle_put_request() - Request Content-Type %d", coap_content_type);
ram54288 0:a7a43371b306 427
ram54288 0:a7a43371b306 428 if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) {
ram54288 0:a7a43371b306 429 M2MTLVDeserializer deserializer;
ram54288 0:a7a43371b306 430 M2MTLVDeserializer::Error error = M2MTLVDeserializer::None;
ram54288 0:a7a43371b306 431 error = deserializer.deserialize_resource_instances(received_coap_header->payload_ptr,
ram54288 0:a7a43371b306 432 received_coap_header->payload_len,
ram54288 0:a7a43371b306 433 *this,
ram54288 0:a7a43371b306 434 M2MTLVDeserializer::Put);
ram54288 0:a7a43371b306 435 switch(error) {
ram54288 0:a7a43371b306 436 case M2MTLVDeserializer::None:
ram54288 0:a7a43371b306 437 if(observation_handler) {
ram54288 0:a7a43371b306 438 String value = "";
ram54288 0:a7a43371b306 439 if (received_coap_header->uri_path_ptr != NULL &&
ram54288 0:a7a43371b306 440 received_coap_header->uri_path_len > 0) {
ram54288 0:a7a43371b306 441
ram54288 0:a7a43371b306 442 value.append_raw((char*)received_coap_header->uri_path_ptr,received_coap_header->uri_path_len);
ram54288 0:a7a43371b306 443 }
ram54288 0:a7a43371b306 444 execute_value_updated = true;
ram54288 0:a7a43371b306 445 }
ram54288 0:a7a43371b306 446 msg_code = COAP_MSG_CODE_RESPONSE_CHANGED;
ram54288 0:a7a43371b306 447 break;
ram54288 0:a7a43371b306 448 case M2MTLVDeserializer::NotFound:
ram54288 0:a7a43371b306 449 msg_code = COAP_MSG_CODE_RESPONSE_NOT_FOUND;
ram54288 0:a7a43371b306 450 break;
ram54288 0:a7a43371b306 451 case M2MTLVDeserializer::NotAllowed:
ram54288 0:a7a43371b306 452 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
ram54288 0:a7a43371b306 453 break;
ram54288 0:a7a43371b306 454 case M2MTLVDeserializer::NotValid:
ram54288 0:a7a43371b306 455 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
ram54288 0:a7a43371b306 456 break;
ram54288 0:a7a43371b306 457 }
ram54288 0:a7a43371b306 458 } else {
ram54288 0:a7a43371b306 459 msg_code =COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT;
ram54288 0:a7a43371b306 460 } // if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type)
ram54288 0:a7a43371b306 461 } else {
ram54288 0:a7a43371b306 462 // Operation is not allowed.
ram54288 0:a7a43371b306 463 tr_error("M2MResource::handle_put_request() - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
ram54288 0:a7a43371b306 464 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
ram54288 0:a7a43371b306 465 }
ram54288 0:a7a43371b306 466 } else {
ram54288 0:a7a43371b306 467 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
ram54288 0:a7a43371b306 468 }
ram54288 0:a7a43371b306 469 if(coap_response) {
ram54288 0:a7a43371b306 470 coap_response->msg_code = msg_code;
ram54288 0:a7a43371b306 471 }
ram54288 0:a7a43371b306 472 } else {
ram54288 0:a7a43371b306 473 coap_response = M2MResourceInstance::handle_put_request(nsdl,
ram54288 0:a7a43371b306 474 received_coap_header,
ram54288 0:a7a43371b306 475 observation_handler,
ram54288 0:a7a43371b306 476 execute_value_updated);
ram54288 0:a7a43371b306 477 }
ram54288 0:a7a43371b306 478 return coap_response;
ram54288 0:a7a43371b306 479 }
ram54288 0:a7a43371b306 480
ram54288 0:a7a43371b306 481 sn_coap_hdr_s* M2MResource::handle_post_request(nsdl_s *nsdl,
ram54288 0:a7a43371b306 482 sn_coap_hdr_s *received_coap_header,
ram54288 0:a7a43371b306 483 M2MObservationHandler */*observation_handler*/,
ram54288 0:a7a43371b306 484 bool &/*execute_value_updated*/,
ram54288 0:a7a43371b306 485 sn_nsdl_addr_s *address)
ram54288 0:a7a43371b306 486 {
ram54288 0:a7a43371b306 487 tr_debug("M2MResource::handle_post_request()");
ram54288 0:a7a43371b306 488 sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04
ram54288 0:a7a43371b306 489 sn_coap_hdr_s * coap_response = sn_nsdl_build_response(nsdl,
ram54288 0:a7a43371b306 490 received_coap_header,
ram54288 0:a7a43371b306 491 msg_code);
ram54288 0:a7a43371b306 492 // process the POST if we have registered a callback for it
ram54288 0:a7a43371b306 493 if(received_coap_header) {
ram54288 0:a7a43371b306 494 if ((operation() & SN_GRS_POST_ALLOWED) != 0) {
ram54288 0:a7a43371b306 495 M2MResource::M2MExecuteParameter *exec_params = new M2MResource::M2MExecuteParameter();
ram54288 0:a7a43371b306 496 if (exec_params) {
ram54288 0:a7a43371b306 497 exec_params->_object_name = object_name();
ram54288 0:a7a43371b306 498 exec_params->_resource_name = name();
ram54288 0:a7a43371b306 499 exec_params->_object_instance_id = object_instance_id();
ram54288 0:a7a43371b306 500 }
ram54288 0:a7a43371b306 501 uint16_t coap_content_type = 0;
ram54288 0:a7a43371b306 502 if(received_coap_header->payload_ptr) {
ram54288 0:a7a43371b306 503 if(received_coap_header->content_format != COAP_CT_NONE) {
ram54288 0:a7a43371b306 504 coap_content_type = received_coap_header->content_format;
ram54288 0:a7a43371b306 505 }
ram54288 0:a7a43371b306 506 if(coap_content_type == 0) {
ram54288 0:a7a43371b306 507 if (exec_params){
ram54288 0:a7a43371b306 508 exec_params->_value = alloc_string_copy(received_coap_header->payload_ptr,
ram54288 0:a7a43371b306 509 received_coap_header->payload_len);
ram54288 0:a7a43371b306 510 if (exec_params->_value) {
ram54288 0:a7a43371b306 511 exec_params->_value_length = received_coap_header->payload_len;
ram54288 0:a7a43371b306 512 }
ram54288 0:a7a43371b306 513 }
ram54288 0:a7a43371b306 514 } else {
ram54288 0:a7a43371b306 515 msg_code = COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT;
ram54288 0:a7a43371b306 516 }
ram54288 0:a7a43371b306 517 }
ram54288 0:a7a43371b306 518 if(COAP_MSG_CODE_RESPONSE_CHANGED == msg_code) {
ram54288 0:a7a43371b306 519 tr_debug("M2MResource::handle_post_request - Execute resource function");
ram54288 0:a7a43371b306 520 if(_delayed_response) {
ram54288 0:a7a43371b306 521 msg_code = COAP_MSG_CODE_EMPTY;
ram54288 0:a7a43371b306 522 coap_response->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT;
ram54288 0:a7a43371b306 523 coap_response->msg_code = msg_code;
ram54288 0:a7a43371b306 524 coap_response->msg_id = received_coap_header->msg_id;
ram54288 0:a7a43371b306 525 if(received_coap_header->token_len) {
ram54288 0:a7a43371b306 526 free(_delayed_token);
ram54288 0:a7a43371b306 527 _delayed_token = NULL;
ram54288 0:a7a43371b306 528 _delayed_token_len = 0;
ram54288 0:a7a43371b306 529 _delayed_token = alloc_copy(received_coap_header->token_ptr, received_coap_header->token_len);
ram54288 0:a7a43371b306 530 if(_delayed_token) {
ram54288 0:a7a43371b306 531 _delayed_token_len = received_coap_header->token_len;
ram54288 0:a7a43371b306 532 }
ram54288 0:a7a43371b306 533 sn_nsdl_send_coap_message(nsdl, address, coap_response);
ram54288 0:a7a43371b306 534 }
ram54288 0:a7a43371b306 535 } else {
ram54288 0:a7a43371b306 536 uint32_t length = 0;
ram54288 0:a7a43371b306 537 get_value(coap_response->payload_ptr, length);
ram54288 0:a7a43371b306 538 coap_response->payload_len = length;
ram54288 0:a7a43371b306 539 }
ram54288 0:a7a43371b306 540 execute(exec_params);
ram54288 0:a7a43371b306 541 }
ram54288 0:a7a43371b306 542 delete exec_params;
ram54288 0:a7a43371b306 543 } else { // if ((object->operation() & SN_GRS_POST_ALLOWED) != 0)
ram54288 0:a7a43371b306 544 tr_error("M2MResource::handle_post_request - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
ram54288 0:a7a43371b306 545 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; // 4.05
ram54288 0:a7a43371b306 546 }
ram54288 0:a7a43371b306 547 } else { //if(object && received_coap_header)
ram54288 0:a7a43371b306 548 tr_error("M2MResource::handle_post_request - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
ram54288 0:a7a43371b306 549 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; // 4.01
ram54288 0:a7a43371b306 550 }
ram54288 0:a7a43371b306 551 if(coap_response) {
ram54288 0:a7a43371b306 552 coap_response->msg_code = msg_code;
ram54288 0:a7a43371b306 553 }
ram54288 0:a7a43371b306 554 return coap_response;
ram54288 0:a7a43371b306 555 }
ram54288 0:a7a43371b306 556
ram54288 0:a7a43371b306 557 void M2MResource::notification_update()
ram54288 0:a7a43371b306 558 {
ram54288 0:a7a43371b306 559 tr_debug("M2MResource::notification_update()");
ram54288 0:a7a43371b306 560 M2MReportHandler *report_handler = M2MBase::report_handler();
ram54288 0:a7a43371b306 561 if(report_handler && is_observable()) {
ram54288 0:a7a43371b306 562 report_handler->set_notification_trigger();
ram54288 0:a7a43371b306 563 }
ram54288 0:a7a43371b306 564 }
ram54288 0:a7a43371b306 565
ram54288 0:a7a43371b306 566 M2MObjectInstance& M2MResource::get_parent_object_instance() const
ram54288 0:a7a43371b306 567 {
ram54288 0:a7a43371b306 568 return _parent;
ram54288 0:a7a43371b306 569 }
ram54288 0:a7a43371b306 570
ram54288 0:a7a43371b306 571 const char* M2MResource::object_name() const
ram54288 0:a7a43371b306 572 {
ram54288 0:a7a43371b306 573 const M2MObjectInstance& parent_object_instance = _parent;
ram54288 0:a7a43371b306 574 const M2MObject& parent_object = parent_object_instance.get_parent_object();
ram54288 0:a7a43371b306 575
ram54288 0:a7a43371b306 576 return parent_object.name();
ram54288 0:a7a43371b306 577 }
ram54288 0:a7a43371b306 578
ram54288 0:a7a43371b306 579
ram54288 0:a7a43371b306 580 M2MResource::M2MExecuteParameter::M2MExecuteParameter()
ram54288 0:a7a43371b306 581 {
ram54288 0:a7a43371b306 582 _value = NULL;
ram54288 0:a7a43371b306 583 _value_length = 0;
ram54288 0:a7a43371b306 584 _object_name = "";
ram54288 0:a7a43371b306 585 _resource_name = "";
ram54288 0:a7a43371b306 586 _object_instance_id = 0;
ram54288 0:a7a43371b306 587 }
ram54288 0:a7a43371b306 588
ram54288 0:a7a43371b306 589 M2MResource::M2MExecuteParameter::~M2MExecuteParameter()
ram54288 0:a7a43371b306 590 {
ram54288 0:a7a43371b306 591 free(_value);
ram54288 0:a7a43371b306 592 }
ram54288 0:a7a43371b306 593
ram54288 0:a7a43371b306 594 uint8_t *M2MResource::M2MExecuteParameter::get_argument_value() const
ram54288 0:a7a43371b306 595 {
ram54288 0:a7a43371b306 596 return _value;
ram54288 0:a7a43371b306 597 }
ram54288 0:a7a43371b306 598
ram54288 0:a7a43371b306 599 uint16_t M2MResource::M2MExecuteParameter::get_argument_value_length() const
ram54288 0:a7a43371b306 600 {
ram54288 0:a7a43371b306 601 return _value_length;
ram54288 0:a7a43371b306 602 }
ram54288 0:a7a43371b306 603
ram54288 0:a7a43371b306 604 const String& M2MResource::M2MExecuteParameter::get_argument_object_name() const
ram54288 0:a7a43371b306 605 {
ram54288 0:a7a43371b306 606 return _object_name;
ram54288 0:a7a43371b306 607 }
ram54288 0:a7a43371b306 608
ram54288 0:a7a43371b306 609 const String& M2MResource::M2MExecuteParameter::get_argument_resource_name() const
ram54288 0:a7a43371b306 610 {
ram54288 0:a7a43371b306 611 return _resource_name;
ram54288 0:a7a43371b306 612 }
ram54288 0:a7a43371b306 613
ram54288 0:a7a43371b306 614 uint16_t M2MResource::M2MExecuteParameter::get_argument_object_instance_id() const
ram54288 0:a7a43371b306 615 {
ram54288 0:a7a43371b306 616 return _object_instance_id;
ram54288 0:a7a43371b306 617 }
ram54288 0:a7a43371b306 618
ram54288 0:a7a43371b306 619