This is an example of BLE GATT Client, which receives broadcast data from BLE_Server_BME280 ( a GATT server) , then transfers values up to mbed Device Connector (cloud).

Please refer details about BLEClient_mbedDevConn below. https://github.com/soramame21/BLEClient_mbedDevConn

The location of required BLE GATT server, BLE_Server_BME280, is at here. https://developer.mbed.org/users/edamame22/code/BLE_Server_BME280/

Committer:
edamame22
Date:
Thu Apr 13 04:48:11 2017 +0000
Revision:
0:29983394c6b6
Initial commit

Who changed what in which revision?

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