FRDM K64F Metronome

Committer:
ram54288
Date:
Sun May 14 18:37:05 2017 +0000
Revision:
0:dbad57390bd1
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ram54288 0:dbad57390bd1 1 /*
ram54288 0:dbad57390bd1 2 * Copyright (c) 2015 ARM Limited. All rights reserved.
ram54288 0:dbad57390bd1 3 * SPDX-License-Identifier: Apache-2.0
ram54288 0:dbad57390bd1 4 * Licensed under the Apache License, Version 2.0 (the License); you may
ram54288 0:dbad57390bd1 5 * not use this file except in compliance with the License.
ram54288 0:dbad57390bd1 6 * You may obtain a copy of the License at
ram54288 0:dbad57390bd1 7 *
ram54288 0:dbad57390bd1 8 * http://www.apache.org/licenses/LICENSE-2.0
ram54288 0:dbad57390bd1 9 *
ram54288 0:dbad57390bd1 10 * Unless required by applicable law or agreed to in writing, software
ram54288 0:dbad57390bd1 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
ram54288 0:dbad57390bd1 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ram54288 0:dbad57390bd1 13 * See the License for the specific language governing permissions and
ram54288 0:dbad57390bd1 14 * limitations under the License.
ram54288 0:dbad57390bd1 15 */
ram54288 0:dbad57390bd1 16 #include <stdlib.h>
ram54288 0:dbad57390bd1 17 #include "mbed-client/m2mresource.h"
ram54288 0:dbad57390bd1 18 #include "mbed-client/m2mconstants.h"
ram54288 0:dbad57390bd1 19 #include "mbed-client/m2mobservationhandler.h"
ram54288 0:dbad57390bd1 20 #include "mbed-client/m2mobject.h"
ram54288 0:dbad57390bd1 21 #include "mbed-client/m2mobjectinstance.h"
ram54288 0:dbad57390bd1 22 #include "include/m2mreporthandler.h"
ram54288 0:dbad57390bd1 23 #include "include/nsdllinker.h"
ram54288 0:dbad57390bd1 24 #include "mbed-client/m2mblockmessage.h"
ram54288 0:dbad57390bd1 25 #include "mbed-trace/mbed_trace.h"
ram54288 0:dbad57390bd1 26
ram54288 0:dbad57390bd1 27 #define TRACE_GROUP "mClt"
ram54288 0:dbad57390bd1 28
ram54288 0:dbad57390bd1 29 M2MResourceInstance::M2MResourceInstance(M2MResource &parent,
ram54288 0:dbad57390bd1 30 const String &res_name,
ram54288 0:dbad57390bd1 31 const String &resource_type,
ram54288 0:dbad57390bd1 32 M2MResourceInstance::ResourceType type,
ram54288 0:dbad57390bd1 33 const uint16_t object_instance_id,
ram54288 0:dbad57390bd1 34 char* path,
ram54288 0:dbad57390bd1 35 bool external_blockwise_store)
ram54288 0:dbad57390bd1 36 : M2MBase(res_name,
ram54288 0:dbad57390bd1 37 M2MBase::Dynamic,
ram54288 0:dbad57390bd1 38 resource_type,
ram54288 0:dbad57390bd1 39 path,
ram54288 0:dbad57390bd1 40 external_blockwise_store),
ram54288 0:dbad57390bd1 41 _parent_resource(parent),
ram54288 0:dbad57390bd1 42 _value(NULL),
ram54288 0:dbad57390bd1 43 _value_length(0),
ram54288 0:dbad57390bd1 44 _block_message_data(NULL),
ram54288 0:dbad57390bd1 45 _execute_callback(NULL),
ram54288 0:dbad57390bd1 46 _resource_callback(NULL),
ram54288 0:dbad57390bd1 47 _execute_function_pointer(NULL),
ram54288 0:dbad57390bd1 48 _notification_sent_function_pointer(NULL),
ram54288 0:dbad57390bd1 49 _incoming_block_message_cb(NULL),
ram54288 0:dbad57390bd1 50 _outgoing_block_message_cb(NULL),
ram54288 0:dbad57390bd1 51 _notification_sent_callback(NULL),
ram54288 0:dbad57390bd1 52 _object_instance_id(object_instance_id),
ram54288 0:dbad57390bd1 53 _resource_type(type)
ram54288 0:dbad57390bd1 54 {
ram54288 0:dbad57390bd1 55 M2MBase::set_base_type(M2MBase::ResourceInstance);
ram54288 0:dbad57390bd1 56 }
ram54288 0:dbad57390bd1 57
ram54288 0:dbad57390bd1 58 M2MResourceInstance::M2MResourceInstance(M2MResource &parent,
ram54288 0:dbad57390bd1 59 const String &res_name,
ram54288 0:dbad57390bd1 60 const String &resource_type,
ram54288 0:dbad57390bd1 61 M2MResourceInstance::ResourceType type,
ram54288 0:dbad57390bd1 62 const uint8_t *value,
ram54288 0:dbad57390bd1 63 const uint8_t value_length,
ram54288 0:dbad57390bd1 64 const uint16_t object_instance_id,
ram54288 0:dbad57390bd1 65 char* path,
ram54288 0:dbad57390bd1 66 bool external_blockwise_store)
ram54288 0:dbad57390bd1 67 : M2MBase(res_name,
ram54288 0:dbad57390bd1 68 M2MBase::Static,
ram54288 0:dbad57390bd1 69 resource_type,
ram54288 0:dbad57390bd1 70 path,
ram54288 0:dbad57390bd1 71 external_blockwise_store),
ram54288 0:dbad57390bd1 72 _parent_resource(parent),
ram54288 0:dbad57390bd1 73 _value(NULL),
ram54288 0:dbad57390bd1 74 _value_length(0),
ram54288 0:dbad57390bd1 75 _block_message_data(NULL),
ram54288 0:dbad57390bd1 76 _execute_callback(NULL),
ram54288 0:dbad57390bd1 77 _resource_callback(NULL),
ram54288 0:dbad57390bd1 78 _execute_function_pointer(NULL),
ram54288 0:dbad57390bd1 79 _notification_sent_function_pointer(NULL),
ram54288 0:dbad57390bd1 80 _incoming_block_message_cb(NULL),
ram54288 0:dbad57390bd1 81 _outgoing_block_message_cb(NULL),
ram54288 0:dbad57390bd1 82 _notification_sent_callback(NULL),
ram54288 0:dbad57390bd1 83 _object_instance_id(object_instance_id),
ram54288 0:dbad57390bd1 84 _resource_type(type)
ram54288 0:dbad57390bd1 85 {
ram54288 0:dbad57390bd1 86 M2MBase::set_base_type(M2MBase::Resource);
ram54288 0:dbad57390bd1 87 if (mode() == M2MBase::Dynamic) {
ram54288 0:dbad57390bd1 88 if( value != NULL && value_length > 0 ) {
ram54288 0:dbad57390bd1 89 _value = alloc_string_copy(value, value_length);
ram54288 0:dbad57390bd1 90 if(_value) {
ram54288 0:dbad57390bd1 91 _value_length = value_length;
ram54288 0:dbad57390bd1 92 }
ram54288 0:dbad57390bd1 93 }
ram54288 0:dbad57390bd1 94 }
ram54288 0:dbad57390bd1 95 // Copy resource value to struct since static resources are handled in mbed-client-c
ram54288 0:dbad57390bd1 96 else if (mode() == M2MBase::Static) {
ram54288 0:dbad57390bd1 97 sn_nsdl_dynamic_resource_parameters_s* res = get_nsdl_resource();
ram54288 0:dbad57390bd1 98 sn_nsdl_static_resource_parameters_s* params = (sn_nsdl_static_resource_parameters_s*)res->static_resource_parameters;
ram54288 0:dbad57390bd1 99 params->resource = alloc_string_copy(value, value_length);
ram54288 0:dbad57390bd1 100 params->resourcelen = value_length;
ram54288 0:dbad57390bd1 101 }
ram54288 0:dbad57390bd1 102 else {
ram54288 0:dbad57390bd1 103 // Directory, not supported
ram54288 0:dbad57390bd1 104 }
ram54288 0:dbad57390bd1 105 }
ram54288 0:dbad57390bd1 106
ram54288 0:dbad57390bd1 107 M2MResourceInstance::M2MResourceInstance(M2MResource &parent,
ram54288 0:dbad57390bd1 108 const lwm2m_parameters_s* s,
ram54288 0:dbad57390bd1 109 M2MResourceInstance::ResourceType type,
ram54288 0:dbad57390bd1 110 const uint16_t object_instance_id)
ram54288 0:dbad57390bd1 111 : M2MBase(s),
ram54288 0:dbad57390bd1 112 _parent_resource(parent),
ram54288 0:dbad57390bd1 113 _value(NULL),
ram54288 0:dbad57390bd1 114 _value_length(0),
ram54288 0:dbad57390bd1 115 _block_message_data(NULL),
ram54288 0:dbad57390bd1 116 _execute_callback(NULL),
ram54288 0:dbad57390bd1 117 _resource_callback(NULL),
ram54288 0:dbad57390bd1 118 _execute_function_pointer(NULL),
ram54288 0:dbad57390bd1 119 _notification_sent_function_pointer(NULL),
ram54288 0:dbad57390bd1 120 _incoming_block_message_cb(NULL),
ram54288 0:dbad57390bd1 121 _outgoing_block_message_cb(NULL),
ram54288 0:dbad57390bd1 122 _notification_sent_callback(NULL),
ram54288 0:dbad57390bd1 123 _object_instance_id(object_instance_id),
ram54288 0:dbad57390bd1 124 _resource_type(type)
ram54288 0:dbad57390bd1 125 {
ram54288 0:dbad57390bd1 126 //TBD: put to flash, or parse from the uri_path!!!!
ram54288 0:dbad57390bd1 127 //same for the _object_instance_id.
ram54288 0:dbad57390bd1 128 // TBD: we dont need _value here, because in c-struct there is resource field!!!!
ram54288 0:dbad57390bd1 129 if( s->dynamic_resource_params->static_resource_parameters->resource != NULL &&
ram54288 0:dbad57390bd1 130 s->dynamic_resource_params->static_resource_parameters->resourcelen > 0 ) {
ram54288 0:dbad57390bd1 131 _value = alloc_string_copy(s->dynamic_resource_params->static_resource_parameters->resource,
ram54288 0:dbad57390bd1 132 s->dynamic_resource_params->static_resource_parameters->resourcelen);
ram54288 0:dbad57390bd1 133 if(_value) {
ram54288 0:dbad57390bd1 134 _value_length = s->dynamic_resource_params->static_resource_parameters->resourcelen;
ram54288 0:dbad57390bd1 135 }
ram54288 0:dbad57390bd1 136 }
ram54288 0:dbad57390bd1 137 //M2MBase::set_base_type(M2MBase::ResourceInstance);
ram54288 0:dbad57390bd1 138 }
ram54288 0:dbad57390bd1 139
ram54288 0:dbad57390bd1 140 M2MResourceInstance::~M2MResourceInstance()
ram54288 0:dbad57390bd1 141 {
ram54288 0:dbad57390bd1 142 free(_value);
ram54288 0:dbad57390bd1 143 delete _execute_function_pointer;
ram54288 0:dbad57390bd1 144 delete _execute_callback;
ram54288 0:dbad57390bd1 145 delete _notification_sent_function_pointer;
ram54288 0:dbad57390bd1 146 delete _incoming_block_message_cb;
ram54288 0:dbad57390bd1 147 delete _outgoing_block_message_cb;
ram54288 0:dbad57390bd1 148 delete _notification_sent_callback;
ram54288 0:dbad57390bd1 149 delete _block_message_data;
ram54288 0:dbad57390bd1 150 }
ram54288 0:dbad57390bd1 151
ram54288 0:dbad57390bd1 152 M2MBase::BaseType M2MResourceInstance::base_type() const
ram54288 0:dbad57390bd1 153 {
ram54288 0:dbad57390bd1 154 return M2MBase::base_type();
ram54288 0:dbad57390bd1 155 }
ram54288 0:dbad57390bd1 156
ram54288 0:dbad57390bd1 157 M2MResourceInstance::ResourceType M2MResourceInstance::resource_instance_type() const
ram54288 0:dbad57390bd1 158 {
ram54288 0:dbad57390bd1 159 return _resource_type;
ram54288 0:dbad57390bd1 160 }
ram54288 0:dbad57390bd1 161
ram54288 0:dbad57390bd1 162 bool M2MResourceInstance::handle_observation_attribute(const char *query)
ram54288 0:dbad57390bd1 163 {
ram54288 0:dbad57390bd1 164 tr_debug("M2MResourceInstance::handle_observation_attribute - is_under_observation(%d)", is_under_observation());
ram54288 0:dbad57390bd1 165 bool success = false;
ram54288 0:dbad57390bd1 166
ram54288 0:dbad57390bd1 167 M2MReportHandler *handler = M2MBase::report_handler();
ram54288 0:dbad57390bd1 168 if (!handler) {
ram54288 0:dbad57390bd1 169 handler = M2MBase::create_report_handler();
ram54288 0:dbad57390bd1 170 }
ram54288 0:dbad57390bd1 171
ram54288 0:dbad57390bd1 172 if (handler) {
ram54288 0:dbad57390bd1 173 success = handler->parse_notification_attribute(query,
ram54288 0:dbad57390bd1 174 M2MBase::base_type(), _resource_type);
ram54288 0:dbad57390bd1 175 if(success) {
ram54288 0:dbad57390bd1 176 if (is_under_observation()) {
ram54288 0:dbad57390bd1 177 handler->set_under_observation(true);
ram54288 0:dbad57390bd1 178 }
ram54288 0:dbad57390bd1 179 } else {
ram54288 0:dbad57390bd1 180 handler->set_default_values();
ram54288 0:dbad57390bd1 181 }
ram54288 0:dbad57390bd1 182 }
ram54288 0:dbad57390bd1 183 return success;
ram54288 0:dbad57390bd1 184 }
ram54288 0:dbad57390bd1 185
ram54288 0:dbad57390bd1 186 void M2MResourceInstance::set_execute_function(execute_callback callback)
ram54288 0:dbad57390bd1 187 {
ram54288 0:dbad57390bd1 188 delete _execute_callback;
ram54288 0:dbad57390bd1 189 _execute_callback = new execute_callback(callback);
ram54288 0:dbad57390bd1 190 }
ram54288 0:dbad57390bd1 191
ram54288 0:dbad57390bd1 192 void M2MResourceInstance::set_execute_function(execute_callback_2 callback)
ram54288 0:dbad57390bd1 193 {
ram54288 0:dbad57390bd1 194 delete _execute_function_pointer;
ram54288 0:dbad57390bd1 195
ram54288 0:dbad57390bd1 196 _execute_function_pointer = new FP1<void, void*>(callback);
ram54288 0:dbad57390bd1 197 set_execute_function(execute_callback(_execute_function_pointer, &FP1<void, void*>::call));
ram54288 0:dbad57390bd1 198 }
ram54288 0:dbad57390bd1 199
ram54288 0:dbad57390bd1 200 void M2MResourceInstance::clear_value()
ram54288 0:dbad57390bd1 201 {
ram54288 0:dbad57390bd1 202 tr_debug("M2MResourceInstance::clear_value");
ram54288 0:dbad57390bd1 203
ram54288 0:dbad57390bd1 204 free(_value);
ram54288 0:dbad57390bd1 205 _value = NULL;
ram54288 0:dbad57390bd1 206 _value_length = 0;
ram54288 0:dbad57390bd1 207
ram54288 0:dbad57390bd1 208 report();
ram54288 0:dbad57390bd1 209 }
ram54288 0:dbad57390bd1 210
ram54288 0:dbad57390bd1 211 bool M2MResourceInstance::set_value(int64_t value)
ram54288 0:dbad57390bd1 212 {
ram54288 0:dbad57390bd1 213 bool success;
ram54288 0:dbad57390bd1 214 // max len of "-9223372036854775808" plus zero termination
ram54288 0:dbad57390bd1 215 char buffer[20+1];
ram54288 0:dbad57390bd1 216 uint32_t size = m2m::itoa_c(value, buffer);
ram54288 0:dbad57390bd1 217
ram54288 0:dbad57390bd1 218 success = set_value((const uint8_t*)buffer, size);
ram54288 0:dbad57390bd1 219
ram54288 0:dbad57390bd1 220 return success;
ram54288 0:dbad57390bd1 221 }
ram54288 0:dbad57390bd1 222
ram54288 0:dbad57390bd1 223 bool M2MResourceInstance::set_value(const uint8_t *value,
ram54288 0:dbad57390bd1 224 const uint32_t value_length)
ram54288 0:dbad57390bd1 225 {
ram54288 0:dbad57390bd1 226 tr_debug("M2MResourceInstance::set_value()");
ram54288 0:dbad57390bd1 227 bool success = false;
ram54288 0:dbad57390bd1 228 bool value_changed = false;
ram54288 0:dbad57390bd1 229 if(is_value_changed(value,value_length)) {
ram54288 0:dbad57390bd1 230 value_changed = true;
ram54288 0:dbad57390bd1 231 }
ram54288 0:dbad57390bd1 232 if( value != NULL && value_length > 0 ) {
ram54288 0:dbad57390bd1 233 success = true;
ram54288 0:dbad57390bd1 234
ram54288 0:dbad57390bd1 235 free(_value);
ram54288 0:dbad57390bd1 236 _value_length = 0;
ram54288 0:dbad57390bd1 237
ram54288 0:dbad57390bd1 238 _value = alloc_string_copy(value, value_length);
ram54288 0:dbad57390bd1 239 if(_value) {
ram54288 0:dbad57390bd1 240 _value_length = value_length;
ram54288 0:dbad57390bd1 241 if( value_changed ) { //
ram54288 0:dbad57390bd1 242 if (_resource_type == M2MResourceInstance::STRING) {
ram54288 0:dbad57390bd1 243 M2MReportHandler *report_handler = M2MBase::report_handler();
ram54288 0:dbad57390bd1 244 if(report_handler && is_under_observation()) {
ram54288 0:dbad57390bd1 245 report_handler->set_notification_trigger();
ram54288 0:dbad57390bd1 246 }
ram54288 0:dbad57390bd1 247 }
ram54288 0:dbad57390bd1 248 else {
ram54288 0:dbad57390bd1 249 report();
ram54288 0:dbad57390bd1 250 }
ram54288 0:dbad57390bd1 251 }
ram54288 0:dbad57390bd1 252 }
ram54288 0:dbad57390bd1 253 }
ram54288 0:dbad57390bd1 254 return success;
ram54288 0:dbad57390bd1 255 }
ram54288 0:dbad57390bd1 256
ram54288 0:dbad57390bd1 257 void M2MResourceInstance::report()
ram54288 0:dbad57390bd1 258 {
ram54288 0:dbad57390bd1 259 tr_debug("M2MResourceInstance::report()");
ram54288 0:dbad57390bd1 260 M2MBase::Observation observation_level = M2MBase::observation_level();
ram54288 0:dbad57390bd1 261 tr_debug("M2MResourceInstance::report() - level %d", observation_level);
ram54288 0:dbad57390bd1 262 if((M2MBase::O_Attribute & observation_level) == M2MBase::O_Attribute ||
ram54288 0:dbad57390bd1 263 (M2MBase::OI_Attribute & observation_level) == M2MBase::OI_Attribute) {
ram54288 0:dbad57390bd1 264 tr_debug("M2MResourceInstance::report() -- object/instance level");
ram54288 0:dbad57390bd1 265 M2MObjectInstance& object_instance = get_parent_resource().get_parent_object_instance();
ram54288 0:dbad57390bd1 266 object_instance.notification_update(observation_level);
ram54288 0:dbad57390bd1 267 }
ram54288 0:dbad57390bd1 268
ram54288 0:dbad57390bd1 269 if(M2MBase::Dynamic == mode() &&
ram54288 0:dbad57390bd1 270 (M2MBase::R_Attribute & observation_level) == M2MBase::R_Attribute) {
ram54288 0:dbad57390bd1 271 tr_debug("M2MResourceInstance::report() - resource level");
ram54288 0:dbad57390bd1 272 if(!_resource_callback && _resource_type != M2MResourceInstance::STRING) {
ram54288 0:dbad57390bd1 273 M2MReportHandler *report_handler = M2MBase::report_handler();
ram54288 0:dbad57390bd1 274 if (report_handler && is_observable()) {
ram54288 0:dbad57390bd1 275 if(_value) {
ram54288 0:dbad57390bd1 276 report_handler->set_value(atof((const char*)_value));
ram54288 0:dbad57390bd1 277 } else {
ram54288 0:dbad57390bd1 278 report_handler->set_value(0);
ram54288 0:dbad57390bd1 279 }
ram54288 0:dbad57390bd1 280 }
ram54288 0:dbad57390bd1 281 }
ram54288 0:dbad57390bd1 282 else {
ram54288 0:dbad57390bd1 283 if (_resource_callback && base_type() == M2MBase::ResourceInstance) {
ram54288 0:dbad57390bd1 284 _resource_callback->notification_update();
ram54288 0:dbad57390bd1 285 }
ram54288 0:dbad57390bd1 286 }
ram54288 0:dbad57390bd1 287 } else if(M2MBase::Static == mode()) {
ram54288 0:dbad57390bd1 288 M2MObservationHandler *observation_handler = M2MBase::observation_handler();
ram54288 0:dbad57390bd1 289 if(observation_handler) {
ram54288 0:dbad57390bd1 290 observation_handler->value_updated(this);
ram54288 0:dbad57390bd1 291 }
ram54288 0:dbad57390bd1 292 } else {
ram54288 0:dbad57390bd1 293 tr_debug("M2MResourceInstance::report() - mode = %d, is_observable = %d", mode(), is_observable());
ram54288 0:dbad57390bd1 294 }
ram54288 0:dbad57390bd1 295 }
ram54288 0:dbad57390bd1 296
ram54288 0:dbad57390bd1 297 bool M2MResourceInstance::is_value_changed(const uint8_t* value, const uint32_t value_len)
ram54288 0:dbad57390bd1 298 {
ram54288 0:dbad57390bd1 299 bool changed = false;
ram54288 0:dbad57390bd1 300 if(value_len != _value_length) {
ram54288 0:dbad57390bd1 301 changed = true;
ram54288 0:dbad57390bd1 302 } else if(value && !_value) {
ram54288 0:dbad57390bd1 303 changed = true;
ram54288 0:dbad57390bd1 304 } else if(_value && !value) {
ram54288 0:dbad57390bd1 305 changed = true;
ram54288 0:dbad57390bd1 306 } else {
ram54288 0:dbad57390bd1 307 if (_value) {
ram54288 0:dbad57390bd1 308 if (strcmp((char*)value, (char*)_value) != 0) {
ram54288 0:dbad57390bd1 309 changed = true;
ram54288 0:dbad57390bd1 310 }
ram54288 0:dbad57390bd1 311 }
ram54288 0:dbad57390bd1 312 }
ram54288 0:dbad57390bd1 313 tr_debug("M2MResourceInstance::is_value_changed() -- %s", changed ? "true" : "false");
ram54288 0:dbad57390bd1 314 return changed;
ram54288 0:dbad57390bd1 315 }
ram54288 0:dbad57390bd1 316
ram54288 0:dbad57390bd1 317 void M2MResourceInstance::execute(void *arguments)
ram54288 0:dbad57390bd1 318 {
ram54288 0:dbad57390bd1 319 tr_debug("M2MResourceInstance::execute");
ram54288 0:dbad57390bd1 320 if(_execute_callback) {
ram54288 0:dbad57390bd1 321 (*_execute_callback)(arguments);
ram54288 0:dbad57390bd1 322 }
ram54288 0:dbad57390bd1 323 }
ram54288 0:dbad57390bd1 324
ram54288 0:dbad57390bd1 325 void M2MResourceInstance::get_value(uint8_t *&value, uint32_t &value_length)
ram54288 0:dbad57390bd1 326 {
ram54288 0:dbad57390bd1 327 value_length = 0;
ram54288 0:dbad57390bd1 328 if(value) {
ram54288 0:dbad57390bd1 329 free(value);
ram54288 0:dbad57390bd1 330 value = NULL;
ram54288 0:dbad57390bd1 331 }
ram54288 0:dbad57390bd1 332 if(_value && _value_length > 0) {
ram54288 0:dbad57390bd1 333 value = alloc_string_copy(_value, _value_length);
ram54288 0:dbad57390bd1 334 if(value) {
ram54288 0:dbad57390bd1 335 value_length = _value_length;
ram54288 0:dbad57390bd1 336 }
ram54288 0:dbad57390bd1 337 }
ram54288 0:dbad57390bd1 338 }
ram54288 0:dbad57390bd1 339
ram54288 0:dbad57390bd1 340 int M2MResourceInstance::get_value_int()
ram54288 0:dbad57390bd1 341 {
ram54288 0:dbad57390bd1 342 int value_int = 0;
ram54288 0:dbad57390bd1 343 // Get the value and convert it into integer. This is not the most
ram54288 0:dbad57390bd1 344 // efficient way, as it takes pointless heap copy to get the zero termination.
ram54288 0:dbad57390bd1 345 uint8_t* buffer = NULL;
ram54288 0:dbad57390bd1 346 uint32_t length;
ram54288 0:dbad57390bd1 347 get_value(buffer,length);
ram54288 0:dbad57390bd1 348 if(buffer) {
ram54288 0:dbad57390bd1 349 value_int = atoi((const char*)buffer);
ram54288 0:dbad57390bd1 350 free(buffer);
ram54288 0:dbad57390bd1 351 }
ram54288 0:dbad57390bd1 352 return value_int;
ram54288 0:dbad57390bd1 353 }
ram54288 0:dbad57390bd1 354
ram54288 0:dbad57390bd1 355 String M2MResourceInstance::get_value_string() const
ram54288 0:dbad57390bd1 356 {
ram54288 0:dbad57390bd1 357 // XXX: do a better constructor to avoid pointless malloc
ram54288 0:dbad57390bd1 358 String value;
ram54288 0:dbad57390bd1 359 if (_value) {
ram54288 0:dbad57390bd1 360 value.append_raw((char*)_value, _value_length);
ram54288 0:dbad57390bd1 361 }
ram54288 0:dbad57390bd1 362
ram54288 0:dbad57390bd1 363 return value;
ram54288 0:dbad57390bd1 364 }
ram54288 0:dbad57390bd1 365
ram54288 0:dbad57390bd1 366 uint8_t* M2MResourceInstance::value() const
ram54288 0:dbad57390bd1 367 {
ram54288 0:dbad57390bd1 368 return _value;
ram54288 0:dbad57390bd1 369 }
ram54288 0:dbad57390bd1 370
ram54288 0:dbad57390bd1 371 uint32_t M2MResourceInstance::value_length() const
ram54288 0:dbad57390bd1 372 {
ram54288 0:dbad57390bd1 373 return _value_length;
ram54288 0:dbad57390bd1 374 }
ram54288 0:dbad57390bd1 375
ram54288 0:dbad57390bd1 376 sn_coap_hdr_s* M2MResourceInstance::handle_get_request(nsdl_s *nsdl,
ram54288 0:dbad57390bd1 377 sn_coap_hdr_s *received_coap_header,
ram54288 0:dbad57390bd1 378 M2MObservationHandler *observation_handler)
ram54288 0:dbad57390bd1 379 {
ram54288 0:dbad57390bd1 380 tr_debug("M2MResourceInstance::handle_get_request()");
ram54288 0:dbad57390bd1 381 sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CONTENT;
ram54288 0:dbad57390bd1 382 sn_coap_hdr_s *coap_response = sn_nsdl_build_response(nsdl,
ram54288 0:dbad57390bd1 383 received_coap_header,
ram54288 0:dbad57390bd1 384 msg_code);
ram54288 0:dbad57390bd1 385 if(received_coap_header) {
ram54288 0:dbad57390bd1 386 // process the GET if we have registered a callback for it
ram54288 0:dbad57390bd1 387 if ((operation() & SN_GRS_GET_ALLOWED) != 0) {
ram54288 0:dbad57390bd1 388 if(coap_response) {
ram54288 0:dbad57390bd1 389 if(_resource_type == M2MResourceInstance::OPAQUE) {
ram54288 0:dbad57390bd1 390 coap_response->content_format = sn_coap_content_format_e(COAP_CONTENT_OMA_OPAQUE_TYPE);
ram54288 0:dbad57390bd1 391 } else {
ram54288 0:dbad57390bd1 392 coap_response->content_format = sn_coap_content_format_e(0);
ram54288 0:dbad57390bd1 393 }
ram54288 0:dbad57390bd1 394 // fill in the CoAP response payload
ram54288 0:dbad57390bd1 395 coap_response->payload_ptr = NULL;
ram54288 0:dbad57390bd1 396 uint32_t payload_len = 0;
ram54288 0:dbad57390bd1 397
ram54288 0:dbad57390bd1 398 //If handler exists it means that resource value is stored in application side
ram54288 0:dbad57390bd1 399 if (block_message() && block_message()->is_block_message()) {
ram54288 0:dbad57390bd1 400 if(_outgoing_block_message_cb) {
ram54288 0:dbad57390bd1 401 String name = "";
ram54288 0:dbad57390bd1 402 if (received_coap_header->uri_path_ptr != NULL &&
ram54288 0:dbad57390bd1 403 received_coap_header->uri_path_len > 0) {
ram54288 0:dbad57390bd1 404 name.append_raw((char *)received_coap_header->uri_path_ptr,
ram54288 0:dbad57390bd1 405 received_coap_header->uri_path_len);
ram54288 0:dbad57390bd1 406 }
ram54288 0:dbad57390bd1 407 (*_outgoing_block_message_cb)(name, coap_response->payload_ptr, payload_len);
ram54288 0:dbad57390bd1 408 }
ram54288 0:dbad57390bd1 409 } else {
ram54288 0:dbad57390bd1 410 get_value(coap_response->payload_ptr,payload_len);
ram54288 0:dbad57390bd1 411 }
ram54288 0:dbad57390bd1 412
ram54288 0:dbad57390bd1 413 coap_response->payload_len = payload_len;
ram54288 0:dbad57390bd1 414 coap_response->options_list_ptr = sn_nsdl_alloc_options_list(nsdl, coap_response);
ram54288 0:dbad57390bd1 415
ram54288 0:dbad57390bd1 416 coap_response->options_list_ptr->max_age = max_age();
ram54288 0:dbad57390bd1 417
ram54288 0:dbad57390bd1 418 if(received_coap_header->options_list_ptr) {
ram54288 0:dbad57390bd1 419 if(received_coap_header->options_list_ptr->observe != -1) {
ram54288 0:dbad57390bd1 420 if (is_observable()) {
ram54288 0:dbad57390bd1 421 uint32_t number = 0;
ram54288 0:dbad57390bd1 422 uint8_t observe_option = 0;
ram54288 0:dbad57390bd1 423 observe_option = received_coap_header->options_list_ptr->observe;
ram54288 0:dbad57390bd1 424
ram54288 0:dbad57390bd1 425 if(START_OBSERVATION == observe_option) {
ram54288 0:dbad57390bd1 426 tr_debug("M2MResourceInstance::handle_get_request - Starts Observation");
ram54288 0:dbad57390bd1 427 // If the observe length is 0 means register for observation.
ram54288 0:dbad57390bd1 428 if(received_coap_header->options_list_ptr->observe != -1) {
ram54288 0:dbad57390bd1 429 number = received_coap_header->options_list_ptr->observe;
ram54288 0:dbad57390bd1 430 }
ram54288 0:dbad57390bd1 431 if(received_coap_header->token_ptr) {
ram54288 0:dbad57390bd1 432 tr_debug("M2MResourceInstance::handle_get_request - Sets Observation Token to resource");
ram54288 0:dbad57390bd1 433 set_observation_token(received_coap_header->token_ptr,
ram54288 0:dbad57390bd1 434 received_coap_header->token_len);
ram54288 0:dbad57390bd1 435 }
ram54288 0:dbad57390bd1 436 // If the observe value is 0 means register for observation.
ram54288 0:dbad57390bd1 437 if(number == 0) {
ram54288 0:dbad57390bd1 438 tr_debug("M2MResourceInstance::handle_get_request - Put Resource under Observation");
ram54288 0:dbad57390bd1 439 set_under_observation(true,observation_handler);
ram54288 0:dbad57390bd1 440 M2MBase::add_observation_level(M2MBase::R_Attribute);
ram54288 0:dbad57390bd1 441 coap_response->options_list_ptr->observe = observation_number();
ram54288 0:dbad57390bd1 442 }
ram54288 0:dbad57390bd1 443 } else if (STOP_OBSERVATION == observe_option) {
ram54288 0:dbad57390bd1 444 tr_debug("M2MResourceInstance::handle_get_request - Stops Observation");
ram54288 0:dbad57390bd1 445 set_under_observation(false,NULL);
ram54288 0:dbad57390bd1 446 M2MBase::remove_observation_level(M2MBase::R_Attribute);
ram54288 0:dbad57390bd1 447 }
ram54288 0:dbad57390bd1 448 } else {
ram54288 0:dbad57390bd1 449 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
ram54288 0:dbad57390bd1 450 }
ram54288 0:dbad57390bd1 451 }
ram54288 0:dbad57390bd1 452 }
ram54288 0:dbad57390bd1 453 }
ram54288 0:dbad57390bd1 454 }else {
ram54288 0:dbad57390bd1 455 tr_error("M2MResourceInstance::handle_get_request - Return COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
ram54288 0:dbad57390bd1 456 // Operation is not allowed.
ram54288 0:dbad57390bd1 457 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
ram54288 0:dbad57390bd1 458 }
ram54288 0:dbad57390bd1 459 } else {
ram54288 0:dbad57390bd1 460 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
ram54288 0:dbad57390bd1 461 }
ram54288 0:dbad57390bd1 462 if(coap_response) {
ram54288 0:dbad57390bd1 463 coap_response->msg_code = msg_code;
ram54288 0:dbad57390bd1 464 }
ram54288 0:dbad57390bd1 465 return coap_response;
ram54288 0:dbad57390bd1 466 }
ram54288 0:dbad57390bd1 467
ram54288 0:dbad57390bd1 468 sn_coap_hdr_s* M2MResourceInstance::handle_put_request(nsdl_s *nsdl,
ram54288 0:dbad57390bd1 469 sn_coap_hdr_s *received_coap_header,
ram54288 0:dbad57390bd1 470 M2MObservationHandler *observation_handler,
ram54288 0:dbad57390bd1 471 bool &execute_value_updated)
ram54288 0:dbad57390bd1 472 {
ram54288 0:dbad57390bd1 473 tr_debug("M2MResourceInstance::handle_put_request()");
ram54288 0:dbad57390bd1 474
ram54288 0:dbad57390bd1 475
ram54288 0:dbad57390bd1 476 sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04
ram54288 0:dbad57390bd1 477 sn_coap_hdr_s *coap_response = sn_nsdl_build_response(nsdl,
ram54288 0:dbad57390bd1 478 received_coap_header,
ram54288 0:dbad57390bd1 479 msg_code);
ram54288 0:dbad57390bd1 480 // process the PUT if we have registered a callback for it
ram54288 0:dbad57390bd1 481 if(received_coap_header && coap_response) {
ram54288 0:dbad57390bd1 482 uint16_t coap_content_type = 0;
ram54288 0:dbad57390bd1 483 if(received_coap_header->content_format != COAP_CT_NONE) {
ram54288 0:dbad57390bd1 484 coap_content_type = received_coap_header->content_format;
ram54288 0:dbad57390bd1 485 }
ram54288 0:dbad57390bd1 486 if(received_coap_header->options_list_ptr &&
ram54288 0:dbad57390bd1 487 received_coap_header->options_list_ptr->uri_query_ptr) {
ram54288 0:dbad57390bd1 488 char *query = (char*)alloc_string_copy(received_coap_header->options_list_ptr->uri_query_ptr,
ram54288 0:dbad57390bd1 489 received_coap_header->options_list_ptr->uri_query_len);
ram54288 0:dbad57390bd1 490 if (query){
ram54288 0:dbad57390bd1 491 tr_debug("M2MResourceInstance::handle_put_request() - Query %s", query);
ram54288 0:dbad57390bd1 492
ram54288 0:dbad57390bd1 493 // if anything was updated, re-initialize the stored notification attributes
ram54288 0:dbad57390bd1 494 if (!handle_observation_attribute(query)){
ram54288 0:dbad57390bd1 495 tr_debug("M2MResourceInstance::handle_put_request() - Invalid query");
ram54288 0:dbad57390bd1 496 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // 4.00
ram54288 0:dbad57390bd1 497 }
ram54288 0:dbad57390bd1 498 free(query);
ram54288 0:dbad57390bd1 499 }
ram54288 0:dbad57390bd1 500 } else if ((operation() & SN_GRS_PUT_ALLOWED) != 0) {
ram54288 0:dbad57390bd1 501 tr_debug("M2MResourceInstance::handle_put_request() - Request Content-Type %d", coap_content_type);
ram54288 0:dbad57390bd1 502
ram54288 0:dbad57390bd1 503 if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) {
ram54288 0:dbad57390bd1 504 msg_code = COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT;
ram54288 0:dbad57390bd1 505 } else {
ram54288 0:dbad57390bd1 506 bool external_block_store = false;
ram54288 0:dbad57390bd1 507 if (block_message()) {
ram54288 0:dbad57390bd1 508 block_message()->set_message_info(received_coap_header);
ram54288 0:dbad57390bd1 509 if (block_message()->is_block_message()) {
ram54288 0:dbad57390bd1 510 external_block_store = true;
ram54288 0:dbad57390bd1 511 if(_incoming_block_message_cb) {
ram54288 0:dbad57390bd1 512 (*_incoming_block_message_cb)(_block_message_data);
ram54288 0:dbad57390bd1 513 }
ram54288 0:dbad57390bd1 514 if (block_message()->is_last_block()) {
ram54288 0:dbad57390bd1 515 block_message()->clear_values();
ram54288 0:dbad57390bd1 516 coap_response->coap_status = COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED;
ram54288 0:dbad57390bd1 517 } else {
ram54288 0:dbad57390bd1 518 coap_response->coap_status = COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING;
ram54288 0:dbad57390bd1 519 }
ram54288 0:dbad57390bd1 520 if (block_message()->error_code() != M2MBlockMessage::ErrorNone) {
ram54288 0:dbad57390bd1 521 block_message()->clear_values();
ram54288 0:dbad57390bd1 522 }
ram54288 0:dbad57390bd1 523 }
ram54288 0:dbad57390bd1 524 }
ram54288 0:dbad57390bd1 525 if (!external_block_store) {
ram54288 0:dbad57390bd1 526 set_value(received_coap_header->payload_ptr, received_coap_header->payload_len);
ram54288 0:dbad57390bd1 527 }
ram54288 0:dbad57390bd1 528 if(received_coap_header->payload_ptr) {
ram54288 0:dbad57390bd1 529 tr_debug("M2MResourceInstance::handle_put_request() - Update Resource with new values");
ram54288 0:dbad57390bd1 530 if(observation_handler) {
ram54288 0:dbad57390bd1 531 String value = "";
ram54288 0:dbad57390bd1 532 if (received_coap_header->uri_path_ptr != NULL &&
ram54288 0:dbad57390bd1 533 received_coap_header->uri_path_len > 0) {
ram54288 0:dbad57390bd1 534 value.append_raw((char*)received_coap_header->uri_path_ptr, received_coap_header->uri_path_len);
ram54288 0:dbad57390bd1 535 }
ram54288 0:dbad57390bd1 536 execute_value_updated = true;
ram54288 0:dbad57390bd1 537 }
ram54288 0:dbad57390bd1 538 }
ram54288 0:dbad57390bd1 539 }
ram54288 0:dbad57390bd1 540 } else {
ram54288 0:dbad57390bd1 541 // Operation is not allowed.
ram54288 0:dbad57390bd1 542 tr_error("M2MResourceInstance::handle_put_request() - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
ram54288 0:dbad57390bd1 543 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
ram54288 0:dbad57390bd1 544 }
ram54288 0:dbad57390bd1 545 } else {
ram54288 0:dbad57390bd1 546 msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
ram54288 0:dbad57390bd1 547 }
ram54288 0:dbad57390bd1 548 if(coap_response) {
ram54288 0:dbad57390bd1 549 coap_response->msg_code = msg_code;
ram54288 0:dbad57390bd1 550 }
ram54288 0:dbad57390bd1 551
ram54288 0:dbad57390bd1 552 return coap_response;
ram54288 0:dbad57390bd1 553 }
ram54288 0:dbad57390bd1 554
ram54288 0:dbad57390bd1 555 void M2MResourceInstance::set_resource_observer(M2MResourceCallback *resource)
ram54288 0:dbad57390bd1 556 {
ram54288 0:dbad57390bd1 557 _resource_callback = resource;
ram54288 0:dbad57390bd1 558 }
ram54288 0:dbad57390bd1 559
ram54288 0:dbad57390bd1 560 uint16_t M2MResourceInstance::object_instance_id() const
ram54288 0:dbad57390bd1 561 {
ram54288 0:dbad57390bd1 562 return _object_instance_id;
ram54288 0:dbad57390bd1 563 }
ram54288 0:dbad57390bd1 564
ram54288 0:dbad57390bd1 565 M2MBlockMessage* M2MResourceInstance::block_message() const
ram54288 0:dbad57390bd1 566 {
ram54288 0:dbad57390bd1 567 return _block_message_data;
ram54288 0:dbad57390bd1 568 }
ram54288 0:dbad57390bd1 569
ram54288 0:dbad57390bd1 570 void M2MResourceInstance::set_incoming_block_message_callback(incoming_block_message_callback callback)
ram54288 0:dbad57390bd1 571 {
ram54288 0:dbad57390bd1 572 // copy the callback object. This will change on next version to be a direct pointer to a interface class,
ram54288 0:dbad57390bd1 573 // this FPn<> is just too heavy for this usage.
ram54288 0:dbad57390bd1 574 delete _incoming_block_message_cb;
ram54288 0:dbad57390bd1 575 _incoming_block_message_cb = new incoming_block_message_callback(callback);
ram54288 0:dbad57390bd1 576
ram54288 0:dbad57390bd1 577 delete _block_message_data;
ram54288 0:dbad57390bd1 578 _block_message_data = NULL;
ram54288 0:dbad57390bd1 579 _block_message_data = new M2MBlockMessage();
ram54288 0:dbad57390bd1 580 }
ram54288 0:dbad57390bd1 581
ram54288 0:dbad57390bd1 582 void M2MResourceInstance::set_outgoing_block_message_callback(outgoing_block_message_callback callback)
ram54288 0:dbad57390bd1 583 {
ram54288 0:dbad57390bd1 584 delete _outgoing_block_message_cb;
ram54288 0:dbad57390bd1 585 _outgoing_block_message_cb = new outgoing_block_message_callback(callback);
ram54288 0:dbad57390bd1 586 }
ram54288 0:dbad57390bd1 587
ram54288 0:dbad57390bd1 588 void M2MResourceInstance::set_notification_sent_callback(notification_sent_callback callback)
ram54288 0:dbad57390bd1 589 {
ram54288 0:dbad57390bd1 590 delete _notification_sent_callback;
ram54288 0:dbad57390bd1 591 _notification_sent_callback = new notification_sent_callback(callback);
ram54288 0:dbad57390bd1 592 }
ram54288 0:dbad57390bd1 593
ram54288 0:dbad57390bd1 594 void M2MResourceInstance::set_notification_sent_callback(notification_sent_callback_2 callback)
ram54288 0:dbad57390bd1 595 {
ram54288 0:dbad57390bd1 596 delete _notification_sent_function_pointer;
ram54288 0:dbad57390bd1 597
ram54288 0:dbad57390bd1 598 _notification_sent_function_pointer = new FP0<void>(callback);
ram54288 0:dbad57390bd1 599 set_notification_sent_callback(
ram54288 0:dbad57390bd1 600 notification_sent_callback(_notification_sent_function_pointer, &FP0<void>::call));
ram54288 0:dbad57390bd1 601 }
ram54288 0:dbad57390bd1 602
ram54288 0:dbad57390bd1 603 void M2MResourceInstance::notification_sent()
ram54288 0:dbad57390bd1 604 {
ram54288 0:dbad57390bd1 605 if (_notification_sent_callback) {
ram54288 0:dbad57390bd1 606 (*_notification_sent_callback)();
ram54288 0:dbad57390bd1 607 }
ram54288 0:dbad57390bd1 608 }
ram54288 0:dbad57390bd1 609
ram54288 0:dbad57390bd1 610 M2MResource& M2MResourceInstance::get_parent_resource() const
ram54288 0:dbad57390bd1 611 {
ram54288 0:dbad57390bd1 612 return _parent_resource;
ram54288 0:dbad57390bd1 613 }
ram54288 0:dbad57390bd1 614
ram54288 0:dbad57390bd1 615 const char* M2MResourceInstance::object_name() const
ram54288 0:dbad57390bd1 616 {
ram54288 0:dbad57390bd1 617 const M2MObjectInstance& parent_object_instance = _parent_resource.get_parent_object_instance();
ram54288 0:dbad57390bd1 618 const M2MObject& parent_object = parent_object_instance.get_parent_object();
ram54288 0:dbad57390bd1 619
ram54288 0:dbad57390bd1 620 return parent_object.name();
ram54288 0:dbad57390bd1 621 }