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