Dependencies:   MMA7660 LM75B

Committer:
MACRUM
Date:
Sat Jun 30 01:40:30 2018 +0000
Revision:
0:119624335925
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MACRUM 0:119624335925 1 /*
MACRUM 0:119624335925 2 * Copyright (c) 2015 ARM Limited. All rights reserved.
MACRUM 0:119624335925 3 * SPDX-License-Identifier: Apache-2.0
MACRUM 0:119624335925 4 * Licensed under the Apache License, Version 2.0 (the License); you may
MACRUM 0:119624335925 5 * not use this file except in compliance with the License.
MACRUM 0:119624335925 6 * You may obtain a copy of the License at
MACRUM 0:119624335925 7 *
MACRUM 0:119624335925 8 * http://www.apache.org/licenses/LICENSE-2.0
MACRUM 0:119624335925 9 *
MACRUM 0:119624335925 10 * Unless required by applicable law or agreed to in writing, software
MACRUM 0:119624335925 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
MACRUM 0:119624335925 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
MACRUM 0:119624335925 13 * See the License for the specific language governing permissions and
MACRUM 0:119624335925 14 * limitations under the License.
MACRUM 0:119624335925 15 */
MACRUM 0:119624335925 16
MACRUM 0:119624335925 17 // Needed for PRIu64 on FreeRTOS
MACRUM 0:119624335925 18 #include <stdio.h>
MACRUM 0:119624335925 19 // Note: this macro is needed on armcc to get the the limit macros like UINT16_MAX
MACRUM 0:119624335925 20 #ifndef __STDC_LIMIT_MACROS
MACRUM 0:119624335925 21 #define __STDC_LIMIT_MACROS
MACRUM 0:119624335925 22 #endif
MACRUM 0:119624335925 23
MACRUM 0:119624335925 24 // Note: this macro is needed on armcc to get the the PRI*32 macros
MACRUM 0:119624335925 25 // from inttypes.h in a C++ code.
MACRUM 0:119624335925 26 #ifndef __STDC_FORMAT_MACROS
MACRUM 0:119624335925 27 #define __STDC_FORMAT_MACROS
MACRUM 0:119624335925 28 #endif
MACRUM 0:119624335925 29
MACRUM 0:119624335925 30 #include <assert.h>
MACRUM 0:119624335925 31 #include <inttypes.h>
MACRUM 0:119624335925 32 #include <stdlib.h>
MACRUM 0:119624335925 33 #include "include/nsdlaccesshelper.h"
MACRUM 0:119624335925 34 #include "include/m2mnsdlobserver.h"
MACRUM 0:119624335925 35 #include "include/m2mtlvdeserializer.h"
MACRUM 0:119624335925 36 #include "include/m2mtlvserializer.h"
MACRUM 0:119624335925 37 #include "include/m2mnsdlinterface.h"
MACRUM 0:119624335925 38 #include "include/uriqueryparser.h"
MACRUM 0:119624335925 39 #include "include/m2mreporthandler.h"
MACRUM 0:119624335925 40 #include "mbed-client/m2mstring.h"
MACRUM 0:119624335925 41 #include "mbed-client/m2msecurity.h"
MACRUM 0:119624335925 42 #include "mbed-client/m2mserver.h"
MACRUM 0:119624335925 43 #include "mbed-client/m2mobject.h"
MACRUM 0:119624335925 44 #include "mbed-client/m2mobjectinstance.h"
MACRUM 0:119624335925 45 #include "mbed-client/m2mresource.h"
MACRUM 0:119624335925 46 #include "mbed-client/m2mblockmessage.h"
MACRUM 0:119624335925 47 #include "mbed-client/m2mconstants.h"
MACRUM 0:119624335925 48 #include "mbed-trace/mbed_trace.h"
MACRUM 0:119624335925 49 #include "sn_grs.h"
MACRUM 0:119624335925 50 #include "mbed-client/m2minterfacefactory.h"
MACRUM 0:119624335925 51 #include "mbed-client/m2mdevice.h"
MACRUM 0:119624335925 52 #include "randLIB.h"
MACRUM 0:119624335925 53 #include "common_functions.h"
MACRUM 0:119624335925 54 #include "sn_nsdl_lib.h"
MACRUM 0:119624335925 55
MACRUM 0:119624335925 56 #define BUFFER_SIZE 21
MACRUM 0:119624335925 57 #define TRACE_GROUP "mClt"
MACRUM 0:119624335925 58 #define MAX_QUERY_COUNT 10
MACRUM 0:119624335925 59
MACRUM 0:119624335925 60 const char *MCC_VERSION = "mccv=1.2.6";
MACRUM 0:119624335925 61
MACRUM 0:119624335925 62 M2MNsdlInterface::M2MNsdlInterface(M2MNsdlObserver &observer, M2MConnectionHandler &connection_handler)
MACRUM 0:119624335925 63 : _observer(observer),
MACRUM 0:119624335925 64 _endpoint(NULL),
MACRUM 0:119624335925 65 _nsdl_handle(NULL),
MACRUM 0:119624335925 66 _security(NULL),
MACRUM 0:119624335925 67 _server(NULL),
MACRUM 0:119624335925 68 _nsdl_exceution_timer(*this),
MACRUM 0:119624335925 69 _registration_timer(*this),
MACRUM 0:119624335925 70 _connection_handler(connection_handler),
MACRUM 0:119624335925 71 _counter_for_nsdl(0),
MACRUM 0:119624335925 72 _bootstrap_id(0),
MACRUM 0:119624335925 73 _server_address(NULL),
MACRUM 0:119624335925 74 _unregister_ongoing(false),
MACRUM 0:119624335925 75 _identity_accepted(false),
MACRUM 0:119624335925 76 _nsdl_exceution_timer_running(false),
MACRUM 0:119624335925 77 _binding_mode(M2MInterface::NOT_SET)
MACRUM 0:119624335925 78 {
MACRUM 0:119624335925 79 tr_debug("M2MNsdlInterface::M2MNsdlInterface()");
MACRUM 0:119624335925 80 _sn_nsdl_address.addr_len = 0;
MACRUM 0:119624335925 81 _sn_nsdl_address.addr_ptr = NULL;
MACRUM 0:119624335925 82 _sn_nsdl_address.port = 0;
MACRUM 0:119624335925 83 _sn_nsdl_address.type = SN_NSDL_ADDRESS_TYPE_NONE;
MACRUM 0:119624335925 84 _server = new M2MServer();
MACRUM 0:119624335925 85 // This initializes libCoap and libNsdl
MACRUM 0:119624335925 86 // Parameters are function pointers to used memory allocation
MACRUM 0:119624335925 87 // and free functions in structure and used functions for sending
MACRUM 0:119624335925 88 // and receiving purposes.
MACRUM 0:119624335925 89 _nsdl_handle = sn_nsdl_init(&(__nsdl_c_send_to_server), &(__nsdl_c_received_from_server),
MACRUM 0:119624335925 90 &(__nsdl_c_memory_alloc), &(__nsdl_c_memory_free), &(__nsdl_c_auto_obs_token));
MACRUM 0:119624335925 91 sn_nsdl_set_context(_nsdl_handle, this);
MACRUM 0:119624335925 92
MACRUM 0:119624335925 93 // Randomize the initial auto obs token. Range is in 1 - 1023
MACRUM 0:119624335925 94 _auto_obs_token = randLIB_get_random_in_range(AUTO_OBS_TOKEN_MIN, AUTO_OBS_TOKEN_MAX);
MACRUM 0:119624335925 95
MACRUM 0:119624335925 96 initialize();
MACRUM 0:119624335925 97 }
MACRUM 0:119624335925 98
MACRUM 0:119624335925 99 M2MNsdlInterface::~M2MNsdlInterface()
MACRUM 0:119624335925 100 {
MACRUM 0:119624335925 101 tr_debug("M2MNsdlInterface::~M2MNsdlInterface() - IN");
MACRUM 0:119624335925 102 if(_endpoint) {
MACRUM 0:119624335925 103 memory_free(_endpoint->endpoint_name_ptr);
MACRUM 0:119624335925 104 memory_free(_endpoint->domain_name_ptr);
MACRUM 0:119624335925 105 memory_free(_endpoint->type_ptr);
MACRUM 0:119624335925 106 memory_free(_endpoint->lifetime_ptr);
MACRUM 0:119624335925 107 memory_free(_endpoint);
MACRUM 0:119624335925 108 }
MACRUM 0:119624335925 109 _object_list.clear();
MACRUM 0:119624335925 110 _security = NULL;
MACRUM 0:119624335925 111 delete _server;
MACRUM 0:119624335925 112 sn_nsdl_destroy(_nsdl_handle);
MACRUM 0:119624335925 113 _nsdl_handle = NULL;
MACRUM 0:119624335925 114 free(_server_address);
MACRUM 0:119624335925 115 free_get_request_list();
MACRUM 0:119624335925 116 tr_debug("M2MNsdlInterface::~M2MNsdlInterface() - OUT");
MACRUM 0:119624335925 117 }
MACRUM 0:119624335925 118
MACRUM 0:119624335925 119 bool M2MNsdlInterface::initialize()
MACRUM 0:119624335925 120 {
MACRUM 0:119624335925 121 tr_debug("M2MNsdlInterface::initialize()");
MACRUM 0:119624335925 122 bool success = false;
MACRUM 0:119624335925 123
MACRUM 0:119624335925 124 // Sets the packet retransmission attempts and time interval
MACRUM 0:119624335925 125 sn_nsdl_set_retransmission_parameters(_nsdl_handle,
MACRUM 0:119624335925 126 MBED_CLIENT_RECONNECTION_COUNT,
MACRUM 0:119624335925 127 MBED_CLIENT_RECONNECTION_INTERVAL);
MACRUM 0:119624335925 128
MACRUM 0:119624335925 129 sn_nsdl_handle_block2_response_internally(_nsdl_handle, false);
MACRUM 0:119624335925 130
MACRUM 0:119624335925 131 // Allocate the memory for endpoint
MACRUM 0:119624335925 132 _endpoint = (sn_nsdl_ep_parameters_s*)memory_alloc(sizeof(sn_nsdl_ep_parameters_s));
MACRUM 0:119624335925 133 if(_endpoint) {
MACRUM 0:119624335925 134 memset(_endpoint, 0, sizeof(sn_nsdl_ep_parameters_s));
MACRUM 0:119624335925 135 success = true;
MACRUM 0:119624335925 136 }
MACRUM 0:119624335925 137
MACRUM 0:119624335925 138 M2MResource* update_trigger = _server->get_resource(M2MServer::RegistrationUpdate);
MACRUM 0:119624335925 139 if (update_trigger) {
MACRUM 0:119624335925 140 update_trigger->set_execute_function(execute_callback(this,
MACRUM 0:119624335925 141 &M2MNsdlInterface::update_trigger_callback));
MACRUM 0:119624335925 142 }
MACRUM 0:119624335925 143
MACRUM 0:119624335925 144 add_object_to_list(_server);
MACRUM 0:119624335925 145 create_nsdl_object_structure(_server);
MACRUM 0:119624335925 146 ns_list_init(&_get_request_list);
MACRUM 0:119624335925 147
MACRUM 0:119624335925 148 return success;
MACRUM 0:119624335925 149 }
MACRUM 0:119624335925 150
MACRUM 0:119624335925 151 void M2MNsdlInterface::create_endpoint(const String &name,
MACRUM 0:119624335925 152 const String &type,
MACRUM 0:119624335925 153 const int32_t life_time,
MACRUM 0:119624335925 154 const String &domain,
MACRUM 0:119624335925 155 const uint8_t mode,
MACRUM 0:119624335925 156 const String &/*context_address*/)
MACRUM 0:119624335925 157 {
MACRUM 0:119624335925 158 tr_info("M2MNsdlInterface::create_endpoint( name %s type %s lifetime %" PRId32 ", domain %s, mode %d)",
MACRUM 0:119624335925 159 name.c_str(), type.c_str(), life_time, domain.c_str(), mode);
MACRUM 0:119624335925 160 _endpoint_name = name;
MACRUM 0:119624335925 161 _binding_mode = mode;
MACRUM 0:119624335925 162 if(_endpoint){
MACRUM 0:119624335925 163 memset(_endpoint, 0, sizeof(sn_nsdl_ep_parameters_s));
MACRUM 0:119624335925 164 if(!_endpoint_name.empty()) {
MACRUM 0:119624335925 165 memory_free(_endpoint->endpoint_name_ptr);
MACRUM 0:119624335925 166 _endpoint->endpoint_name_ptr = alloc_string_copy((uint8_t*)_endpoint_name.c_str(), _endpoint_name.length());
MACRUM 0:119624335925 167 _endpoint->endpoint_name_len = _endpoint_name.length();
MACRUM 0:119624335925 168 }
MACRUM 0:119624335925 169 if(!type.empty()) {
MACRUM 0:119624335925 170 _endpoint->type_ptr = alloc_string_copy((uint8_t*)type.c_str(), type.length());
MACRUM 0:119624335925 171 _endpoint->type_len = type.length();
MACRUM 0:119624335925 172 }
MACRUM 0:119624335925 173 if(!domain.empty()) {
MACRUM 0:119624335925 174 _endpoint->domain_name_ptr = alloc_string_copy((uint8_t*)domain.c_str(), domain.length());
MACRUM 0:119624335925 175 _endpoint->domain_name_len = domain.length();
MACRUM 0:119624335925 176 }
MACRUM 0:119624335925 177
MACRUM 0:119624335925 178 // nsdl binding mode is only 3 least significant bits
MACRUM 0:119624335925 179 _endpoint->binding_and_mode = (sn_nsdl_oma_binding_and_mode_t)((uint8_t)mode & 0x07);
MACRUM 0:119624335925 180
MACRUM 0:119624335925 181 // If lifetime is less than zero then leave the field empty
MACRUM 0:119624335925 182 if( life_time > 0) {
MACRUM 0:119624335925 183 set_endpoint_lifetime_buffer(life_time);
MACRUM 0:119624335925 184 }
MACRUM 0:119624335925 185 }
MACRUM 0:119624335925 186 }
MACRUM 0:119624335925 187
MACRUM 0:119624335925 188 void M2MNsdlInterface::update_endpoint(const String &name)
MACRUM 0:119624335925 189 {
MACRUM 0:119624335925 190 _endpoint_name = name;
MACRUM 0:119624335925 191 if(_endpoint){
MACRUM 0:119624335925 192 if(!_endpoint_name.empty()) {
MACRUM 0:119624335925 193 memory_free(_endpoint->endpoint_name_ptr);
MACRUM 0:119624335925 194 _endpoint->endpoint_name_ptr = alloc_string_copy((uint8_t*)_endpoint_name.c_str(), _endpoint_name.length());
MACRUM 0:119624335925 195 _endpoint->endpoint_name_len = _endpoint_name.length();
MACRUM 0:119624335925 196 }
MACRUM 0:119624335925 197 }
MACRUM 0:119624335925 198 }
MACRUM 0:119624335925 199
MACRUM 0:119624335925 200 void M2MNsdlInterface::update_domain(const String &domain)
MACRUM 0:119624335925 201 {
MACRUM 0:119624335925 202 if(_endpoint){
MACRUM 0:119624335925 203 memory_free(_endpoint->domain_name_ptr);
MACRUM 0:119624335925 204 _endpoint->domain_name_len = 0;
MACRUM 0:119624335925 205 if(!domain.empty()) {
MACRUM 0:119624335925 206 _endpoint->domain_name_ptr = alloc_string_copy((uint8_t*)domain.c_str(), domain.length());
MACRUM 0:119624335925 207 _endpoint->domain_name_len = domain.length();
MACRUM 0:119624335925 208 }
MACRUM 0:119624335925 209 }
MACRUM 0:119624335925 210 }
MACRUM 0:119624335925 211
MACRUM 0:119624335925 212 void M2MNsdlInterface::set_endpoint_lifetime_buffer(int lifetime)
MACRUM 0:119624335925 213 {
MACRUM 0:119624335925 214 tr_debug("M2MNsdlInterface::set_endpoint_lifetime_buffer - %d", lifetime);
MACRUM 0:119624335925 215 if (lifetime < 60) {
MACRUM 0:119624335925 216 return;
MACRUM 0:119624335925 217 }
MACRUM 0:119624335925 218
MACRUM 0:119624335925 219 _server->set_resource_value(M2MServer::Lifetime, lifetime);
MACRUM 0:119624335925 220
MACRUM 0:119624335925 221 if (_endpoint && _endpoint->lifetime_ptr) {
MACRUM 0:119624335925 222 memory_free(_endpoint->lifetime_ptr);
MACRUM 0:119624335925 223 _endpoint->lifetime_ptr = NULL;
MACRUM 0:119624335925 224 _endpoint->lifetime_len = 0;
MACRUM 0:119624335925 225 }
MACRUM 0:119624335925 226
MACRUM 0:119624335925 227 char buffer[20+1];
MACRUM 0:119624335925 228 uint32_t size = m2m::itoa_c(lifetime, buffer);
MACRUM 0:119624335925 229 if (_endpoint && size <= sizeof(buffer)) {
MACRUM 0:119624335925 230 _endpoint->lifetime_len = 0;
MACRUM 0:119624335925 231 _endpoint->lifetime_ptr = alloc_string_copy((uint8_t*)buffer, size);
MACRUM 0:119624335925 232 if (_endpoint->lifetime_ptr) {
MACRUM 0:119624335925 233 _endpoint->lifetime_len = size;
MACRUM 0:119624335925 234 }
MACRUM 0:119624335925 235 }
MACRUM 0:119624335925 236 }
MACRUM 0:119624335925 237
MACRUM 0:119624335925 238
MACRUM 0:119624335925 239 void M2MNsdlInterface::delete_endpoint()
MACRUM 0:119624335925 240 {
MACRUM 0:119624335925 241 tr_debug("M2MNsdlInterface::delete_endpoint()");
MACRUM 0:119624335925 242 if(_endpoint) {
MACRUM 0:119624335925 243 free(_endpoint->lifetime_ptr);
MACRUM 0:119624335925 244 memory_free(_endpoint);
MACRUM 0:119624335925 245 _endpoint = NULL;
MACRUM 0:119624335925 246 }
MACRUM 0:119624335925 247 }
MACRUM 0:119624335925 248
MACRUM 0:119624335925 249 bool M2MNsdlInterface::create_nsdl_list_structure(const M2MObjectList &object_list)
MACRUM 0:119624335925 250 {
MACRUM 0:119624335925 251 tr_debug("M2MNsdlInterface::create_nsdl_list_structure()");
MACRUM 0:119624335925 252 bool success = false;
MACRUM 0:119624335925 253 if(!object_list.empty()) {
MACRUM 0:119624335925 254 M2MObjectList::const_iterator it;
MACRUM 0:119624335925 255 it = object_list.begin();
MACRUM 0:119624335925 256 for ( ; it != object_list.end(); it++ ) {
MACRUM 0:119624335925 257 // Create NSDL structure for all Objects inside
MACRUM 0:119624335925 258 success = create_nsdl_object_structure(*it);
MACRUM 0:119624335925 259 add_object_to_list(*it);
MACRUM 0:119624335925 260 }
MACRUM 0:119624335925 261 }
MACRUM 0:119624335925 262 if (!success) {
MACRUM 0:119624335925 263 tr_error("M2MNsdlInterface::create_nsdl_list_structure - fail!");
MACRUM 0:119624335925 264 }
MACRUM 0:119624335925 265 return success;
MACRUM 0:119624335925 266 }
MACRUM 0:119624335925 267
MACRUM 0:119624335925 268 bool M2MNsdlInterface::remove_nsdl_resource(M2MBase *base)
MACRUM 0:119624335925 269 {
MACRUM 0:119624335925 270 sn_nsdl_dynamic_resource_parameters_s* resource = base->get_nsdl_resource();
MACRUM 0:119624335925 271 return sn_nsdl_pop_resource(_nsdl_handle, resource);
MACRUM 0:119624335925 272 }
MACRUM 0:119624335925 273
MACRUM 0:119624335925 274 bool M2MNsdlInterface::create_bootstrap_resource(sn_nsdl_addr_s *address)
MACRUM 0:119624335925 275 {
MACRUM 0:119624335925 276 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
MACRUM 0:119624335925 277 tr_debug("M2MNsdlInterface::create_bootstrap_resource()");
MACRUM 0:119624335925 278 _identity_accepted = false;
MACRUM 0:119624335925 279 bool success = false;
MACRUM 0:119624335925 280 sn_nsdl_bs_ep_info_t bootstrap_endpoint;
MACRUM 0:119624335925 281 tr_debug("M2MNsdlInterface::create_bootstrap_resource() - endpoint name: %.*s", _endpoint->endpoint_name_len,
MACRUM 0:119624335925 282 _endpoint->endpoint_name_ptr);
MACRUM 0:119624335925 283
MACRUM 0:119624335925 284 if(_bootstrap_id == 0) {
MACRUM 0:119624335925 285 // Take copy of the address, uri_query_parameters() will modify the source buffer
MACRUM 0:119624335925 286 bool msg_sent = false;
MACRUM 0:119624335925 287 if (_server_address) {
MACRUM 0:119624335925 288 char *address_copy = M2MBase::alloc_string_copy(_server_address);
MACRUM 0:119624335925 289 if (address_copy) {
MACRUM 0:119624335925 290 char* query = query_string(_server_address);
MACRUM 0:119624335925 291 if (query != NULL) {
MACRUM 0:119624335925 292 int param_count = query_param_count(query);
MACRUM 0:119624335925 293 if (param_count) {
MACRUM 0:119624335925 294 char* uri_query_params[MAX_QUERY_COUNT] = {};
MACRUM 0:119624335925 295 if (uri_query_parameters(query, uri_query_params,0)) {
MACRUM 0:119624335925 296
MACRUM 0:119624335925 297
MACRUM 0:119624335925 298 uri_query_parameters((char*)MCC_VERSION, uri_query_params, param_count);
MACRUM 0:119624335925 299 param_count += query_param_count((char*)MCC_VERSION);
MACRUM 0:119624335925 300
MACRUM 0:119624335925 301
MACRUM 0:119624335925 302 msg_sent = true;
MACRUM 0:119624335925 303 sn_nsdl_clear_coap_resending_queue(_nsdl_handle);
MACRUM 0:119624335925 304 _bootstrap_id = sn_nsdl_oma_bootstrap(_nsdl_handle,
MACRUM 0:119624335925 305 address,
MACRUM 0:119624335925 306 _endpoint,
MACRUM 0:119624335925 307 &bootstrap_endpoint,
MACRUM 0:119624335925 308 uri_query_params,
MACRUM 0:119624335925 309 param_count);
MACRUM 0:119624335925 310 }
MACRUM 0:119624335925 311 free(_server_address);
MACRUM 0:119624335925 312 _server_address = M2MBase::alloc_string_copy(address_copy);
MACRUM 0:119624335925 313 }
MACRUM 0:119624335925 314 }
MACRUM 0:119624335925 315 free(address_copy);
MACRUM 0:119624335925 316 }
MACRUM 0:119624335925 317 }
MACRUM 0:119624335925 318 if (!msg_sent) {
MACRUM 0:119624335925 319 sn_nsdl_clear_coap_resending_queue(_nsdl_handle);
MACRUM 0:119624335925 320 _bootstrap_id = sn_nsdl_oma_bootstrap(_nsdl_handle,
MACRUM 0:119624335925 321 address,
MACRUM 0:119624335925 322 _endpoint,
MACRUM 0:119624335925 323 &bootstrap_endpoint,
MACRUM 0:119624335925 324 NULL,
MACRUM 0:119624335925 325 0);
MACRUM 0:119624335925 326 }
MACRUM 0:119624335925 327
MACRUM 0:119624335925 328 success = _bootstrap_id != 0;
MACRUM 0:119624335925 329 tr_debug("M2MNsdlInterface::create_bootstrap_resource - _bootstrap_id %d", _bootstrap_id);
MACRUM 0:119624335925 330 }
MACRUM 0:119624335925 331 return success;
MACRUM 0:119624335925 332 #else
MACRUM 0:119624335925 333 (void)address;
MACRUM 0:119624335925 334 (void)bootstrap_endpoint_name;
MACRUM 0:119624335925 335 return false;
MACRUM 0:119624335925 336 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
MACRUM 0:119624335925 337 }
MACRUM 0:119624335925 338
MACRUM 0:119624335925 339 void M2MNsdlInterface::set_server_address(uint8_t* address,
MACRUM 0:119624335925 340 uint8_t address_length,
MACRUM 0:119624335925 341 const uint16_t port,
MACRUM 0:119624335925 342 sn_nsdl_addr_type_e address_type)
MACRUM 0:119624335925 343 {
MACRUM 0:119624335925 344 tr_debug("M2MNsdlInterface::set_server_address()");
MACRUM 0:119624335925 345 set_NSP_address(_nsdl_handle, address, address_length, port, address_type);
MACRUM 0:119624335925 346 }
MACRUM 0:119624335925 347
MACRUM 0:119624335925 348 bool M2MNsdlInterface::send_register_message()
MACRUM 0:119624335925 349 {
MACRUM 0:119624335925 350 tr_info("M2MNsdlInterface::send_register_message()");
MACRUM 0:119624335925 351 handle_pending_notifications(true);
MACRUM 0:119624335925 352
MACRUM 0:119624335925 353 bool success = false;
MACRUM 0:119624335925 354 if (_server_address) {
MACRUM 0:119624335925 355 success = parse_and_send_uri_query_parameters();
MACRUM 0:119624335925 356 }
MACRUM 0:119624335925 357 // If URI parsing fails or there is no parameters, try again without parameters
MACRUM 0:119624335925 358 if (!success) {
MACRUM 0:119624335925 359 sn_nsdl_clear_coap_resending_queue(_nsdl_handle);
MACRUM 0:119624335925 360 success = sn_nsdl_register_endpoint(_nsdl_handle,_endpoint, NULL, 0) != 0;
MACRUM 0:119624335925 361 }
MACRUM 0:119624335925 362 return success;
MACRUM 0:119624335925 363 }
MACRUM 0:119624335925 364
MACRUM 0:119624335925 365 bool M2MNsdlInterface::send_get_data_request(const char *uri,
MACRUM 0:119624335925 366 const size_t offset,
MACRUM 0:119624335925 367 const bool async,
MACRUM 0:119624335925 368 get_data_cb data_cb,
MACRUM 0:119624335925 369 get_data_error_cb error_cb,
MACRUM 0:119624335925 370 void *context)
MACRUM 0:119624335925 371 {
MACRUM 0:119624335925 372 int32_t message_id = 0;
MACRUM 0:119624335925 373 uint32_t token = 0;
MACRUM 0:119624335925 374 get_data_request_s *data_request = (get_data_request_s*)memory_alloc(sizeof(get_data_request_s));
MACRUM 0:119624335925 375 if (data_request == NULL) {
MACRUM 0:119624335925 376 return false;
MACRUM 0:119624335925 377 }
MACRUM 0:119624335925 378 data_request->context = context;
MACRUM 0:119624335925 379 data_request->async_req = async;
MACRUM 0:119624335925 380 data_request->received_size = offset;
MACRUM 0:119624335925 381 data_request->uri_path = (char*)alloc_string_copy((uint8_t*)uri, strlen(uri));
MACRUM 0:119624335925 382 if (data_request->uri_path == NULL) {
MACRUM 0:119624335925 383 memory_free(data_request);
MACRUM 0:119624335925 384 return false;
MACRUM 0:119624335925 385 }
MACRUM 0:119624335925 386
MACRUM 0:119624335925 387 data_request->on_get_data_cb = data_cb;
MACRUM 0:119624335925 388 data_request->on_get_data_error_cb = error_cb;
MACRUM 0:119624335925 389
MACRUM 0:119624335925 390 randLIB_get_n_bytes_random(&token, sizeof(token));
MACRUM 0:119624335925 391
MACRUM 0:119624335925 392 if (!token) {
MACRUM 0:119624335925 393 token++;
MACRUM 0:119624335925 394 }
MACRUM 0:119624335925 395
MACRUM 0:119624335925 396 data_request->msg_token = token;
MACRUM 0:119624335925 397
MACRUM 0:119624335925 398 message_id = sn_nsdl_send_get_data_request(_nsdl_handle, uri, token, offset);
MACRUM 0:119624335925 399 if (message_id == 0) {
MACRUM 0:119624335925 400 memory_free(data_request->uri_path);
MACRUM 0:119624335925 401 memory_free(data_request);
MACRUM 0:119624335925 402 return false;
MACRUM 0:119624335925 403 }
MACRUM 0:119624335925 404
MACRUM 0:119624335925 405 ns_list_add_to_end(&_get_request_list, data_request);
MACRUM 0:119624335925 406
MACRUM 0:119624335925 407 return true;
MACRUM 0:119624335925 408 }
MACRUM 0:119624335925 409
MACRUM 0:119624335925 410 bool M2MNsdlInterface::send_update_registration(const uint32_t lifetime, bool clear_queue)
MACRUM 0:119624335925 411 {
MACRUM 0:119624335925 412 tr_info("M2MNsdlInterface::send_update_registration( lifetime %" PRIu32 ")", lifetime);
MACRUM 0:119624335925 413 bool success = false;
MACRUM 0:119624335925 414 int32_t ret = 0;
MACRUM 0:119624335925 415 create_nsdl_list_structure(_object_list);
MACRUM 0:119624335925 416
MACRUM 0:119624335925 417 _registration_timer.stop_timer();
MACRUM 0:119624335925 418 bool lifetime_changed = true;
MACRUM 0:119624335925 419
MACRUM 0:119624335925 420 // Check if resource(1/0/1) value has been updated and update it into _endpoint struct
MACRUM 0:119624335925 421 if (lifetime == 0) {
MACRUM 0:119624335925 422 lifetime_changed = lifetime_value_changed();
MACRUM 0:119624335925 423 if (lifetime_changed) {
MACRUM 0:119624335925 424 set_endpoint_lifetime_buffer(_server->resource_value_int(M2MServer::Lifetime));
MACRUM 0:119624335925 425 }
MACRUM 0:119624335925 426 } else {
MACRUM 0:119624335925 427 set_endpoint_lifetime_buffer(lifetime);
MACRUM 0:119624335925 428 }
MACRUM 0:119624335925 429
MACRUM 0:119624335925 430 if(_nsdl_handle) {
MACRUM 0:119624335925 431 if(clear_queue) {
MACRUM 0:119624335925 432 sn_nsdl_clear_coap_resending_queue(_nsdl_handle);
MACRUM 0:119624335925 433 }
MACRUM 0:119624335925 434 if (!lifetime_changed) {
MACRUM 0:119624335925 435 tr_debug("M2MNsdlInterface::send_update_registration - regular update");
MACRUM 0:119624335925 436 ret = sn_nsdl_update_registration(_nsdl_handle, NULL, 0);
MACRUM 0:119624335925 437 } else {
MACRUM 0:119624335925 438 if (_endpoint && _endpoint->lifetime_ptr) {
MACRUM 0:119624335925 439 tr_debug("M2MNsdlInterface::send_update_registration - new lifetime value");
MACRUM 0:119624335925 440 ret = sn_nsdl_update_registration(_nsdl_handle,
MACRUM 0:119624335925 441 _endpoint->lifetime_ptr,
MACRUM 0:119624335925 442 _endpoint->lifetime_len);
MACRUM 0:119624335925 443 }
MACRUM 0:119624335925 444 }
MACRUM 0:119624335925 445 if (ret == -4) {
MACRUM 0:119624335925 446 tr_warn("Failed to send registration update. Clearing queue and retrying.");
MACRUM 0:119624335925 447 sn_nsdl_clear_coap_resending_queue(_nsdl_handle);
MACRUM 0:119624335925 448 if (!lifetime_changed) {
MACRUM 0:119624335925 449 tr_debug("M2MNsdlInterface::send_update_registration - regular update - retry");
MACRUM 0:119624335925 450 ret = sn_nsdl_update_registration(_nsdl_handle, NULL, 0);
MACRUM 0:119624335925 451 } else {
MACRUM 0:119624335925 452 tr_debug("M2MNsdlInterface::send_update_registration - new lifetime value - retry");
MACRUM 0:119624335925 453 ret = sn_nsdl_update_registration(_nsdl_handle,
MACRUM 0:119624335925 454 _endpoint->lifetime_ptr,
MACRUM 0:119624335925 455 _endpoint->lifetime_len);
MACRUM 0:119624335925 456 }
MACRUM 0:119624335925 457 }
MACRUM 0:119624335925 458 }
MACRUM 0:119624335925 459 if (ret >= 0) {
MACRUM 0:119624335925 460 success = true;
MACRUM 0:119624335925 461 }
MACRUM 0:119624335925 462
MACRUM 0:119624335925 463 _registration_timer.start_timer(registration_time() * 1000,
MACRUM 0:119624335925 464 M2MTimerObserver::Registration,
MACRUM 0:119624335925 465 false);
MACRUM 0:119624335925 466
MACRUM 0:119624335925 467 return success;
MACRUM 0:119624335925 468 }
MACRUM 0:119624335925 469
MACRUM 0:119624335925 470 bool M2MNsdlInterface::send_unregister_message()
MACRUM 0:119624335925 471 {
MACRUM 0:119624335925 472 tr_info("M2MNsdlInterface::send_unregister_message");
MACRUM 0:119624335925 473 if (_unregister_ongoing) {
MACRUM 0:119624335925 474 tr_debug("M2MNsdlInterface::send_unregister_message - unregistration already in progress");
MACRUM 0:119624335925 475 return true;
MACRUM 0:119624335925 476 }
MACRUM 0:119624335925 477
MACRUM 0:119624335925 478 bool success = false;
MACRUM 0:119624335925 479 int32_t ret = 0;
MACRUM 0:119624335925 480
MACRUM 0:119624335925 481 _unregister_ongoing = true;
MACRUM 0:119624335925 482 ret = sn_nsdl_unregister_endpoint(_nsdl_handle);
MACRUM 0:119624335925 483 if (ret == -4) {
MACRUM 0:119624335925 484 tr_warn("Failed to send registration update. Clearing queue and retrying.");
MACRUM 0:119624335925 485 sn_nsdl_clear_coap_resending_queue(_nsdl_handle);
MACRUM 0:119624335925 486 ret = sn_nsdl_unregister_endpoint(_nsdl_handle);
MACRUM 0:119624335925 487 }
MACRUM 0:119624335925 488 if (ret >= 0) {
MACRUM 0:119624335925 489 success = true;
MACRUM 0:119624335925 490 }
MACRUM 0:119624335925 491 return success;
MACRUM 0:119624335925 492 }
MACRUM 0:119624335925 493
MACRUM 0:119624335925 494 // XXX: move these to common place, no need to copy these wrappers to multiple places:
MACRUM 0:119624335925 495 void *M2MNsdlInterface::memory_alloc(uint32_t size)
MACRUM 0:119624335925 496 {
MACRUM 0:119624335925 497 if(size)
MACRUM 0:119624335925 498 return malloc(size);
MACRUM 0:119624335925 499 else
MACRUM 0:119624335925 500 return 0;
MACRUM 0:119624335925 501 }
MACRUM 0:119624335925 502
MACRUM 0:119624335925 503 void M2MNsdlInterface::memory_free(void *ptr)
MACRUM 0:119624335925 504 {
MACRUM 0:119624335925 505 if(ptr)
MACRUM 0:119624335925 506 free(ptr);
MACRUM 0:119624335925 507 }
MACRUM 0:119624335925 508
MACRUM 0:119624335925 509 uint8_t* M2MNsdlInterface::alloc_string_copy(const uint8_t* source, uint16_t size)
MACRUM 0:119624335925 510 {
MACRUM 0:119624335925 511 assert(source != NULL);
MACRUM 0:119624335925 512
MACRUM 0:119624335925 513 uint8_t* result = (uint8_t*)memory_alloc(size + 1);
MACRUM 0:119624335925 514 if (result) {
MACRUM 0:119624335925 515 memcpy(result, source, size);
MACRUM 0:119624335925 516 result[size] = '\0';
MACRUM 0:119624335925 517 }
MACRUM 0:119624335925 518 return result;
MACRUM 0:119624335925 519 }
MACRUM 0:119624335925 520
MACRUM 0:119624335925 521 uint8_t M2MNsdlInterface::send_to_server_callback(struct nsdl_s * /*nsdl_handle*/,
MACRUM 0:119624335925 522 sn_nsdl_capab_e /*protocol*/,
MACRUM 0:119624335925 523 uint8_t *data_ptr,
MACRUM 0:119624335925 524 uint16_t data_len,
MACRUM 0:119624335925 525 sn_nsdl_addr_s *address)
MACRUM 0:119624335925 526 {
MACRUM 0:119624335925 527 tr_debug("M2MNsdlInterface::send_to_server_callback(data size %d)", data_len);
MACRUM 0:119624335925 528 _observer.coap_message_ready(data_ptr,data_len,address);
MACRUM 0:119624335925 529 return 1;
MACRUM 0:119624335925 530 }
MACRUM 0:119624335925 531
MACRUM 0:119624335925 532 uint8_t M2MNsdlInterface::received_from_server_callback(struct nsdl_s *nsdl_handle,
MACRUM 0:119624335925 533 sn_coap_hdr_s *coap_header,
MACRUM 0:119624335925 534 sn_nsdl_addr_s *address)
MACRUM 0:119624335925 535 {
MACRUM 0:119624335925 536 tr_debug("M2MNsdlInterface::received_from_server_callback");
MACRUM 0:119624335925 537 _observer.coap_data_processed();
MACRUM 0:119624335925 538 uint8_t value = 0;
MACRUM 0:119624335925 539 get_data_request_s get_data_req;
MACRUM 0:119624335925 540 if(nsdl_handle && coap_header) {
MACRUM 0:119624335925 541 bool is_bootstrap_msg = address && (nsdl_handle->oma_bs_address_len == address->addr_len) &&
MACRUM 0:119624335925 542 (nsdl_handle->oma_bs_port == address->port) &&
MACRUM 0:119624335925 543 !memcmp(nsdl_handle->oma_bs_address_ptr, address->addr_ptr, nsdl_handle->oma_bs_address_len);
MACRUM 0:119624335925 544
MACRUM 0:119624335925 545 if(coap_header->msg_id == nsdl_handle->register_msg_id) {
MACRUM 0:119624335925 546 if(coap_header->msg_code == COAP_MSG_CODE_RESPONSE_CREATED) {
MACRUM 0:119624335925 547 tr_info("M2MNsdlInterface::received_from_server_callback - registered");
MACRUM 0:119624335925 548 // If lifetime is less than zero then leave the field empty
MACRUM 0:119624335925 549 if(coap_header->options_list_ptr) {
MACRUM 0:119624335925 550 uint32_t max_time = coap_header->options_list_ptr->max_age;
MACRUM 0:119624335925 551
MACRUM 0:119624335925 552 // If a sufficiently-large Max-Age option is present, we interpret it as registration lifetime;
MACRUM 0:119624335925 553 // mbed server (mDS) reports lifetime this way as a non-standard extension. Other servers
MACRUM 0:119624335925 554 // would likely not include an explicit Max-Age option, in which case we'd see the default 60 seconds.
MACRUM 0:119624335925 555 if( max_time >= MINIMUM_REGISTRATION_TIME) {
MACRUM 0:119624335925 556 set_endpoint_lifetime_buffer(max_time);
MACRUM 0:119624335925 557 }
MACRUM 0:119624335925 558 if(coap_header->options_list_ptr->location_path_ptr) {
MACRUM 0:119624335925 559 sn_nsdl_set_endpoint_location(_nsdl_handle,
MACRUM 0:119624335925 560 coap_header->options_list_ptr->location_path_ptr,
MACRUM 0:119624335925 561 coap_header->options_list_ptr->location_path_len);
MACRUM 0:119624335925 562 }
MACRUM 0:119624335925 563
MACRUM 0:119624335925 564 }
MACRUM 0:119624335925 565 if (_endpoint->lifetime_ptr) {
MACRUM 0:119624335925 566 _registration_timer.stop_timer();
MACRUM 0:119624335925 567 _registration_timer.start_timer(registration_time() * 1000,
MACRUM 0:119624335925 568 M2MTimerObserver::Registration,
MACRUM 0:119624335925 569 false);
MACRUM 0:119624335925 570 }
MACRUM 0:119624335925 571 _observer.client_registered(_server);
MACRUM 0:119624335925 572 } else {
MACRUM 0:119624335925 573 tr_error("M2MNsdlInterface::received_from_server_callback - registration error %d", coap_header->msg_code);
MACRUM 0:119624335925 574 if(coap_header->coap_status == COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED) {
MACRUM 0:119624335925 575 tr_error("M2MNsdlInterface::received_from_server_callback - message sending failed !!!!");
MACRUM 0:119624335925 576 }
MACRUM 0:119624335925 577 // Try to do clean register again
MACRUM 0:119624335925 578 if(COAP_MSG_CODE_RESPONSE_BAD_REQUEST == coap_header->msg_code ||
MACRUM 0:119624335925 579 COAP_MSG_CODE_RESPONSE_FORBIDDEN == coap_header->msg_code) {
MACRUM 0:119624335925 580 _observer.registration_error(M2MInterface::InvalidParameters, false);
MACRUM 0:119624335925 581 } else {
MACRUM 0:119624335925 582 _observer.registration_error(M2MInterface::NetworkError, true);
MACRUM 0:119624335925 583 }
MACRUM 0:119624335925 584
MACRUM 0:119624335925 585 }
MACRUM 0:119624335925 586 } else if(coap_header->msg_id == nsdl_handle->unregister_msg_id) {
MACRUM 0:119624335925 587 _unregister_ongoing = false;
MACRUM 0:119624335925 588 tr_info("M2MNsdlInterface::received_from_server_callback - unregistered");
MACRUM 0:119624335925 589 if(coap_header->msg_code == COAP_MSG_CODE_RESPONSE_DELETED) {
MACRUM 0:119624335925 590 _registration_timer.stop_timer();
MACRUM 0:119624335925 591 _observer.client_unregistered();
MACRUM 0:119624335925 592 } else {
MACRUM 0:119624335925 593 tr_error("M2MNsdlInterface::received_from_server_callback - unregistration error %d", coap_header->msg_code);
MACRUM 0:119624335925 594 M2MInterface::Error error = M2MInterface::UnregistrationFailed;
MACRUM 0:119624335925 595 if (coap_header->msg_code == COAP_MSG_CODE_RESPONSE_NOT_FOUND) {
MACRUM 0:119624335925 596 _observer.registration_error(error, false);
MACRUM 0:119624335925 597 } else {
MACRUM 0:119624335925 598 _observer.registration_error(error, true);
MACRUM 0:119624335925 599 }
MACRUM 0:119624335925 600 }
MACRUM 0:119624335925 601 } else if(coap_header->msg_id == nsdl_handle->update_register_msg_id) {
MACRUM 0:119624335925 602 if(coap_header->msg_code == COAP_MSG_CODE_RESPONSE_CHANGED) {
MACRUM 0:119624335925 603 tr_info("M2MNsdlInterface::received_from_server_callback - registration_updated");
MACRUM 0:119624335925 604 _observer.registration_updated(*_server);
MACRUM 0:119624335925 605 handle_pending_notifications(false);
MACRUM 0:119624335925 606 } else {
MACRUM 0:119624335925 607 tr_error("M2MNsdlInterface::received_from_server_callback - registration_updated failed %d, %d", coap_header->msg_code, coap_header->coap_status);
MACRUM 0:119624335925 608
MACRUM 0:119624335925 609 _registration_timer.stop_timer();
MACRUM 0:119624335925 610 if ((_binding_mode == M2MInterface::UDP ||
MACRUM 0:119624335925 611 _binding_mode == M2MInterface::UDP_QUEUE ||
MACRUM 0:119624335925 612 _binding_mode == M2MInterface::UDP_SMS_QUEUE) &&
MACRUM 0:119624335925 613 coap_header->msg_code != COAP_MSG_CODE_RESPONSE_NOT_FOUND) {
MACRUM 0:119624335925 614 _observer.registration_error(M2MInterface::NetworkError, true);
MACRUM 0:119624335925 615 } else {
MACRUM 0:119624335925 616 bool msg_sent = false;
MACRUM 0:119624335925 617 if (_server_address) {
MACRUM 0:119624335925 618 msg_sent = parse_and_send_uri_query_parameters();
MACRUM 0:119624335925 619 }
MACRUM 0:119624335925 620 if (!msg_sent) {
MACRUM 0:119624335925 621 sn_nsdl_clear_coap_resending_queue(_nsdl_handle);
MACRUM 0:119624335925 622 sn_nsdl_register_endpoint(_nsdl_handle,_endpoint, NULL, 0);
MACRUM 0:119624335925 623 }
MACRUM 0:119624335925 624 }
MACRUM 0:119624335925 625 }
MACRUM 0:119624335925 626 }
MACRUM 0:119624335925 627 // Response for GET request
MACRUM 0:119624335925 628 else if (coap_header->token_ptr && is_response_to_get_req(coap_header, get_data_req)) {
MACRUM 0:119624335925 629 tr_info("M2MNsdlInterface::received_from_server_callback - GET response");
MACRUM 0:119624335925 630 size_t total_size = 0;
MACRUM 0:119624335925 631
MACRUM 0:119624335925 632 if (coap_header->options_list_ptr) {
MACRUM 0:119624335925 633 if (coap_header->options_list_ptr->use_size2) {
MACRUM 0:119624335925 634 total_size = coap_header->options_list_ptr->size2;
MACRUM 0:119624335925 635 }
MACRUM 0:119624335925 636 } else {
MACRUM 0:119624335925 637 total_size = coap_header->payload_len;
MACRUM 0:119624335925 638 }
MACRUM 0:119624335925 639
MACRUM 0:119624335925 640 if (coap_header->msg_code == COAP_MSG_CODE_RESPONSE_CONTENT) {
MACRUM 0:119624335925 641 get_data_req.received_size += coap_header->payload_len;
MACRUM 0:119624335925 642 get_data_req.on_get_data_cb(coap_header->payload_ptr,
MACRUM 0:119624335925 643 coap_header->payload_len,
MACRUM 0:119624335925 644 total_size,
MACRUM 0:119624335925 645 get_data_req.context);
MACRUM 0:119624335925 646
MACRUM 0:119624335925 647 // In sync mode, call next GET automatically until all blocks have been received
MACRUM 0:119624335925 648 if (!get_data_req.async_req) {
MACRUM 0:119624335925 649 if (coap_header->options_list_ptr && coap_header->options_list_ptr->block2 & 0x08) {
MACRUM 0:119624335925 650 send_get_data_request(get_data_req.uri_path,
MACRUM 0:119624335925 651 get_data_req.received_size,
MACRUM 0:119624335925 652 get_data_req.async_req,
MACRUM 0:119624335925 653 get_data_req.on_get_data_cb,
MACRUM 0:119624335925 654 get_data_req.on_get_data_error_cb,
MACRUM 0:119624335925 655 get_data_req.context);
MACRUM 0:119624335925 656 } else {
MACRUM 0:119624335925 657 tr_info("M2MNsdlInterface::received_from_server_callback - GET response, all blocks received");
MACRUM 0:119624335925 658 }
MACRUM 0:119624335925 659 }
MACRUM 0:119624335925 660 } else {
MACRUM 0:119624335925 661 // TODO! Convert coap error code
MACRUM 0:119624335925 662 get_data_req_error_e error = FAILED_TO_SEND_MSG;
MACRUM 0:119624335925 663 get_data_req.on_get_data_error_cb(error, get_data_req.context);
MACRUM 0:119624335925 664 }
MACRUM 0:119624335925 665
MACRUM 0:119624335925 666 free_get_request_list(coap_header);
MACRUM 0:119624335925 667 }
MACRUM 0:119624335925 668 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
MACRUM 0:119624335925 669 else if(coap_header->msg_id == nsdl_handle->bootstrap_msg_id) {
MACRUM 0:119624335925 670 tr_info("M2MNsdlInterface::received_from_server_callback - bootstrap message");
MACRUM 0:119624335925 671 _bootstrap_id = 0;
MACRUM 0:119624335925 672 M2MInterface::Error error = interface_error(*coap_header);
MACRUM 0:119624335925 673 if(error != M2MInterface::ErrorNone) {
MACRUM 0:119624335925 674 char buffer[MAX_ALLOWED_ERROR_STRING_LENGTH];
MACRUM 0:119624335925 675 memset(buffer,0,MAX_ALLOWED_ERROR_STRING_LENGTH);
MACRUM 0:119624335925 676
MACRUM 0:119624335925 677 const char* error= coap_error(*coap_header);
MACRUM 0:119624335925 678 memcpy(buffer,error,strlen(error));
MACRUM 0:119624335925 679 if(coap_header->payload_ptr) {
MACRUM 0:119624335925 680 strncat(buffer,":",1);
MACRUM 0:119624335925 681 strncat(buffer,(char*)coap_header->payload_ptr,coap_header->payload_len);
MACRUM 0:119624335925 682 }
MACRUM 0:119624335925 683
MACRUM 0:119624335925 684 handle_bootstrap_error(buffer, false);
MACRUM 0:119624335925 685 } else {
MACRUM 0:119624335925 686 _identity_accepted = true;
MACRUM 0:119624335925 687 }
MACRUM 0:119624335925 688 }
MACRUM 0:119624335925 689 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
MACRUM 0:119624335925 690 else {
MACRUM 0:119624335925 691
MACRUM 0:119624335925 692 sn_coap_hdr_s *coap_response = NULL;
MACRUM 0:119624335925 693 bool execute_value_updated = false;
MACRUM 0:119624335925 694 M2MObjectInstance *obj_instance = NULL;
MACRUM 0:119624335925 695 String resource_name;
MACRUM 0:119624335925 696
MACRUM 0:119624335925 697 if(COAP_MSG_CODE_REQUEST_PUT == coap_header->msg_code) {
MACRUM 0:119624335925 698 if (is_bootstrap_msg) {
MACRUM 0:119624335925 699 handle_bootstrap_put_message(coap_header, address);
MACRUM 0:119624335925 700 }
MACRUM 0:119624335925 701 else{
MACRUM 0:119624335925 702 tr_debug("M2MNsdlInterface::received_from_server_callback - Method not allowed (PUT).");
MACRUM 0:119624335925 703 coap_response = sn_nsdl_build_response(_nsdl_handle,
MACRUM 0:119624335925 704 coap_header,
MACRUM 0:119624335925 705 COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED);
MACRUM 0:119624335925 706 }
MACRUM 0:119624335925 707 }
MACRUM 0:119624335925 708 else if(COAP_MSG_CODE_REQUEST_DELETE == coap_header->msg_code) {
MACRUM 0:119624335925 709 if (is_bootstrap_msg) {
MACRUM 0:119624335925 710 handle_bootstrap_delete(coap_header, address);
MACRUM 0:119624335925 711 }
MACRUM 0:119624335925 712 else{
MACRUM 0:119624335925 713 tr_debug("M2MNsdlInterface::received_from_server_callback - Method not allowed (DELETE).");
MACRUM 0:119624335925 714 coap_response = sn_nsdl_build_response(_nsdl_handle,
MACRUM 0:119624335925 715 coap_header,
MACRUM 0:119624335925 716 COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED);
MACRUM 0:119624335925 717 }
MACRUM 0:119624335925 718 }
MACRUM 0:119624335925 719 else if(COAP_MSG_CODE_REQUEST_POST == coap_header->msg_code) {
MACRUM 0:119624335925 720 if(is_bootstrap_msg) {
MACRUM 0:119624335925 721 handle_bootstrap_finished(coap_header, address);
MACRUM 0:119624335925 722 }
MACRUM 0:119624335925 723 else if(coap_header->uri_path_ptr) {
MACRUM 0:119624335925 724
MACRUM 0:119624335925 725 resource_name = coap_to_string(coap_header->uri_path_ptr,
MACRUM 0:119624335925 726 coap_header->uri_path_len);
MACRUM 0:119624335925 727
MACRUM 0:119624335925 728 String object_name;
MACRUM 0:119624335925 729 int slash_found = resource_name.find_last_of('/');
MACRUM 0:119624335925 730 //The POST operation here is only allowed for non-existing object instances
MACRUM 0:119624335925 731 if(slash_found != -1) {
MACRUM 0:119624335925 732 object_name = resource_name.substr(0,slash_found);
MACRUM 0:119624335925 733 if( object_name.find_last_of('/') != -1){
MACRUM 0:119624335925 734 coap_response = sn_nsdl_build_response(_nsdl_handle,
MACRUM 0:119624335925 735 coap_header,
MACRUM 0:119624335925 736 COAP_MSG_CODE_RESPONSE_NOT_FOUND);
MACRUM 0:119624335925 737 } else {
MACRUM 0:119624335925 738 int32_t instance_id = atoi(resource_name.substr(slash_found+1,
MACRUM 0:119624335925 739 resource_name.size()-object_name.size()).c_str());
MACRUM 0:119624335925 740 M2MBase* base = find_resource(object_name, 0);
MACRUM 0:119624335925 741 if(base) {
MACRUM 0:119624335925 742 if((instance_id >= 0) && (instance_id < UINT16_MAX)) {
MACRUM 0:119624335925 743 if(coap_header->payload_ptr) {
MACRUM 0:119624335925 744 M2MObject* object = static_cast<M2MObject*> (base);
MACRUM 0:119624335925 745 obj_instance = object->create_object_instance(instance_id);
MACRUM 0:119624335925 746 if(obj_instance) {
MACRUM 0:119624335925 747 obj_instance->set_operation(M2MBase::GET_PUT_POST_ALLOWED);
MACRUM 0:119624335925 748 coap_response = obj_instance->handle_post_request(_nsdl_handle,
MACRUM 0:119624335925 749 coap_header,
MACRUM 0:119624335925 750 this,
MACRUM 0:119624335925 751 execute_value_updated);
MACRUM 0:119624335925 752 }
MACRUM 0:119624335925 753 if(coap_response && coap_response->msg_code != COAP_MSG_CODE_RESPONSE_CREATED) {
MACRUM 0:119624335925 754 //Invalid request so remove created ObjectInstance
MACRUM 0:119624335925 755 object->remove_object_instance(instance_id);
MACRUM 0:119624335925 756 } else {
MACRUM 0:119624335925 757 tr_debug("M2MNsdlInterface::received_from_server_callback - Send Update registration for Create");
MACRUM 0:119624335925 758 if (lifetime_value_changed()) {
MACRUM 0:119624335925 759 send_update_registration(_server->resource_value_int(M2MServer::Lifetime));
MACRUM 0:119624335925 760 } else {
MACRUM 0:119624335925 761 send_update_registration();
MACRUM 0:119624335925 762 }
MACRUM 0:119624335925 763 }
MACRUM 0:119624335925 764 } else {
MACRUM 0:119624335925 765 tr_error("M2MNsdlInterface::received_from_server_callback - Missing Payload - Cannot create");
MACRUM 0:119624335925 766 coap_response = sn_nsdl_build_response(_nsdl_handle,
MACRUM 0:119624335925 767 coap_header,
MACRUM 0:119624335925 768 COAP_MSG_CODE_RESPONSE_BAD_REQUEST);
MACRUM 0:119624335925 769 }
MACRUM 0:119624335925 770 } else { // instance id out of range
MACRUM 0:119624335925 771 tr_error("M2MNsdlInterface::received_from_server_callback - instance id out of range - Cannot create");
MACRUM 0:119624335925 772 coap_response = sn_nsdl_build_response(_nsdl_handle,
MACRUM 0:119624335925 773 coap_header,
MACRUM 0:119624335925 774 COAP_MSG_CODE_RESPONSE_BAD_REQUEST);
MACRUM 0:119624335925 775 }
MACRUM 0:119624335925 776 } else { // if(base)
MACRUM 0:119624335925 777 tr_error("M2MNsdlInterface::received_from_server_callback - Missing BASE - Cannot create");
MACRUM 0:119624335925 778 coap_response = sn_nsdl_build_response(_nsdl_handle,
MACRUM 0:119624335925 779 coap_header,
MACRUM 0:119624335925 780 COAP_MSG_CODE_RESPONSE_NOT_FOUND);
MACRUM 0:119624335925 781 }
MACRUM 0:119624335925 782 }
MACRUM 0:119624335925 783 } else{ // if(slash_found != -1)
MACRUM 0:119624335925 784 tr_error("M2MNsdlInterface::received_from_server_callback - slash_found - Cannot create");
MACRUM 0:119624335925 785 coap_response = sn_nsdl_build_response(_nsdl_handle,
MACRUM 0:119624335925 786 coap_header,
MACRUM 0:119624335925 787 COAP_MSG_CODE_RESPONSE_NOT_FOUND);
MACRUM 0:119624335925 788 }
MACRUM 0:119624335925 789
MACRUM 0:119624335925 790 }
MACRUM 0:119624335925 791 }
MACRUM 0:119624335925 792 else if(COAP_MSG_CODE_EMPTY == coap_header->msg_code) {
MACRUM 0:119624335925 793 // Cancel ongoing observation
MACRUM 0:119624335925 794 if (COAP_MSG_TYPE_RESET == coap_header->msg_type) {
MACRUM 0:119624335925 795 M2MBase *base = find_resource("", coap_header->msg_id);
MACRUM 0:119624335925 796 if (base) {
MACRUM 0:119624335925 797 M2MBase::BaseType type = base->base_type();
MACRUM 0:119624335925 798 switch (type) {
MACRUM 0:119624335925 799 case M2MBase::Object:
MACRUM 0:119624335925 800 base->remove_observation_level(M2MBase::O_Attribute);
MACRUM 0:119624335925 801 break;
MACRUM 0:119624335925 802 case M2MBase::Resource:
MACRUM 0:119624335925 803 base->remove_observation_level(M2MBase::R_Attribute);
MACRUM 0:119624335925 804 break;
MACRUM 0:119624335925 805 case M2MBase::ObjectInstance:
MACRUM 0:119624335925 806 base->remove_observation_level(M2MBase::OI_Attribute);
MACRUM 0:119624335925 807 break;
MACRUM 0:119624335925 808 default:
MACRUM 0:119624335925 809 break;
MACRUM 0:119624335925 810 }
MACRUM 0:119624335925 811 base->set_under_observation(false, this);
MACRUM 0:119624335925 812 base->send_notification_delivery_status(*base, NOTIFICATION_STATUS_UNSUBSCRIBED);
MACRUM 0:119624335925 813 }
MACRUM 0:119624335925 814 // Notification delivered
MACRUM 0:119624335925 815 } else {
MACRUM 0:119624335925 816 M2MBase *base = find_resource("", coap_header->msg_id);
MACRUM 0:119624335925 817 if (base) {
MACRUM 0:119624335925 818 base->send_notification_delivery_status(*base,
MACRUM 0:119624335925 819 NOTIFICATION_STATUS_DELIVERED);
MACRUM 0:119624335925 820 // Supported only in Resource level
MACRUM 0:119624335925 821 // TODO! remove below code once old API is removed
MACRUM 0:119624335925 822 if (M2MBase::Resource == base->base_type()) {
MACRUM 0:119624335925 823 M2MResource *resource = static_cast<M2MResource *> (base);
MACRUM 0:119624335925 824 resource->notification_sent();
MACRUM 0:119624335925 825 }
MACRUM 0:119624335925 826 }
MACRUM 0:119624335925 827 }
MACRUM 0:119624335925 828 // Retransmission done
MACRUM 0:119624335925 829 } else if (COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED == coap_header->coap_status) {
MACRUM 0:119624335925 830 tr_info("M2MNsdlInterface::received_from_server_callback - message sending failed, id %d", coap_header->msg_id);
MACRUM 0:119624335925 831
MACRUM 0:119624335925 832 // Report notification status back to application
MACRUM 0:119624335925 833 M2MBase *base = find_resource("", coap_header->msg_id);
MACRUM 0:119624335925 834 if (base) {
MACRUM 0:119624335925 835 base->send_notification_delivery_status(*base, NOTIFICATION_STATUS_SEND_FAILED);
MACRUM 0:119624335925 836 }
MACRUM 0:119624335925 837 // Handle Server-side expections during registration flow
MACRUM 0:119624335925 838 // Client might receive error from server due to temporary connection/operability reasons,
MACRUM 0:119624335925 839 // server might not recover the flow in this case, so it is better for Client to restart registration.
MACRUM 0:119624335925 840 } else if (nsdl_handle->register_msg_id &&
MACRUM 0:119624335925 841 ((coap_header->msg_code == COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR) ||
MACRUM 0:119624335925 842 (coap_header->msg_code == COAP_MSG_CODE_RESPONSE_BAD_GATEWAY) ||
MACRUM 0:119624335925 843 (coap_header->msg_code == COAP_MSG_CODE_RESPONSE_SERVICE_UNAVAILABLE) ||
MACRUM 0:119624335925 844 (coap_header->msg_code == COAP_MSG_CODE_RESPONSE_GATEWAY_TIMEOUT))) {
MACRUM 0:119624335925 845 tr_error("M2MNsdlInterface::received_from_server_callback - registration error %d", coap_header->msg_code);
MACRUM 0:119624335925 846 tr_error("M2MNsdlInterface::received_from_server_callback - unexpected error received from server");
MACRUM 0:119624335925 847 // Try to do clean register again
MACRUM 0:119624335925 848 _observer.registration_error(M2MInterface::NetworkError, true);
MACRUM 0:119624335925 849 } else {
MACRUM 0:119624335925 850 // Add warn for any message that gets this far. We might be missing some handling in above.
MACRUM 0:119624335925 851 tr_warn("M2MNsdlInterface::received_from_server_callback - msg was ignored %d", coap_header->msg_code);
MACRUM 0:119624335925 852 }
MACRUM 0:119624335925 853
MACRUM 0:119624335925 854 // Send response to server
MACRUM 0:119624335925 855 if(coap_response) {
MACRUM 0:119624335925 856 tr_debug("M2MNsdlInterface::received_from_server_callback - send CoAP response");
MACRUM 0:119624335925 857 (sn_nsdl_send_coap_message(_nsdl_handle, address, coap_response) == 0) ? value = 0 : value = 1;
MACRUM 0:119624335925 858 sn_nsdl_release_allocated_coap_msg_mem(_nsdl_handle, coap_response);
MACRUM 0:119624335925 859 }
MACRUM 0:119624335925 860
MACRUM 0:119624335925 861 // Tell to application that value has been updated
MACRUM 0:119624335925 862 if (execute_value_updated) {
MACRUM 0:119624335925 863 value_updated(obj_instance);
MACRUM 0:119624335925 864 }
MACRUM 0:119624335925 865
MACRUM 0:119624335925 866 }
MACRUM 0:119624335925 867 }
MACRUM 0:119624335925 868 return value;
MACRUM 0:119624335925 869 }
MACRUM 0:119624335925 870
MACRUM 0:119624335925 871 uint8_t M2MNsdlInterface::resource_callback(struct nsdl_s */*nsdl_handle*/,
MACRUM 0:119624335925 872 sn_coap_hdr_s *received_coap_header,
MACRUM 0:119624335925 873 sn_nsdl_addr_s *address,
MACRUM 0:119624335925 874 sn_nsdl_capab_e /*nsdl_capab*/)
MACRUM 0:119624335925 875 {
MACRUM 0:119624335925 876 tr_debug("M2MNsdlInterface::resource_callback()");
MACRUM 0:119624335925 877 _observer.coap_data_processed();
MACRUM 0:119624335925 878 uint8_t result = 1;
MACRUM 0:119624335925 879 uint8_t *payload = NULL;
MACRUM 0:119624335925 880 bool free_payload = true;
MACRUM 0:119624335925 881 sn_coap_hdr_s *coap_response = NULL;
MACRUM 0:119624335925 882 sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 4.00
MACRUM 0:119624335925 883 String resource_name = coap_to_string(received_coap_header->uri_path_ptr,
MACRUM 0:119624335925 884 received_coap_header->uri_path_len);
MACRUM 0:119624335925 885
MACRUM 0:119624335925 886 bool execute_value_updated = false;
MACRUM 0:119624335925 887 M2MBase* base = find_resource(resource_name, 0);
MACRUM 0:119624335925 888 if (base) {
MACRUM 0:119624335925 889 if (COAP_MSG_CODE_REQUEST_GET == received_coap_header->msg_code) {
MACRUM 0:119624335925 890 coap_response = base->handle_get_request(_nsdl_handle, received_coap_header,this);
MACRUM 0:119624335925 891 } else if (COAP_MSG_CODE_REQUEST_PUT == received_coap_header->msg_code) {
MACRUM 0:119624335925 892 coap_response = base->handle_put_request(_nsdl_handle, received_coap_header, this, execute_value_updated);
MACRUM 0:119624335925 893 } else if (COAP_MSG_CODE_REQUEST_POST == received_coap_header->msg_code) {
MACRUM 0:119624335925 894 if (base->base_type() == M2MBase::ResourceInstance) {
MACRUM 0:119624335925 895 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
MACRUM 0:119624335925 896 } else {
MACRUM 0:119624335925 897 coap_response = base->handle_post_request(_nsdl_handle,
MACRUM 0:119624335925 898 received_coap_header,
MACRUM 0:119624335925 899 this,
MACRUM 0:119624335925 900 execute_value_updated,
MACRUM 0:119624335925 901 address);
MACRUM 0:119624335925 902 }
MACRUM 0:119624335925 903 } else if (COAP_MSG_CODE_REQUEST_DELETE == received_coap_header->msg_code) {
MACRUM 0:119624335925 904 // Delete the object instance
MACRUM 0:119624335925 905 M2MBase::BaseType type = base->base_type();
MACRUM 0:119624335925 906 if(M2MBase::ObjectInstance == type) {
MACRUM 0:119624335925 907 M2MBase* base_object = find_resource(base->uri_path(), 0);
MACRUM 0:119624335925 908 if(base_object) {
MACRUM 0:119624335925 909 M2MObject &object = ((M2MObjectInstance*)base_object)->get_parent_object();
MACRUM 0:119624335925 910 int slash_found = resource_name.find_last_of('/');
MACRUM 0:119624335925 911 // Object instance validty checks done in upper level, no need for error handling
MACRUM 0:119624335925 912 if (slash_found != -1) {
MACRUM 0:119624335925 913 String object_name;
MACRUM 0:119624335925 914 object_name = resource_name.substr(slash_found + 1, resource_name.length());
MACRUM 0:119624335925 915 if (object.remove_object_instance(strtoul(
MACRUM 0:119624335925 916 object_name.c_str(),
MACRUM 0:119624335925 917 NULL,
MACRUM 0:119624335925 918 10))) {
MACRUM 0:119624335925 919 msg_code = COAP_MSG_CODE_RESPONSE_DELETED;
MACRUM 0:119624335925 920 }
MACRUM 0:119624335925 921 }
MACRUM 0:119624335925 922 }
MACRUM 0:119624335925 923 } else {
MACRUM 0:119624335925 924 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // 4.00
MACRUM 0:119624335925 925 }
MACRUM 0:119624335925 926 }
MACRUM 0:119624335925 927 } else {
MACRUM 0:119624335925 928 tr_error("M2MNsdlInterface::resource_callback() - Resource NOT FOUND");
MACRUM 0:119624335925 929 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // 4.00
MACRUM 0:119624335925 930 }
MACRUM 0:119624335925 931
MACRUM 0:119624335925 932 if (!coap_response) {
MACRUM 0:119624335925 933 coap_response = sn_nsdl_build_response(_nsdl_handle,
MACRUM 0:119624335925 934 received_coap_header,
MACRUM 0:119624335925 935 msg_code);
MACRUM 0:119624335925 936 }
MACRUM 0:119624335925 937
MACRUM 0:119624335925 938 // This copy will be passed to resource instance
MACRUM 0:119624335925 939 payload = (uint8_t*)memory_alloc(received_coap_header->payload_len + 1);
MACRUM 0:119624335925 940 if (payload) {
MACRUM 0:119624335925 941 memcpy(payload, received_coap_header->payload_ptr, received_coap_header->payload_len);
MACRUM 0:119624335925 942 payload[received_coap_header->payload_len] = '\0';
MACRUM 0:119624335925 943 }
MACRUM 0:119624335925 944 else {
MACRUM 0:119624335925 945 if (coap_response) {
MACRUM 0:119624335925 946 coap_response->msg_code = COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE;
MACRUM 0:119624335925 947 }
MACRUM 0:119624335925 948 }
MACRUM 0:119624335925 949
MACRUM 0:119624335925 950 if (coap_response &&
MACRUM 0:119624335925 951 coap_response->coap_status != COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING &&
MACRUM 0:119624335925 952 coap_response->msg_code != COAP_MSG_CODE_EMPTY) {
MACRUM 0:119624335925 953 (sn_nsdl_send_coap_message(_nsdl_handle, address, coap_response) == 0) ? result = 0 : result = 1;
MACRUM 0:119624335925 954 if(coap_response->payload_ptr) {
MACRUM 0:119624335925 955 free(coap_response->payload_ptr);
MACRUM 0:119624335925 956 coap_response->payload_ptr = NULL;
MACRUM 0:119624335925 957 }
MACRUM 0:119624335925 958 }
MACRUM 0:119624335925 959
MACRUM 0:119624335925 960 // If the external blockwise storing is enabled call value updated once all the blocks have been received
MACRUM 0:119624335925 961 if (execute_value_updated &&
MACRUM 0:119624335925 962 coap_response &&
MACRUM 0:119624335925 963 coap_response->coap_status != COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING &&
MACRUM 0:119624335925 964 coap_response->msg_code < COAP_MSG_CODE_RESPONSE_BAD_REQUEST) {
MACRUM 0:119624335925 965 if ((COAP_MSG_CODE_REQUEST_PUT == received_coap_header->msg_code) &&
MACRUM 0:119624335925 966 (base->base_type() == M2MBase::Resource ||
MACRUM 0:119624335925 967 base->base_type() == M2MBase::ResourceInstance)) {
MACRUM 0:119624335925 968 M2MResourceBase* res = (M2MResourceBase*)base;
MACRUM 0:119624335925 969 bool external_block_store = false;
MACRUM 0:119624335925 970
MACRUM 0:119624335925 971 if (res->block_message() && res->block_message()->is_block_message()) {
MACRUM 0:119624335925 972 external_block_store = true;
MACRUM 0:119624335925 973 }
MACRUM 0:119624335925 974 if (!external_block_store) {
MACRUM 0:119624335925 975 // Ownership of payload moved to resource, skip the freeing.
MACRUM 0:119624335925 976 free_payload = false;
MACRUM 0:119624335925 977 res->set_value_raw(payload, received_coap_header->payload_len);
MACRUM 0:119624335925 978 }
MACRUM 0:119624335925 979 }
MACRUM 0:119624335925 980
MACRUM 0:119624335925 981 if (coap_response->msg_code != COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE) {
MACRUM 0:119624335925 982 value_updated(base);
MACRUM 0:119624335925 983 }
MACRUM 0:119624335925 984 }
MACRUM 0:119624335925 985
MACRUM 0:119624335925 986 if (free_payload) {
MACRUM 0:119624335925 987 free(payload);
MACRUM 0:119624335925 988 }
MACRUM 0:119624335925 989
MACRUM 0:119624335925 990 sn_nsdl_release_allocated_coap_msg_mem(_nsdl_handle, coap_response);
MACRUM 0:119624335925 991 return result;
MACRUM 0:119624335925 992 }
MACRUM 0:119624335925 993
MACRUM 0:119624335925 994 bool M2MNsdlInterface::process_received_data(uint8_t *data,
MACRUM 0:119624335925 995 uint16_t data_size,
MACRUM 0:119624335925 996 sn_nsdl_addr_s *address)
MACRUM 0:119624335925 997 {
MACRUM 0:119624335925 998 tr_debug("M2MNsdlInterface::process_received_data(data size %d)", data_size);
MACRUM 0:119624335925 999 return (0 == sn_nsdl_process_coap(_nsdl_handle,
MACRUM 0:119624335925 1000 data,
MACRUM 0:119624335925 1001 data_size,
MACRUM 0:119624335925 1002 address)) ? true : false;
MACRUM 0:119624335925 1003 }
MACRUM 0:119624335925 1004
MACRUM 0:119624335925 1005 void M2MNsdlInterface::stop_timers()
MACRUM 0:119624335925 1006 {
MACRUM 0:119624335925 1007 tr_debug("M2MNsdlInterface::stop_timers()");
MACRUM 0:119624335925 1008 _registration_timer.stop_timer();
MACRUM 0:119624335925 1009 _nsdl_exceution_timer.stop_timer();
MACRUM 0:119624335925 1010 _nsdl_exceution_timer_running = false;
MACRUM 0:119624335925 1011 _bootstrap_id = 0;
MACRUM 0:119624335925 1012 _unregister_ongoing = false;
MACRUM 0:119624335925 1013 }
MACRUM 0:119624335925 1014
MACRUM 0:119624335925 1015 void M2MNsdlInterface::timer_expired(M2MTimerObserver::Type type)
MACRUM 0:119624335925 1016 {
MACRUM 0:119624335925 1017 if(M2MTimerObserver::NsdlExecution == type) {
MACRUM 0:119624335925 1018 sn_nsdl_exec(_nsdl_handle, _counter_for_nsdl);
MACRUM 0:119624335925 1019 _counter_for_nsdl++;
MACRUM 0:119624335925 1020 } else if((M2MTimerObserver::Registration) == type && (_unregister_ongoing==false)) {
MACRUM 0:119624335925 1021 tr_debug("M2MNsdlInterface::timer_expired - Send update registration");
MACRUM 0:119624335925 1022 if (lifetime_value_changed()) {
MACRUM 0:119624335925 1023 send_update_registration(_server->resource_value_int(M2MServer::Lifetime));
MACRUM 0:119624335925 1024 } else {
MACRUM 0:119624335925 1025 send_update_registration();
MACRUM 0:119624335925 1026 }
MACRUM 0:119624335925 1027 }
MACRUM 0:119624335925 1028 }
MACRUM 0:119624335925 1029
MACRUM 0:119624335925 1030 void M2MNsdlInterface::observation_to_be_sent(M2MBase *object,
MACRUM 0:119624335925 1031 uint16_t obs_number,
MACRUM 0:119624335925 1032 const m2m::Vector<uint16_t> &changed_instance_ids,
MACRUM 0:119624335925 1033 bool send_object)
MACRUM 0:119624335925 1034 {
MACRUM 0:119624335925 1035 claim_mutex();
MACRUM 0:119624335925 1036 if(object) {
MACRUM 0:119624335925 1037 tr_debug("M2MNsdlInterface::observation_to_be_sent()");
MACRUM 0:119624335925 1038 M2MBase::BaseType type = object->base_type();
MACRUM 0:119624335925 1039 if(type == M2MBase::Object) {
MACRUM 0:119624335925 1040 send_object_observation(static_cast<M2MObject*> (object),
MACRUM 0:119624335925 1041 obs_number,
MACRUM 0:119624335925 1042 changed_instance_ids,
MACRUM 0:119624335925 1043 send_object, false);
MACRUM 0:119624335925 1044 } else if(type == M2MBase::ObjectInstance) {
MACRUM 0:119624335925 1045 send_object_instance_observation(static_cast<M2MObjectInstance*> (object), obs_number, false);
MACRUM 0:119624335925 1046 } else if(type == M2MBase::Resource) {
MACRUM 0:119624335925 1047 send_resource_observation(static_cast<M2MResource*> (object), obs_number, false);
MACRUM 0:119624335925 1048 }
MACRUM 0:119624335925 1049 }
MACRUM 0:119624335925 1050 release_mutex();
MACRUM 0:119624335925 1051 }
MACRUM 0:119624335925 1052
MACRUM 0:119624335925 1053 #ifndef DISABLE_DELAYED_RESPONSE
MACRUM 0:119624335925 1054 void M2MNsdlInterface::send_delayed_response(M2MBase *base)
MACRUM 0:119624335925 1055 {
MACRUM 0:119624335925 1056 claim_mutex();
MACRUM 0:119624335925 1057 tr_debug("M2MNsdlInterface::send_delayed_response()");
MACRUM 0:119624335925 1058 M2MResource *resource = NULL;
MACRUM 0:119624335925 1059 if(base) {
MACRUM 0:119624335925 1060 if(M2MBase::Resource == base->base_type()) {
MACRUM 0:119624335925 1061 resource = static_cast<M2MResource *> (base);
MACRUM 0:119624335925 1062 }
MACRUM 0:119624335925 1063 if(resource) {
MACRUM 0:119624335925 1064 sn_coap_hdr_s coap_response;
MACRUM 0:119624335925 1065
MACRUM 0:119624335925 1066 memset(&coap_response,0,sizeof(sn_coap_hdr_s));
MACRUM 0:119624335925 1067
MACRUM 0:119624335925 1068 coap_response.msg_type = COAP_MSG_TYPE_CONFIRMABLE;
MACRUM 0:119624335925 1069 coap_response.msg_code = COAP_MSG_CODE_RESPONSE_CONTENT;
MACRUM 0:119624335925 1070 resource->get_delayed_token(coap_response.token_ptr,coap_response.token_len);
MACRUM 0:119624335925 1071
MACRUM 0:119624335925 1072 uint32_t length = 0;
MACRUM 0:119624335925 1073 resource->get_value(coap_response.payload_ptr, length);
MACRUM 0:119624335925 1074 coap_response.payload_len = length;
MACRUM 0:119624335925 1075
MACRUM 0:119624335925 1076 sn_nsdl_send_coap_message(_nsdl_handle, _nsdl_handle->nsp_address_ptr->omalw_address_ptr, &coap_response);
MACRUM 0:119624335925 1077
MACRUM 0:119624335925 1078 free(coap_response.payload_ptr);
MACRUM 0:119624335925 1079 free(coap_response.token_ptr);
MACRUM 0:119624335925 1080 }
MACRUM 0:119624335925 1081 }
MACRUM 0:119624335925 1082 release_mutex();
MACRUM 0:119624335925 1083 }
MACRUM 0:119624335925 1084 #endif
MACRUM 0:119624335925 1085
MACRUM 0:119624335925 1086 void M2MNsdlInterface::resource_to_be_deleted(M2MBase *base)
MACRUM 0:119624335925 1087 {
MACRUM 0:119624335925 1088 tr_debug("M2MNsdlInterface::resource_to_be_deleted()");
MACRUM 0:119624335925 1089 claim_mutex();
MACRUM 0:119624335925 1090 remove_nsdl_resource(base);
MACRUM 0:119624335925 1091
MACRUM 0:119624335925 1092 // Since the M2MObject's are stored in _object_list, they need to be removed from there also.
MACRUM 0:119624335925 1093 if (base && base->base_type() == M2MBase::Object) {
MACRUM 0:119624335925 1094 remove_object(base);
MACRUM 0:119624335925 1095 }
MACRUM 0:119624335925 1096
MACRUM 0:119624335925 1097 release_mutex();
MACRUM 0:119624335925 1098 }
MACRUM 0:119624335925 1099
MACRUM 0:119624335925 1100 void M2MNsdlInterface::value_updated(M2MBase *base)
MACRUM 0:119624335925 1101 {
MACRUM 0:119624335925 1102 tr_debug("M2MNsdlInterface::value_updated()");
MACRUM 0:119624335925 1103 String name;
MACRUM 0:119624335925 1104 if(base) {
MACRUM 0:119624335925 1105 switch(base->base_type()) {
MACRUM 0:119624335925 1106 case M2MBase::Object:
MACRUM 0:119624335925 1107 create_nsdl_object_structure(static_cast<M2MObject*> (base));
MACRUM 0:119624335925 1108 name = base->name();
MACRUM 0:119624335925 1109 break;
MACRUM 0:119624335925 1110 case M2MBase::ObjectInstance:
MACRUM 0:119624335925 1111 create_nsdl_object_instance_structure(static_cast<M2MObjectInstance*> (base));
MACRUM 0:119624335925 1112 name = static_cast<M2MObjectInstance*> (base)->get_parent_object().name();
MACRUM 0:119624335925 1113
MACRUM 0:119624335925 1114 break;
MACRUM 0:119624335925 1115 case M2MBase::Resource: {
MACRUM 0:119624335925 1116 M2MResource* resource = static_cast<M2MResource*> (base);
MACRUM 0:119624335925 1117 create_nsdl_resource_structure(resource,
MACRUM 0:119624335925 1118 resource->supports_multiple_instances());
MACRUM 0:119624335925 1119 name = base->name();
MACRUM 0:119624335925 1120 }
MACRUM 0:119624335925 1121 break;
MACRUM 0:119624335925 1122 case M2MBase::ResourceInstance: {
MACRUM 0:119624335925 1123 M2MResourceInstance* instance = static_cast<M2MResourceInstance*> (base);
MACRUM 0:119624335925 1124 create_nsdl_resource(instance);
MACRUM 0:119624335925 1125 name = static_cast<M2MResourceInstance*> (base)->get_parent_resource().name();
MACRUM 0:119624335925 1126 }
MACRUM 0:119624335925 1127 break;
MACRUM 0:119624335925 1128 }
MACRUM 0:119624335925 1129 }
MACRUM 0:119624335925 1130
MACRUM 0:119624335925 1131 if (base && base->is_value_updated_function_set()) {
MACRUM 0:119624335925 1132 base->execute_value_updated(name);
MACRUM 0:119624335925 1133 }
MACRUM 0:119624335925 1134 else {
MACRUM 0:119624335925 1135 _observer.value_updated(base);
MACRUM 0:119624335925 1136 }
MACRUM 0:119624335925 1137 }
MACRUM 0:119624335925 1138
MACRUM 0:119624335925 1139 void M2MNsdlInterface::remove_object(M2MBase *object)
MACRUM 0:119624335925 1140 {
MACRUM 0:119624335925 1141 claim_mutex();
MACRUM 0:119624335925 1142 tr_debug("M2MNsdlInterface::remove_object()");
MACRUM 0:119624335925 1143 M2MObject* rem_object = static_cast<M2MObject*> (object);
MACRUM 0:119624335925 1144 if(rem_object && !_object_list.empty()) {
MACRUM 0:119624335925 1145 M2MObjectList::const_iterator it;
MACRUM 0:119624335925 1146 it = _object_list.begin();
MACRUM 0:119624335925 1147 int index = 0;
MACRUM 0:119624335925 1148 for ( ; it != _object_list.end(); it++, index++ ) {
MACRUM 0:119624335925 1149 if((*it) == rem_object) {
MACRUM 0:119624335925 1150 _object_list.erase(index);
MACRUM 0:119624335925 1151 break;
MACRUM 0:119624335925 1152 }
MACRUM 0:119624335925 1153 }
MACRUM 0:119624335925 1154 }
MACRUM 0:119624335925 1155 if(_object_list.empty()) {
MACRUM 0:119624335925 1156 _object_list.clear();
MACRUM 0:119624335925 1157 }
MACRUM 0:119624335925 1158 release_mutex();
MACRUM 0:119624335925 1159 }
MACRUM 0:119624335925 1160
MACRUM 0:119624335925 1161 bool M2MNsdlInterface::create_nsdl_object_structure(M2MObject *object)
MACRUM 0:119624335925 1162 {
MACRUM 0:119624335925 1163 bool success = false;
MACRUM 0:119624335925 1164 if(object) {
MACRUM 0:119624335925 1165 const M2MObjectInstanceList &instance_list = object->instances();
MACRUM 0:119624335925 1166 if(!instance_list.empty()) {
MACRUM 0:119624335925 1167 M2MObjectInstanceList::const_iterator it;
MACRUM 0:119624335925 1168 it = instance_list.begin();
MACRUM 0:119624335925 1169 for ( ; it != instance_list.end(); it++ ) {
MACRUM 0:119624335925 1170 // Create NSDL structure for all object instances inside
MACRUM 0:119624335925 1171 success = create_nsdl_object_instance_structure(*it);
MACRUM 0:119624335925 1172 }
MACRUM 0:119624335925 1173 }
MACRUM 0:119624335925 1174 }
MACRUM 0:119624335925 1175 if(object && object->operation() != M2MBase::NOT_ALLOWED) {
MACRUM 0:119624335925 1176 success = create_nsdl_resource(object);
MACRUM 0:119624335925 1177 }
MACRUM 0:119624335925 1178
MACRUM 0:119624335925 1179 return success;
MACRUM 0:119624335925 1180 }
MACRUM 0:119624335925 1181
MACRUM 0:119624335925 1182 bool M2MNsdlInterface::create_nsdl_object_instance_structure(M2MObjectInstance *object_instance)
MACRUM 0:119624335925 1183 {
MACRUM 0:119624335925 1184 bool success = false;
MACRUM 0:119624335925 1185 if( object_instance) {
MACRUM 0:119624335925 1186 const M2MResourceList &res_list = object_instance->resources();
MACRUM 0:119624335925 1187 if(!res_list.empty()) {
MACRUM 0:119624335925 1188 M2MResourceList::const_iterator it;
MACRUM 0:119624335925 1189 it = res_list.begin();
MACRUM 0:119624335925 1190 for ( ; it != res_list.end(); it++ ) {
MACRUM 0:119624335925 1191 // Create NSDL structure for all resources inside
MACRUM 0:119624335925 1192 success = create_nsdl_resource_structure(*it,
MACRUM 0:119624335925 1193 (*it)->supports_multiple_instances());
MACRUM 0:119624335925 1194 }
MACRUM 0:119624335925 1195 }
MACRUM 0:119624335925 1196 if(object_instance->operation() != M2MBase::NOT_ALLOWED) {
MACRUM 0:119624335925 1197 success = create_nsdl_resource(object_instance);
MACRUM 0:119624335925 1198 }
MACRUM 0:119624335925 1199 }
MACRUM 0:119624335925 1200 return success;
MACRUM 0:119624335925 1201 }
MACRUM 0:119624335925 1202
MACRUM 0:119624335925 1203 bool M2MNsdlInterface::create_nsdl_resource_structure(M2MResource *res,
MACRUM 0:119624335925 1204 bool multiple_instances)
MACRUM 0:119624335925 1205 {
MACRUM 0:119624335925 1206 bool success = false;
MACRUM 0:119624335925 1207 if(res) {
MACRUM 0:119624335925 1208 // if there are multiple instances supported
MACRUM 0:119624335925 1209 if(multiple_instances) {
MACRUM 0:119624335925 1210 const M2MResourceInstanceList &res_list = res->resource_instances();
MACRUM 0:119624335925 1211 if(!res_list.empty()) {
MACRUM 0:119624335925 1212 M2MResourceInstanceList::const_iterator it;
MACRUM 0:119624335925 1213 it = res_list.begin();
MACRUM 0:119624335925 1214 for ( ; it != res_list.end(); it++ ) {
MACRUM 0:119624335925 1215 success = create_nsdl_resource((*it));
MACRUM 0:119624335925 1216 if(!success) {
MACRUM 0:119624335925 1217 tr_error("M2MNsdlInterface::create_nsdl_resource_structure - instance creation failed");
MACRUM 0:119624335925 1218 return false;
MACRUM 0:119624335925 1219 }
MACRUM 0:119624335925 1220 }
MACRUM 0:119624335925 1221 // Register the main Resource as well along with ResourceInstances
MACRUM 0:119624335925 1222 success = create_nsdl_resource(res);
MACRUM 0:119624335925 1223 }
MACRUM 0:119624335925 1224 } else {
MACRUM 0:119624335925 1225 success = create_nsdl_resource(res);
MACRUM 0:119624335925 1226 }
MACRUM 0:119624335925 1227 }
MACRUM 0:119624335925 1228 return success;
MACRUM 0:119624335925 1229 }
MACRUM 0:119624335925 1230
MACRUM 0:119624335925 1231 bool M2MNsdlInterface::create_nsdl_resource(M2MBase *base)
MACRUM 0:119624335925 1232 {
MACRUM 0:119624335925 1233 claim_mutex();
MACRUM 0:119624335925 1234 bool success = false;
MACRUM 0:119624335925 1235 if(base) {
MACRUM 0:119624335925 1236 int8_t result = 0;
MACRUM 0:119624335925 1237 sn_nsdl_dynamic_resource_parameters_s* nsdl_resource = base->get_nsdl_resource();
MACRUM 0:119624335925 1238
MACRUM 0:119624335925 1239 // needed on deletion
MACRUM 0:119624335925 1240 if (base->observation_handler() == NULL) {
MACRUM 0:119624335925 1241 base->set_observation_handler(this);
MACRUM 0:119624335925 1242 }
MACRUM 0:119624335925 1243
MACRUM 0:119624335925 1244 result = sn_nsdl_put_resource(_nsdl_handle, nsdl_resource);
MACRUM 0:119624335925 1245
MACRUM 0:119624335925 1246 // Put under observation if auto-obs feature is set.
MACRUM 0:119624335925 1247 // TODO! What if the observation is set in multiple levels?
MACRUM 0:119624335925 1248 if (nsdl_resource && nsdl_resource->auto_observable && result != SN_GRS_RESOURCE_ALREADY_EXISTS) {
MACRUM 0:119624335925 1249 base->set_under_observation(true, base->observation_handler());
MACRUM 0:119624335925 1250
MACRUM 0:119624335925 1251 // Increment auto-obs token to be unique in every object
MACRUM 0:119624335925 1252 _auto_obs_token++;
MACRUM 0:119624335925 1253 if (_auto_obs_token > AUTO_OBS_TOKEN_MAX) {
MACRUM 0:119624335925 1254 _auto_obs_token = 1;
MACRUM 0:119624335925 1255 }
MACRUM 0:119624335925 1256
MACRUM 0:119624335925 1257 // Store token in big-endian byte order
MACRUM 0:119624335925 1258 uint8_t token[sizeof(uint16_t)];
MACRUM 0:119624335925 1259 common_write_16_bit(_auto_obs_token, token);
MACRUM 0:119624335925 1260 base->set_observation_token(token, sizeof(uint16_t));
MACRUM 0:119624335925 1261
MACRUM 0:119624335925 1262 switch (base->base_type()) {
MACRUM 0:119624335925 1263 case M2MBase::Object:
MACRUM 0:119624335925 1264 base->add_observation_level(M2MBase::O_Attribute);
MACRUM 0:119624335925 1265 break;
MACRUM 0:119624335925 1266
MACRUM 0:119624335925 1267 case M2MBase::ObjectInstance:
MACRUM 0:119624335925 1268 base->add_observation_level(M2MBase::OI_Attribute);
MACRUM 0:119624335925 1269 break;
MACRUM 0:119624335925 1270
MACRUM 0:119624335925 1271 case M2MBase::Resource:
MACRUM 0:119624335925 1272 case M2MBase::ResourceInstance:
MACRUM 0:119624335925 1273 base->add_observation_level(M2MBase::R_Attribute);
MACRUM 0:119624335925 1274 break;
MACRUM 0:119624335925 1275 }
MACRUM 0:119624335925 1276 }
MACRUM 0:119624335925 1277
MACRUM 0:119624335925 1278 // Either the resource is created or it already
MACRUM 0:119624335925 1279 // exists , then result is success.
MACRUM 0:119624335925 1280 if (result == 0 ||
MACRUM 0:119624335925 1281 result == SN_GRS_RESOURCE_ALREADY_EXISTS){
MACRUM 0:119624335925 1282 success = true;
MACRUM 0:119624335925 1283 }
MACRUM 0:119624335925 1284 }
MACRUM 0:119624335925 1285 release_mutex();
MACRUM 0:119624335925 1286 return success;
MACRUM 0:119624335925 1287 }
MACRUM 0:119624335925 1288
MACRUM 0:119624335925 1289 // convenience method to get the URI from its buffer field...
MACRUM 0:119624335925 1290 String M2MNsdlInterface::coap_to_string(const uint8_t *coap_data, int coap_data_length)
MACRUM 0:119624335925 1291 {
MACRUM 0:119624335925 1292 String value = "";
MACRUM 0:119624335925 1293 if (coap_data != NULL && coap_data_length > 0) {
MACRUM 0:119624335925 1294 value.append_raw((char *)coap_data,coap_data_length);
MACRUM 0:119624335925 1295 }
MACRUM 0:119624335925 1296 return value;
MACRUM 0:119624335925 1297 }
MACRUM 0:119624335925 1298
MACRUM 0:119624335925 1299 uint64_t M2MNsdlInterface::registration_time() const
MACRUM 0:119624335925 1300 {
MACRUM 0:119624335925 1301 uint64_t value = 0;
MACRUM 0:119624335925 1302 if(_endpoint) {
MACRUM 0:119624335925 1303 value = _server->resource_value_int(M2MServer::Lifetime);
MACRUM 0:119624335925 1304 }
MACRUM 0:119624335925 1305
MACRUM 0:119624335925 1306 if(value >= OPTIMUM_LIFETIME) {
MACRUM 0:119624335925 1307 value = value - REDUCE_LIFETIME;
MACRUM 0:119624335925 1308 } else {
MACRUM 0:119624335925 1309 value = REDUCTION_FACTOR * value;
MACRUM 0:119624335925 1310 }
MACRUM 0:119624335925 1311 tr_debug("M2MNsdlInterface::registration_time - value (in seconds) %" PRIu64, value);
MACRUM 0:119624335925 1312 return value;
MACRUM 0:119624335925 1313 }
MACRUM 0:119624335925 1314
MACRUM 0:119624335925 1315 M2MBase* M2MNsdlInterface::find_resource(const String &object_name,
MACRUM 0:119624335925 1316 const uint16_t msg_id) const
MACRUM 0:119624335925 1317 {
MACRUM 0:119624335925 1318 M2MBase *object = NULL;
MACRUM 0:119624335925 1319 if(!_object_list.empty()) {
MACRUM 0:119624335925 1320 M2MObjectList::const_iterator it;
MACRUM 0:119624335925 1321 it = _object_list.begin();
MACRUM 0:119624335925 1322 for ( ; it != _object_list.end(); it++ ) {
MACRUM 0:119624335925 1323 if (!msg_id) {
MACRUM 0:119624335925 1324 if (strcmp((char*)(*it)->uri_path(), object_name.c_str()) == 0) {
MACRUM 0:119624335925 1325 object = (*it);
MACRUM 0:119624335925 1326 tr_debug("M2MNsdlInterface::find_resource(%s) found", object_name.c_str());
MACRUM 0:119624335925 1327 break;
MACRUM 0:119624335925 1328 }
MACRUM 0:119624335925 1329 } else {
MACRUM 0:119624335925 1330 uint16_t stored_msg_id = (*it)->get_notification_msgid();
MACRUM 0:119624335925 1331 if (stored_msg_id == msg_id) {
MACRUM 0:119624335925 1332 object = (*it);
MACRUM 0:119624335925 1333 tr_debug("M2MNsdlInterface::find_resource - msg id found");
MACRUM 0:119624335925 1334 break;
MACRUM 0:119624335925 1335 }
MACRUM 0:119624335925 1336 }
MACRUM 0:119624335925 1337 object = find_resource((*it), object_name, msg_id);
MACRUM 0:119624335925 1338 if(object != NULL) {
MACRUM 0:119624335925 1339 break;
MACRUM 0:119624335925 1340 }
MACRUM 0:119624335925 1341 }
MACRUM 0:119624335925 1342 }
MACRUM 0:119624335925 1343 return object;
MACRUM 0:119624335925 1344 }
MACRUM 0:119624335925 1345
MACRUM 0:119624335925 1346 M2MBase* M2MNsdlInterface::find_resource(const M2MObject *object,
MACRUM 0:119624335925 1347 const String &object_instance,
MACRUM 0:119624335925 1348 const uint16_t msg_id) const
MACRUM 0:119624335925 1349 {
MACRUM 0:119624335925 1350 M2MBase *instance = NULL;
MACRUM 0:119624335925 1351 if(object) {
MACRUM 0:119624335925 1352 const M2MObjectInstanceList &list = object->instances();
MACRUM 0:119624335925 1353 if(!list.empty()) {
MACRUM 0:119624335925 1354 M2MObjectInstanceList::const_iterator it;
MACRUM 0:119624335925 1355 it = list.begin();
MACRUM 0:119624335925 1356 for ( ; it != list.end(); it++ ) {
MACRUM 0:119624335925 1357 if (!msg_id) {
MACRUM 0:119624335925 1358 if(!strcmp((char*)(*it)->uri_path(), object_instance.c_str())){
MACRUM 0:119624335925 1359 instance = (*it);
MACRUM 0:119624335925 1360 tr_debug("M2MNsdlInterface::find_resource(object instance level) - found (%s)",
MACRUM 0:119624335925 1361 (char*)(*it)->uri_path());
MACRUM 0:119624335925 1362 break;
MACRUM 0:119624335925 1363 }
MACRUM 0:119624335925 1364 } else {
MACRUM 0:119624335925 1365 uint16_t stored_msg_id = (*it)->get_notification_msgid();
MACRUM 0:119624335925 1366 if (stored_msg_id == msg_id) {
MACRUM 0:119624335925 1367 instance = (*it);
MACRUM 0:119624335925 1368 tr_debug("M2MNsdlInterface::find_resource(object instance level) - found msgid (%d)", stored_msg_id);
MACRUM 0:119624335925 1369 break;
MACRUM 0:119624335925 1370 }
MACRUM 0:119624335925 1371 }
MACRUM 0:119624335925 1372 instance = find_resource((*it),object_instance, msg_id);
MACRUM 0:119624335925 1373 if(instance != NULL){
MACRUM 0:119624335925 1374 break;
MACRUM 0:119624335925 1375 }
MACRUM 0:119624335925 1376 }
MACRUM 0:119624335925 1377 }
MACRUM 0:119624335925 1378 }
MACRUM 0:119624335925 1379 return instance;
MACRUM 0:119624335925 1380 }
MACRUM 0:119624335925 1381
MACRUM 0:119624335925 1382 M2MBase* M2MNsdlInterface::find_resource(const M2MObjectInstance *object_instance,
MACRUM 0:119624335925 1383 const String &resource_instance,
MACRUM 0:119624335925 1384 const uint16_t msg_id) const
MACRUM 0:119624335925 1385 {
MACRUM 0:119624335925 1386 M2MBase *instance = NULL;
MACRUM 0:119624335925 1387 if(object_instance) {
MACRUM 0:119624335925 1388 const M2MResourceList &list = object_instance->resources();
MACRUM 0:119624335925 1389 if(!list.empty()) {
MACRUM 0:119624335925 1390 M2MResourceList::const_iterator it;
MACRUM 0:119624335925 1391 it = list.begin();
MACRUM 0:119624335925 1392 for ( ; it != list.end(); it++ ) {
MACRUM 0:119624335925 1393 if (!msg_id) {
MACRUM 0:119624335925 1394 if(!strcmp((char*)(*it)->uri_path(), resource_instance.c_str())) {
MACRUM 0:119624335925 1395 instance = *it;
MACRUM 0:119624335925 1396 break;
MACRUM 0:119624335925 1397 }
MACRUM 0:119624335925 1398 else if((*it)->supports_multiple_instances()) {
MACRUM 0:119624335925 1399 instance = find_resource((*it), (*it)->uri_path(),
MACRUM 0:119624335925 1400 resource_instance);
MACRUM 0:119624335925 1401 if(instance != NULL){
MACRUM 0:119624335925 1402 break;
MACRUM 0:119624335925 1403 }
MACRUM 0:119624335925 1404 }
MACRUM 0:119624335925 1405 } else {
MACRUM 0:119624335925 1406 uint16_t stored_msg_id = (*it)->get_notification_msgid();
MACRUM 0:119624335925 1407 if (stored_msg_id == msg_id) {
MACRUM 0:119624335925 1408 instance = *it;
MACRUM 0:119624335925 1409 tr_debug("M2MNsdlInterface::find_resource(resource level) - found msgid (%d)", stored_msg_id);
MACRUM 0:119624335925 1410 break;
MACRUM 0:119624335925 1411 }
MACRUM 0:119624335925 1412 }
MACRUM 0:119624335925 1413 }
MACRUM 0:119624335925 1414 }
MACRUM 0:119624335925 1415 }
MACRUM 0:119624335925 1416 return instance;
MACRUM 0:119624335925 1417 }
MACRUM 0:119624335925 1418
MACRUM 0:119624335925 1419 M2MBase* M2MNsdlInterface::find_resource(const M2MResource *resource,
MACRUM 0:119624335925 1420 const String &object_name,
MACRUM 0:119624335925 1421 const String &resource_instance) const
MACRUM 0:119624335925 1422 {
MACRUM 0:119624335925 1423 M2MBase *res = NULL;
MACRUM 0:119624335925 1424 if(resource) {
MACRUM 0:119624335925 1425 if(resource->supports_multiple_instances()) {
MACRUM 0:119624335925 1426 const M2MResourceInstanceList &list = resource->resource_instances();
MACRUM 0:119624335925 1427 if(!list.empty()) {
MACRUM 0:119624335925 1428 M2MResourceInstanceList::const_iterator it;
MACRUM 0:119624335925 1429 it = list.begin();
MACRUM 0:119624335925 1430 for ( ; it != list.end(); it++ ) {
MACRUM 0:119624335925 1431 if(!strcmp((char*)(*it)->uri_path(), resource_instance.c_str())){
MACRUM 0:119624335925 1432 res = (*it);
MACRUM 0:119624335925 1433 break;
MACRUM 0:119624335925 1434 }
MACRUM 0:119624335925 1435 }
MACRUM 0:119624335925 1436 }
MACRUM 0:119624335925 1437 }
MACRUM 0:119624335925 1438 }
MACRUM 0:119624335925 1439 return res;
MACRUM 0:119624335925 1440 }
MACRUM 0:119624335925 1441
MACRUM 0:119624335925 1442 bool M2MNsdlInterface::object_present(M2MObject* object) const
MACRUM 0:119624335925 1443 {
MACRUM 0:119624335925 1444 bool success = false;
MACRUM 0:119624335925 1445 if(object && !_object_list.empty()) {
MACRUM 0:119624335925 1446 M2MObjectList::const_iterator it;
MACRUM 0:119624335925 1447 it = _object_list.begin();
MACRUM 0:119624335925 1448 for ( ; it != _object_list.end(); it++ ) {
MACRUM 0:119624335925 1449 if((*it) == object) {
MACRUM 0:119624335925 1450 success = true;
MACRUM 0:119624335925 1451 break;
MACRUM 0:119624335925 1452 }
MACRUM 0:119624335925 1453 }
MACRUM 0:119624335925 1454 }
MACRUM 0:119624335925 1455 return success;
MACRUM 0:119624335925 1456 }
MACRUM 0:119624335925 1457
MACRUM 0:119624335925 1458 bool M2MNsdlInterface::add_object_to_list(M2MObject* object)
MACRUM 0:119624335925 1459 {
MACRUM 0:119624335925 1460 bool success = false;
MACRUM 0:119624335925 1461 if(object && !object_present(object)) {
MACRUM 0:119624335925 1462 _object_list.push_back(object);
MACRUM 0:119624335925 1463 success = true;
MACRUM 0:119624335925 1464 }
MACRUM 0:119624335925 1465 return success;
MACRUM 0:119624335925 1466 }
MACRUM 0:119624335925 1467
MACRUM 0:119624335925 1468 M2MInterface::Error M2MNsdlInterface::interface_error(const sn_coap_hdr_s &coap_header)
MACRUM 0:119624335925 1469 {
MACRUM 0:119624335925 1470 M2MInterface::Error error;
MACRUM 0:119624335925 1471 switch(coap_header.msg_code) {
MACRUM 0:119624335925 1472 case COAP_MSG_CODE_RESPONSE_BAD_REQUEST:
MACRUM 0:119624335925 1473 case COAP_MSG_CODE_RESPONSE_BAD_OPTION:
MACRUM 0:119624335925 1474 case COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_INCOMPLETE:
MACRUM 0:119624335925 1475 case COAP_MSG_CODE_RESPONSE_PRECONDITION_FAILED:
MACRUM 0:119624335925 1476 case COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE:
MACRUM 0:119624335925 1477 case COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT:
MACRUM 0:119624335925 1478 error = M2MInterface::InvalidParameters;
MACRUM 0:119624335925 1479 break;
MACRUM 0:119624335925 1480 case COAP_MSG_CODE_RESPONSE_UNAUTHORIZED:
MACRUM 0:119624335925 1481 case COAP_MSG_CODE_RESPONSE_FORBIDDEN:
MACRUM 0:119624335925 1482 case COAP_MSG_CODE_RESPONSE_NOT_ACCEPTABLE:
MACRUM 0:119624335925 1483 case COAP_MSG_CODE_RESPONSE_NOT_FOUND:
MACRUM 0:119624335925 1484 case COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED:
MACRUM 0:119624335925 1485 error = M2MInterface::NotAllowed;
MACRUM 0:119624335925 1486 break;
MACRUM 0:119624335925 1487 case COAP_MSG_CODE_RESPONSE_CREATED:
MACRUM 0:119624335925 1488 case COAP_MSG_CODE_RESPONSE_DELETED:
MACRUM 0:119624335925 1489 case COAP_MSG_CODE_RESPONSE_VALID:
MACRUM 0:119624335925 1490 case COAP_MSG_CODE_RESPONSE_CHANGED:
MACRUM 0:119624335925 1491 case COAP_MSG_CODE_RESPONSE_CONTENT:
MACRUM 0:119624335925 1492 error = M2MInterface::ErrorNone;
MACRUM 0:119624335925 1493 break;
MACRUM 0:119624335925 1494 default:
MACRUM 0:119624335925 1495 error = M2MInterface::UnknownError;
MACRUM 0:119624335925 1496 break;
MACRUM 0:119624335925 1497 }
MACRUM 0:119624335925 1498 if(coap_header.coap_status == COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED) {
MACRUM 0:119624335925 1499 error = M2MInterface::NetworkError;
MACRUM 0:119624335925 1500 }
MACRUM 0:119624335925 1501 return error;
MACRUM 0:119624335925 1502 }
MACRUM 0:119624335925 1503
MACRUM 0:119624335925 1504 const char *M2MNsdlInterface::coap_error(const sn_coap_hdr_s &coap_header)
MACRUM 0:119624335925 1505 {
MACRUM 0:119624335925 1506
MACRUM 0:119624335925 1507 if(coap_header.msg_code == COAP_MSG_CODE_RESPONSE_BAD_REQUEST) {
MACRUM 0:119624335925 1508 return COAP_ERROR_REASON_1;
MACRUM 0:119624335925 1509 } else if(coap_header.msg_code == COAP_MSG_CODE_RESPONSE_BAD_OPTION) {
MACRUM 0:119624335925 1510 return COAP_ERROR_REASON_2;
MACRUM 0:119624335925 1511 } else if(coap_header.msg_code == COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_INCOMPLETE) {
MACRUM 0:119624335925 1512 return COAP_ERROR_REASON_3;
MACRUM 0:119624335925 1513 }else if(coap_header.msg_code == COAP_MSG_CODE_RESPONSE_PRECONDITION_FAILED) {
MACRUM 0:119624335925 1514 return COAP_ERROR_REASON_4;
MACRUM 0:119624335925 1515 } else if(coap_header.msg_code == COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE) {
MACRUM 0:119624335925 1516 return COAP_ERROR_REASON_5;
MACRUM 0:119624335925 1517 } else if(coap_header.msg_code == COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT) {
MACRUM 0:119624335925 1518 return COAP_ERROR_REASON_6;
MACRUM 0:119624335925 1519 } else if(coap_header.msg_code == COAP_MSG_CODE_RESPONSE_UNAUTHORIZED) {
MACRUM 0:119624335925 1520 return COAP_ERROR_REASON_7;
MACRUM 0:119624335925 1521 } else if(coap_header.msg_code == COAP_MSG_CODE_RESPONSE_FORBIDDEN) {
MACRUM 0:119624335925 1522 return COAP_ERROR_REASON_8;
MACRUM 0:119624335925 1523 } else if(coap_header.msg_code == COAP_MSG_CODE_RESPONSE_NOT_ACCEPTABLE) {
MACRUM 0:119624335925 1524 return COAP_ERROR_REASON_9;
MACRUM 0:119624335925 1525 } else if(coap_header.msg_code == COAP_MSG_CODE_RESPONSE_NOT_FOUND) {
MACRUM 0:119624335925 1526 return COAP_ERROR_REASON_10;
MACRUM 0:119624335925 1527 } else if(coap_header.msg_code == COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED) {
MACRUM 0:119624335925 1528 return COAP_ERROR_REASON_11;
MACRUM 0:119624335925 1529 } else if(coap_header.msg_code == COAP_MSG_CODE_RESPONSE_SERVICE_UNAVAILABLE) {
MACRUM 0:119624335925 1530 return COAP_ERROR_REASON_13;
MACRUM 0:119624335925 1531 } else if(coap_header.msg_code == COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR) {
MACRUM 0:119624335925 1532 return COAP_ERROR_REASON_14;
MACRUM 0:119624335925 1533 } else if(coap_header.msg_code == COAP_MSG_CODE_RESPONSE_BAD_GATEWAY) {
MACRUM 0:119624335925 1534 return COAP_ERROR_REASON_15;
MACRUM 0:119624335925 1535 } else if(coap_header.msg_code == COAP_MSG_CODE_RESPONSE_GATEWAY_TIMEOUT) {
MACRUM 0:119624335925 1536 return COAP_ERROR_REASON_16;
MACRUM 0:119624335925 1537 } else if(coap_header.msg_code == COAP_MSG_CODE_RESPONSE_PROXYING_NOT_SUPPORTED) {
MACRUM 0:119624335925 1538 return COAP_ERROR_REASON_17;
MACRUM 0:119624335925 1539 } else if(coap_header.coap_status == COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED) {
MACRUM 0:119624335925 1540 return COAP_ERROR_REASON_12;
MACRUM 0:119624335925 1541 }
MACRUM 0:119624335925 1542 return COAP_NO_ERROR;
MACRUM 0:119624335925 1543 }
MACRUM 0:119624335925 1544
MACRUM 0:119624335925 1545 void M2MNsdlInterface::send_object_observation(M2MObject *object,
MACRUM 0:119624335925 1546 uint16_t obs_number,
MACRUM 0:119624335925 1547 const m2m::Vector<uint16_t> &changed_instance_ids,
MACRUM 0:119624335925 1548 bool send_object,
MACRUM 0:119624335925 1549 bool resend)
MACRUM 0:119624335925 1550 {
MACRUM 0:119624335925 1551 tr_info("M2MNsdlInterface::send_object_observation");
MACRUM 0:119624335925 1552 if(object) {
MACRUM 0:119624335925 1553 uint8_t *value = 0;
MACRUM 0:119624335925 1554 uint32_t length = 0;
MACRUM 0:119624335925 1555 uint8_t token[MAX_TOKEN_SIZE];
MACRUM 0:119624335925 1556 uint8_t token_length = 0;
MACRUM 0:119624335925 1557
MACRUM 0:119624335925 1558 // Send whole object structure
MACRUM 0:119624335925 1559 if (send_object) {
MACRUM 0:119624335925 1560 value = M2MTLVSerializer::serialize(object->instances(), length);
MACRUM 0:119624335925 1561 }
MACRUM 0:119624335925 1562 // Send only changed object instances
MACRUM 0:119624335925 1563 else {
MACRUM 0:119624335925 1564 M2MObjectInstanceList list;
MACRUM 0:119624335925 1565 Vector<uint16_t>::const_iterator it;
MACRUM 0:119624335925 1566 it = changed_instance_ids.begin();
MACRUM 0:119624335925 1567 for (; it != changed_instance_ids.end(); it++){
MACRUM 0:119624335925 1568 M2MObjectInstance* obj_instance = object->object_instance(*it);
MACRUM 0:119624335925 1569 if (obj_instance){
MACRUM 0:119624335925 1570 list.push_back(obj_instance);
MACRUM 0:119624335925 1571 }
MACRUM 0:119624335925 1572 }
MACRUM 0:119624335925 1573 if (!list.empty()) {
MACRUM 0:119624335925 1574 value = M2MTLVSerializer::serialize(list, length);
MACRUM 0:119624335925 1575 list.clear();
MACRUM 0:119624335925 1576 }
MACRUM 0:119624335925 1577 }
MACRUM 0:119624335925 1578
MACRUM 0:119624335925 1579 object->get_observation_token((uint8_t*)&token,token_length);
MACRUM 0:119624335925 1580 if (resend) {
MACRUM 0:119624335925 1581 sn_nsdl_send_observation_notification(_nsdl_handle, token, token_length, value, length,
MACRUM 0:119624335925 1582 sn_coap_observe_e(obs_number), COAP_MSG_TYPE_CONFIRMABLE,
MACRUM 0:119624335925 1583 sn_coap_content_format_e(object->coap_content_type()),
MACRUM 0:119624335925 1584 object->get_notification_msgid());
MACRUM 0:119624335925 1585 } else {
MACRUM 0:119624335925 1586 int32_t msgid = sn_nsdl_send_observation_notification(_nsdl_handle, token, token_length, value, length,
MACRUM 0:119624335925 1587 sn_coap_observe_e(obs_number), COAP_MSG_TYPE_CONFIRMABLE,
MACRUM 0:119624335925 1588 sn_coap_content_format_e(object->coap_content_type()), -1);
MACRUM 0:119624335925 1589 execute_notification_delivery_status_cb(object, msgid);
MACRUM 0:119624335925 1590 }
MACRUM 0:119624335925 1591
MACRUM 0:119624335925 1592 memory_free(value);
MACRUM 0:119624335925 1593 }
MACRUM 0:119624335925 1594 }
MACRUM 0:119624335925 1595
MACRUM 0:119624335925 1596 void M2MNsdlInterface::send_object_instance_observation(M2MObjectInstance *object_instance,
MACRUM 0:119624335925 1597 uint16_t obs_number,
MACRUM 0:119624335925 1598 bool resend)
MACRUM 0:119624335925 1599 {
MACRUM 0:119624335925 1600 tr_info("M2MNsdlInterface::send_object_instance_observation");
MACRUM 0:119624335925 1601 if(object_instance) {
MACRUM 0:119624335925 1602 uint8_t *value = 0;
MACRUM 0:119624335925 1603 uint32_t length = 0;
MACRUM 0:119624335925 1604 uint8_t token[MAX_TOKEN_SIZE];
MACRUM 0:119624335925 1605 uint8_t token_length = 0;
MACRUM 0:119624335925 1606
MACRUM 0:119624335925 1607 value = M2MTLVSerializer::serialize(object_instance->resources(), length);
MACRUM 0:119624335925 1608
MACRUM 0:119624335925 1609 object_instance->get_observation_token((uint8_t*)&token,token_length);
MACRUM 0:119624335925 1610
MACRUM 0:119624335925 1611 if (resend) {
MACRUM 0:119624335925 1612 sn_nsdl_send_observation_notification(_nsdl_handle, token, token_length, value, length,
MACRUM 0:119624335925 1613 sn_coap_observe_e(obs_number), COAP_MSG_TYPE_CONFIRMABLE,
MACRUM 0:119624335925 1614 sn_coap_content_format_e(object_instance->coap_content_type()),
MACRUM 0:119624335925 1615 object_instance->get_notification_msgid());
MACRUM 0:119624335925 1616 } else {
MACRUM 0:119624335925 1617 int32_t msgid = sn_nsdl_send_observation_notification(_nsdl_handle, token, token_length, value, length,
MACRUM 0:119624335925 1618 sn_coap_observe_e(obs_number), COAP_MSG_TYPE_CONFIRMABLE,
MACRUM 0:119624335925 1619 sn_coap_content_format_e(object_instance->coap_content_type()), -1);
MACRUM 0:119624335925 1620 execute_notification_delivery_status_cb(object_instance, msgid);
MACRUM 0:119624335925 1621 }
MACRUM 0:119624335925 1622
MACRUM 0:119624335925 1623 memory_free(value);
MACRUM 0:119624335925 1624 }
MACRUM 0:119624335925 1625 }
MACRUM 0:119624335925 1626
MACRUM 0:119624335925 1627 void M2MNsdlInterface::send_resource_observation(M2MResource *resource,
MACRUM 0:119624335925 1628 uint16_t obs_number,
MACRUM 0:119624335925 1629 bool resend)
MACRUM 0:119624335925 1630 {
MACRUM 0:119624335925 1631 if(resource) {
MACRUM 0:119624335925 1632 tr_info("M2MNsdlInterface::send_resource_observation - uri %s", resource->uri_path());
MACRUM 0:119624335925 1633 uint8_t *value = 0;
MACRUM 0:119624335925 1634 uint32_t length = 0;
MACRUM 0:119624335925 1635 uint8_t token[MAX_TOKEN_SIZE];
MACRUM 0:119624335925 1636 uint8_t token_length = 0;
MACRUM 0:119624335925 1637
MACRUM 0:119624335925 1638 resource->get_observation_token((uint8_t*)token,token_length);
MACRUM 0:119624335925 1639 uint16_t content_type = 0;
MACRUM 0:119624335925 1640 if(M2MResourceBase::OPAQUE == resource->resource_instance_type()) {
MACRUM 0:119624335925 1641 content_type = COAP_CONTENT_OMA_OPAQUE_TYPE;
MACRUM 0:119624335925 1642 }
MACRUM 0:119624335925 1643 if (resource->resource_instance_count() > 0) {
MACRUM 0:119624335925 1644 content_type = resource->coap_content_type();
MACRUM 0:119624335925 1645 value = M2MTLVSerializer::serialize(resource, length);
MACRUM 0:119624335925 1646 } else {
MACRUM 0:119624335925 1647 resource->get_value(value,length);
MACRUM 0:119624335925 1648 }
MACRUM 0:119624335925 1649
MACRUM 0:119624335925 1650 if (resend) {
MACRUM 0:119624335925 1651 sn_nsdl_send_observation_notification(_nsdl_handle, token, token_length, value, length,
MACRUM 0:119624335925 1652 sn_coap_observe_e(obs_number),
MACRUM 0:119624335925 1653 COAP_MSG_TYPE_CONFIRMABLE,
MACRUM 0:119624335925 1654 sn_coap_content_format_e(content_type),
MACRUM 0:119624335925 1655 resource->get_notification_msgid());
MACRUM 0:119624335925 1656 } else {
MACRUM 0:119624335925 1657 int32_t msgid = sn_nsdl_send_observation_notification(_nsdl_handle, token, token_length, value, length,
MACRUM 0:119624335925 1658 sn_coap_observe_e(obs_number),
MACRUM 0:119624335925 1659 COAP_MSG_TYPE_CONFIRMABLE,
MACRUM 0:119624335925 1660 sn_coap_content_format_e(content_type), -1);
MACRUM 0:119624335925 1661 execute_notification_delivery_status_cb(resource, msgid);
MACRUM 0:119624335925 1662 }
MACRUM 0:119624335925 1663
MACRUM 0:119624335925 1664 memory_free(value);
MACRUM 0:119624335925 1665 }
MACRUM 0:119624335925 1666 }
MACRUM 0:119624335925 1667 nsdl_s * M2MNsdlInterface::get_nsdl_handle() const
MACRUM 0:119624335925 1668 {
MACRUM 0:119624335925 1669 return _nsdl_handle;
MACRUM 0:119624335925 1670 }
MACRUM 0:119624335925 1671
MACRUM 0:119624335925 1672 void M2MNsdlInterface::handle_bootstrap_put_message(sn_coap_hdr_s *coap_header,
MACRUM 0:119624335925 1673 sn_nsdl_addr_s *address) {
MACRUM 0:119624335925 1674 #ifndef M2M_CLIENT_DISABLE_BOOTSTRAP_FEATURE
MACRUM 0:119624335925 1675 tr_info("M2MNsdlInterface::handle_bootstrap_put_message");
MACRUM 0:119624335925 1676 uint8_t response_code = COAP_MSG_CODE_RESPONSE_CHANGED;
MACRUM 0:119624335925 1677 sn_coap_hdr_s *coap_response = NULL;
MACRUM 0:119624335925 1678 bool success = false;
MACRUM 0:119624335925 1679 uint16_t content_type = 0;
MACRUM 0:119624335925 1680 char buffer[MAX_ALLOWED_ERROR_STRING_LENGTH] = {0};
MACRUM 0:119624335925 1681 M2MNsdlInterface::ObjectType object_type = M2MNsdlInterface::SECURITY;
MACRUM 0:119624335925 1682
MACRUM 0:119624335925 1683 if (!_security) {
MACRUM 0:119624335925 1684 _security = M2MSecurity::get_instance();
MACRUM 0:119624335925 1685 }
MACRUM 0:119624335925 1686
MACRUM 0:119624335925 1687 String resource_name = coap_to_string(coap_header->uri_path_ptr,
MACRUM 0:119624335925 1688 coap_header->uri_path_len);
MACRUM 0:119624335925 1689 tr_debug("M2MNsdlInterface::handle_bootstrap_put_message - object path %s", resource_name.c_str());
MACRUM 0:119624335925 1690
MACRUM 0:119624335925 1691 // Security object
MACRUM 0:119624335925 1692 if (resource_name.compare(0,1,"0") == 0) {
MACRUM 0:119624335925 1693 object_type = M2MNsdlInterface::SECURITY;
MACRUM 0:119624335925 1694 success = true;
MACRUM 0:119624335925 1695 }
MACRUM 0:119624335925 1696 // Server object
MACRUM 0:119624335925 1697 else if (resource_name.compare(0,1,"1") == 0) {
MACRUM 0:119624335925 1698 object_type = M2MNsdlInterface::SERVER;
MACRUM 0:119624335925 1699 success = true;
MACRUM 0:119624335925 1700 }
MACRUM 0:119624335925 1701 // Device object
MACRUM 0:119624335925 1702 else if (resource_name.compare(0,1,"3") == 0) {
MACRUM 0:119624335925 1703 M2MDevice* dev = M2MInterfaceFactory::create_device();
MACRUM 0:119624335925 1704 // Not mandatory resource, that's why it must be created first
MACRUM 0:119624335925 1705 dev->create_resource(M2MDevice::CurrentTime, 0);
MACRUM 0:119624335925 1706 object_type = M2MNsdlInterface::DEVICE;
MACRUM 0:119624335925 1707 success = true;
MACRUM 0:119624335925 1708 }
MACRUM 0:119624335925 1709
MACRUM 0:119624335925 1710 if (success) {
MACRUM 0:119624335925 1711 if(coap_header->content_format != COAP_CT_NONE) {
MACRUM 0:119624335925 1712 content_type = coap_header->content_format;
MACRUM 0:119624335925 1713 }
MACRUM 0:119624335925 1714
MACRUM 0:119624335925 1715 if (content_type != COAP_CONTENT_OMA_TLV_TYPE &&
MACRUM 0:119624335925 1716 content_type != COAP_CONTENT_OMA_TLV_TYPE_OLD) {
MACRUM 0:119624335925 1717 tr_error("M2MNsdlInterface::handle_bootstrap_put_message - content_type %d", content_type);
MACRUM 0:119624335925 1718 success = false;
MACRUM 0:119624335925 1719 }
MACRUM 0:119624335925 1720 // Parse TLV message and check is the object valid
MACRUM 0:119624335925 1721 if (success) {
MACRUM 0:119624335925 1722 change_operation_mode(_security, M2MBase::PUT_ALLOWED);
MACRUM 0:119624335925 1723 success = parse_bootstrap_message(coap_header, object_type);
MACRUM 0:119624335925 1724 if (success && object_type == M2MNsdlInterface::SECURITY) {
MACRUM 0:119624335925 1725 success = validate_security_object();
MACRUM 0:119624335925 1726 if (!success) {
MACRUM 0:119624335925 1727 snprintf(buffer,sizeof(buffer), ERROR_REASON_22, "Invalid security object");
MACRUM 0:119624335925 1728 response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
MACRUM 0:119624335925 1729 }
MACRUM 0:119624335925 1730 }
MACRUM 0:119624335925 1731 // Set operation back to default ones
MACRUM 0:119624335925 1732 if (_security) {
MACRUM 0:119624335925 1733 change_operation_mode(_security, M2MBase::NOT_ALLOWED);
MACRUM 0:119624335925 1734 }
MACRUM 0:119624335925 1735 }
MACRUM 0:119624335925 1736 }
MACRUM 0:119624335925 1737
MACRUM 0:119624335925 1738 if (!success) {
MACRUM 0:119624335925 1739 response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
MACRUM 0:119624335925 1740 }
MACRUM 0:119624335925 1741
MACRUM 0:119624335925 1742 coap_response = sn_nsdl_build_response(_nsdl_handle,
MACRUM 0:119624335925 1743 coap_header,
MACRUM 0:119624335925 1744 response_code);
MACRUM 0:119624335925 1745
MACRUM 0:119624335925 1746 if (coap_response) {
MACRUM 0:119624335925 1747 sn_nsdl_send_coap_message(_nsdl_handle, address, coap_response);
MACRUM 0:119624335925 1748 sn_nsdl_release_allocated_coap_msg_mem(_nsdl_handle, coap_response);
MACRUM 0:119624335925 1749 }
MACRUM 0:119624335925 1750
MACRUM 0:119624335925 1751 if (!success) {
MACRUM 0:119624335925 1752 // Do not overwrite ERROR_REASON_22
MACRUM 0:119624335925 1753 if (strlen(buffer) == 0) {
MACRUM 0:119624335925 1754 snprintf(buffer,sizeof(buffer), ERROR_REASON_20,resource_name.c_str());
MACRUM 0:119624335925 1755 }
MACRUM 0:119624335925 1756 handle_bootstrap_error(buffer, true);
MACRUM 0:119624335925 1757 }
MACRUM 0:119624335925 1758 #else
MACRUM 0:119624335925 1759 (void) coap_header;
MACRUM 0:119624335925 1760 (void) address;
MACRUM 0:119624335925 1761 #endif
MACRUM 0:119624335925 1762 }
MACRUM 0:119624335925 1763
MACRUM 0:119624335925 1764 bool M2MNsdlInterface::parse_bootstrap_message(sn_coap_hdr_s *coap_header,
MACRUM 0:119624335925 1765 M2MNsdlInterface::ObjectType lwm2m_object_type)
MACRUM 0:119624335925 1766 {
MACRUM 0:119624335925 1767 #ifndef M2M_CLIENT_DISABLE_BOOTSTRAP_FEATURE
MACRUM 0:119624335925 1768 tr_info("M2MNsdlInterface::parse_bootstrap_message");
MACRUM 0:119624335925 1769 bool ret = false;
MACRUM 0:119624335925 1770 bool is_obj_instance = false;
MACRUM 0:119624335925 1771 uint16_t instance_id = 0;
MACRUM 0:119624335925 1772 if (_security) {
MACRUM 0:119624335925 1773 ret = is_obj_instance = M2MTLVDeserializer::is_object_instance(coap_header->payload_ptr);
MACRUM 0:119624335925 1774 if (!is_obj_instance) {
MACRUM 0:119624335925 1775 ret = M2MTLVDeserializer::is_resource(coap_header->payload_ptr);
MACRUM 0:119624335925 1776 }
MACRUM 0:119624335925 1777 if (ret) {
MACRUM 0:119624335925 1778 M2MTLVDeserializer::Error error = M2MTLVDeserializer::None;
MACRUM 0:119624335925 1779 if (is_obj_instance) {
MACRUM 0:119624335925 1780 M2MObject* dev_object = static_cast<M2MObject*> (M2MInterfaceFactory::create_device());
MACRUM 0:119624335925 1781 switch (lwm2m_object_type) {
MACRUM 0:119624335925 1782 case M2MNsdlInterface::SECURITY:
MACRUM 0:119624335925 1783 instance_id = M2MTLVDeserializer::instance_id(coap_header->payload_ptr);
MACRUM 0:119624335925 1784 if (_security->object_instance(instance_id) == NULL) {
MACRUM 0:119624335925 1785 _security->create_object_instance(M2MSecurity::M2MServer);
MACRUM 0:119624335925 1786 change_operation_mode(_security, M2MBase::PUT_ALLOWED);
MACRUM 0:119624335925 1787 }
MACRUM 0:119624335925 1788 error = M2MTLVDeserializer::deserialise_object_instances(coap_header->payload_ptr,
MACRUM 0:119624335925 1789 coap_header->payload_len,
MACRUM 0:119624335925 1790 *_security,
MACRUM 0:119624335925 1791 M2MTLVDeserializer::Put);
MACRUM 0:119624335925 1792 break;
MACRUM 0:119624335925 1793 case M2MNsdlInterface::SERVER:
MACRUM 0:119624335925 1794 error = M2MTLVDeserializer::deserialise_object_instances(coap_header->payload_ptr,
MACRUM 0:119624335925 1795 coap_header->payload_len,
MACRUM 0:119624335925 1796 *_server,
MACRUM 0:119624335925 1797 M2MTLVDeserializer::Put);
MACRUM 0:119624335925 1798 break;
MACRUM 0:119624335925 1799 case M2MNsdlInterface::DEVICE:
MACRUM 0:119624335925 1800 error = M2MTLVDeserializer::deserialise_object_instances(coap_header->payload_ptr,
MACRUM 0:119624335925 1801 coap_header->payload_len,
MACRUM 0:119624335925 1802 *dev_object,
MACRUM 0:119624335925 1803 M2MTLVDeserializer::Put);
MACRUM 0:119624335925 1804 break;
MACRUM 0:119624335925 1805 default:
MACRUM 0:119624335925 1806 break;
MACRUM 0:119624335925 1807 }
MACRUM 0:119624335925 1808 }
MACRUM 0:119624335925 1809 else {
MACRUM 0:119624335925 1810 instance_id = M2MTLVDeserializer::instance_id(coap_header->payload_ptr);
MACRUM 0:119624335925 1811 M2MObjectInstance* instance = NULL;
MACRUM 0:119624335925 1812 switch (lwm2m_object_type) {
MACRUM 0:119624335925 1813 case M2MNsdlInterface::SECURITY:
MACRUM 0:119624335925 1814 instance = _security->object_instance(instance_id);
MACRUM 0:119624335925 1815 if (instance) {
MACRUM 0:119624335925 1816 error = M2MTLVDeserializer::deserialize_resources(coap_header->payload_ptr,
MACRUM 0:119624335925 1817 coap_header->payload_len,
MACRUM 0:119624335925 1818 *instance,
MACRUM 0:119624335925 1819 M2MTLVDeserializer::Put);
MACRUM 0:119624335925 1820 } else {
MACRUM 0:119624335925 1821 error = M2MTLVDeserializer::NotValid;
MACRUM 0:119624335925 1822 }
MACRUM 0:119624335925 1823
MACRUM 0:119624335925 1824 break;
MACRUM 0:119624335925 1825 case M2MNsdlInterface::SERVER:
MACRUM 0:119624335925 1826 instance = _server->object_instance(instance_id);
MACRUM 0:119624335925 1827 if (instance) {
MACRUM 0:119624335925 1828 error = M2MTLVDeserializer::deserialize_resources(coap_header->payload_ptr,
MACRUM 0:119624335925 1829 coap_header->payload_len,
MACRUM 0:119624335925 1830 *instance,
MACRUM 0:119624335925 1831 M2MTLVDeserializer::Post);
MACRUM 0:119624335925 1832 } else {
MACRUM 0:119624335925 1833 error = M2MTLVDeserializer::NotValid;
MACRUM 0:119624335925 1834 }
MACRUM 0:119624335925 1835
MACRUM 0:119624335925 1836 break;
MACRUM 0:119624335925 1837 case M2MNsdlInterface::DEVICE:
MACRUM 0:119624335925 1838 default:
MACRUM 0:119624335925 1839 break;
MACRUM 0:119624335925 1840 }
MACRUM 0:119624335925 1841 }
MACRUM 0:119624335925 1842
MACRUM 0:119624335925 1843 if (error != M2MTLVDeserializer::None) {
MACRUM 0:119624335925 1844 tr_error("M2MNsdlInterface::parse_bootstrap_message - error %d", error);
MACRUM 0:119624335925 1845 ret = false;
MACRUM 0:119624335925 1846 }
MACRUM 0:119624335925 1847 }
MACRUM 0:119624335925 1848 } else {
MACRUM 0:119624335925 1849 tr_error("M2MNsdlInterface::parse_bootstrap_message -- no security object!");
MACRUM 0:119624335925 1850 }
MACRUM 0:119624335925 1851 return ret;
MACRUM 0:119624335925 1852 #else
MACRUM 0:119624335925 1853 (void) coap_header;
MACRUM 0:119624335925 1854 (void) is_security_object;
MACRUM 0:119624335925 1855 return false;
MACRUM 0:119624335925 1856 #endif
MACRUM 0:119624335925 1857 }
MACRUM 0:119624335925 1858
MACRUM 0:119624335925 1859 void M2MNsdlInterface::handle_bootstrap_finished(sn_coap_hdr_s *coap_header,sn_nsdl_addr_s *address)
MACRUM 0:119624335925 1860 {
MACRUM 0:119624335925 1861 #ifndef M2M_CLIENT_DISABLE_BOOTSTRAP_FEATURE
MACRUM 0:119624335925 1862 char buffer[MAX_ALLOWED_ERROR_STRING_LENGTH];
MACRUM 0:119624335925 1863
MACRUM 0:119624335925 1864 String object_name = coap_to_string(coap_header->uri_path_ptr,
MACRUM 0:119624335925 1865 coap_header->uri_path_len);
MACRUM 0:119624335925 1866 tr_info("M2MNsdlInterface::handle_bootstrap_finished - path: %s", object_name.c_str());
MACRUM 0:119624335925 1867 sn_coap_hdr_s *coap_response = NULL;
MACRUM 0:119624335925 1868 uint8_t msg_code = COAP_MSG_CODE_RESPONSE_CHANGED;
MACRUM 0:119624335925 1869
MACRUM 0:119624335925 1870 // Accept only '/bs' path and check that needed data is in security object
MACRUM 0:119624335925 1871 if (object_name.size() != 2 ||
MACRUM 0:119624335925 1872 object_name.compare(0,2,BOOTSTRAP_URI) != 0) {
MACRUM 0:119624335925 1873 snprintf(buffer,sizeof(buffer), ERROR_REASON_22, object_name.c_str());
MACRUM 0:119624335925 1874 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
MACRUM 0:119624335925 1875 }
MACRUM 0:119624335925 1876 else {
MACRUM 0:119624335925 1877 // Add short server id to server object
MACRUM 0:119624335925 1878 int32_t m2m_id = _security->get_security_instance_id(M2MSecurity::M2MServer);
MACRUM 0:119624335925 1879 if (m2m_id == -1) {
MACRUM 0:119624335925 1880 snprintf(buffer,sizeof(buffer), ERROR_REASON_4);
MACRUM 0:119624335925 1881 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
MACRUM 0:119624335925 1882 }
MACRUM 0:119624335925 1883 else {
MACRUM 0:119624335925 1884 _server->set_resource_value(M2MServer::ShortServerID,
MACRUM 0:119624335925 1885 _security->resource_value_int(M2MSecurity::ShortServerID, m2m_id));
MACRUM 0:119624335925 1886 }
MACRUM 0:119624335925 1887 }
MACRUM 0:119624335925 1888
MACRUM 0:119624335925 1889 coap_response = sn_nsdl_build_response(_nsdl_handle,
MACRUM 0:119624335925 1890 coap_header,
MACRUM 0:119624335925 1891 msg_code);
MACRUM 0:119624335925 1892 if(coap_response) {
MACRUM 0:119624335925 1893 sn_nsdl_send_coap_message(_nsdl_handle, address, coap_response);
MACRUM 0:119624335925 1894 sn_nsdl_release_allocated_coap_msg_mem(_nsdl_handle, coap_response);
MACRUM 0:119624335925 1895 }
MACRUM 0:119624335925 1896
MACRUM 0:119624335925 1897 if (COAP_MSG_CODE_RESPONSE_CHANGED == msg_code) {
MACRUM 0:119624335925 1898 // Switch back to original ep name
MACRUM 0:119624335925 1899 if (_endpoint->endpoint_name_ptr) {
MACRUM 0:119624335925 1900 memory_free(_endpoint->endpoint_name_ptr);
MACRUM 0:119624335925 1901 }
MACRUM 0:119624335925 1902 _endpoint->endpoint_name_ptr = alloc_string_copy((uint8_t*)_endpoint_name.c_str(), _endpoint_name.length());
MACRUM 0:119624335925 1903 _endpoint->endpoint_name_len = _endpoint_name.length();
MACRUM 0:119624335925 1904 // Inform observer that bootstrap is finished but it should wait until nsdl has sent data.
MACRUM 0:119624335925 1905 // The final bootstrap_done callback is called in the observers data_sent callback.
MACRUM 0:119624335925 1906 _observer.bootstrap_wait();
MACRUM 0:119624335925 1907 } else {
MACRUM 0:119624335925 1908 handle_bootstrap_error(buffer, true);
MACRUM 0:119624335925 1909 }
MACRUM 0:119624335925 1910 #else
MACRUM 0:119624335925 1911 (void) coap_header;
MACRUM 0:119624335925 1912 (void) address;
MACRUM 0:119624335925 1913 #endif
MACRUM 0:119624335925 1914 }
MACRUM 0:119624335925 1915
MACRUM 0:119624335925 1916 void M2MNsdlInterface::handle_bootstrap_delete(sn_coap_hdr_s *coap_header,sn_nsdl_addr_s *address)
MACRUM 0:119624335925 1917 {
MACRUM 0:119624335925 1918
MACRUM 0:119624335925 1919 #ifndef M2M_CLIENT_DISABLE_BOOTSTRAP_FEATURE
MACRUM 0:119624335925 1920 char buffer[MAX_ALLOWED_ERROR_STRING_LENGTH];
MACRUM 0:119624335925 1921 memset(buffer,0,sizeof(buffer));
MACRUM 0:119624335925 1922 sn_coap_hdr_s *coap_response = NULL;
MACRUM 0:119624335925 1923 uint8_t msg_code = COAP_MSG_CODE_RESPONSE_DELETED;
MACRUM 0:119624335925 1924 String object_name = coap_to_string(coap_header->uri_path_ptr,
MACRUM 0:119624335925 1925 coap_header->uri_path_len);
MACRUM 0:119624335925 1926 tr_info("M2MNsdlInterface::handle_bootstrap_delete - obj %s", object_name.c_str());
MACRUM 0:119624335925 1927 if(!_identity_accepted) {
MACRUM 0:119624335925 1928 snprintf(buffer,sizeof(buffer), ERROR_REASON_21,"/bs un-init");
MACRUM 0:119624335925 1929 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
MACRUM 0:119624335925 1930 }
MACRUM 0:119624335925 1931 // Only following paths are accepted, 0, 0/0
MACRUM 0:119624335925 1932 else if (object_name.size() == 2 || object_name.size() > 3) {
MACRUM 0:119624335925 1933 snprintf(buffer,sizeof(buffer), ERROR_REASON_21,object_name.c_str());
MACRUM 0:119624335925 1934 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
MACRUM 0:119624335925 1935 }
MACRUM 0:119624335925 1936 else if ((object_name.size() == 1 && object_name.compare(0,1,"0") != 0) ||
MACRUM 0:119624335925 1937 (object_name.size() == 3 && object_name.compare(0,3,"0/0") != 0)) {
MACRUM 0:119624335925 1938 snprintf(buffer,sizeof(buffer), ERROR_REASON_21,object_name.c_str());
MACRUM 0:119624335925 1939 msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST;
MACRUM 0:119624335925 1940 }
MACRUM 0:119624335925 1941
MACRUM 0:119624335925 1942 coap_response = sn_nsdl_build_response(_nsdl_handle,
MACRUM 0:119624335925 1943 coap_header,
MACRUM 0:119624335925 1944 msg_code);
MACRUM 0:119624335925 1945
MACRUM 0:119624335925 1946 if(coap_response) {
MACRUM 0:119624335925 1947 sn_nsdl_send_coap_message(_nsdl_handle, address, coap_response);
MACRUM 0:119624335925 1948 sn_nsdl_release_allocated_coap_msg_mem(_nsdl_handle, coap_response);
MACRUM 0:119624335925 1949 if(_security) {
MACRUM 0:119624335925 1950 _security->clear_resources();
MACRUM 0:119624335925 1951 }
MACRUM 0:119624335925 1952 }
MACRUM 0:119624335925 1953 if (!coap_response || COAP_MSG_CODE_RESPONSE_DELETED != msg_code) {
MACRUM 0:119624335925 1954 handle_bootstrap_error(buffer, true);
MACRUM 0:119624335925 1955 }
MACRUM 0:119624335925 1956 #else
MACRUM 0:119624335925 1957 (void) coap_header;
MACRUM 0:119624335925 1958 (void) address;
MACRUM 0:119624335925 1959 #endif
MACRUM 0:119624335925 1960 }
MACRUM 0:119624335925 1961
MACRUM 0:119624335925 1962 bool M2MNsdlInterface::validate_security_object()
MACRUM 0:119624335925 1963 {
MACRUM 0:119624335925 1964 bool valid = false;
MACRUM 0:119624335925 1965 #ifndef M2M_CLIENT_DISABLE_BOOTSTRAP_FEATURE
MACRUM 0:119624335925 1966 M2MObjectInstanceList instances = _security->instances();
MACRUM 0:119624335925 1967 M2MObjectInstanceList::const_iterator it;
MACRUM 0:119624335925 1968 it = instances.begin();
MACRUM 0:119624335925 1969 uint16_t instance_id = 0;
MACRUM 0:119624335925 1970 for ( ; it != instances.end(); it++ ) {
MACRUM 0:119624335925 1971 valid = true;
MACRUM 0:119624335925 1972 instance_id = (*it)->instance_id();
MACRUM 0:119624335925 1973 tr_debug("M2MNsdlInterface::validate_security_object - instance %d", instance_id);
MACRUM 0:119624335925 1974 String address = _security->resource_value_string(M2MSecurity::M2MServerUri, instance_id);
MACRUM 0:119624335925 1975 uint32_t sec_mode = _security->resource_value_int(M2MSecurity::SecurityMode, instance_id);
MACRUM 0:119624335925 1976 uint32_t is_bs_server = _security->resource_value_int(M2MSecurity::BootstrapServer, instance_id);
MACRUM 0:119624335925 1977 uint32_t public_key_size = 0;
MACRUM 0:119624335925 1978 uint32_t server_key_size = 0;
MACRUM 0:119624335925 1979 uint32_t pkey_size = 0;
MACRUM 0:119624335925 1980
MACRUM 0:119624335925 1981 M2MResource* resource = _security->get_resource(M2MSecurity::PublicKey, instance_id);
MACRUM 0:119624335925 1982 if (resource) {
MACRUM 0:119624335925 1983 public_key_size = resource->value_length();
MACRUM 0:119624335925 1984 }
MACRUM 0:119624335925 1985 resource = _security->get_resource(M2MSecurity::ServerPublicKey, instance_id);
MACRUM 0:119624335925 1986 if (resource) {
MACRUM 0:119624335925 1987 server_key_size = resource->value_length();
MACRUM 0:119624335925 1988 }
MACRUM 0:119624335925 1989 resource = _security->get_resource(M2MSecurity::Secretkey, instance_id);
MACRUM 0:119624335925 1990 if (resource) {
MACRUM 0:119624335925 1991 pkey_size = resource->value_length();
MACRUM 0:119624335925 1992 }
MACRUM 0:119624335925 1993
MACRUM 0:119624335925 1994 tr_info("M2MNsdlInterface::validate_security_object - Server URI /0/0: %s", address.c_str());
MACRUM 0:119624335925 1995 tr_info("M2MNsdlInterface::validate_security_object - is bs server /0/1: %" PRIu32, is_bs_server);
MACRUM 0:119624335925 1996 tr_info("M2MNsdlInterface::validate_security_object - Security Mode /0/2: %" PRIu32, sec_mode);
MACRUM 0:119624335925 1997 tr_info("M2MNsdlInterface::validate_security_object - Public key size /0/3: %" PRIu32, public_key_size);
MACRUM 0:119624335925 1998 tr_info("M2MNsdlInterface::validate_security_object - Server Public key size /0/4: %" PRIu32, server_key_size);
MACRUM 0:119624335925 1999 tr_info("M2MNsdlInterface::validate_security_object - Secret key size /0/5: %" PRIu32, pkey_size);
MACRUM 0:119624335925 2000 if (address.empty()) {
MACRUM 0:119624335925 2001 return false;
MACRUM 0:119624335925 2002 }
MACRUM 0:119624335925 2003 // Only NoSec and Certificate modes are supported
MACRUM 0:119624335925 2004 if (M2MSecurity::Certificate == sec_mode) {
MACRUM 0:119624335925 2005 if (!public_key_size || !server_key_size || !pkey_size) {
MACRUM 0:119624335925 2006 return false;
MACRUM 0:119624335925 2007 }
MACRUM 0:119624335925 2008 } else if (M2MSecurity::NoSecurity != sec_mode){
MACRUM 0:119624335925 2009 return false;
MACRUM 0:119624335925 2010 }
MACRUM 0:119624335925 2011 }
MACRUM 0:119624335925 2012 #endif
MACRUM 0:119624335925 2013 return valid;
MACRUM 0:119624335925 2014 }
MACRUM 0:119624335925 2015
MACRUM 0:119624335925 2016
MACRUM 0:119624335925 2017 void M2MNsdlInterface::handle_bootstrap_error(const char *reason, bool wait)
MACRUM 0:119624335925 2018 {
MACRUM 0:119624335925 2019 tr_error("M2MNsdlInterface::handle_bootstrap_error(%s)",reason);
MACRUM 0:119624335925 2020 _identity_accepted = false;
MACRUM 0:119624335925 2021 if (_security) {
MACRUM 0:119624335925 2022 int32_t m2m_id = _security->get_security_instance_id(M2MSecurity::M2MServer);
MACRUM 0:119624335925 2023 if (m2m_id >= 0) {
MACRUM 0:119624335925 2024 _security->remove_object_instance(m2m_id);
MACRUM 0:119624335925 2025 }
MACRUM 0:119624335925 2026 }
MACRUM 0:119624335925 2027
MACRUM 0:119624335925 2028 if (wait) {
MACRUM 0:119624335925 2029 _observer.bootstrap_error_wait(reason);
MACRUM 0:119624335925 2030 } else {
MACRUM 0:119624335925 2031 _observer.bootstrap_error(reason);
MACRUM 0:119624335925 2032 }
MACRUM 0:119624335925 2033 }
MACRUM 0:119624335925 2034
MACRUM 0:119624335925 2035 const String& M2MNsdlInterface::endpoint_name() const
MACRUM 0:119624335925 2036 {
MACRUM 0:119624335925 2037 return _endpoint_name;
MACRUM 0:119624335925 2038 }
MACRUM 0:119624335925 2039
MACRUM 0:119624335925 2040 const String M2MNsdlInterface::internal_endpoint_name() const
MACRUM 0:119624335925 2041 {
MACRUM 0:119624335925 2042 String iep("");
MACRUM 0:119624335925 2043 if (_nsdl_handle->ep_information_ptr->location_ptr) {
MACRUM 0:119624335925 2044 String temp((const char*)_nsdl_handle->ep_information_ptr->location_ptr,
MACRUM 0:119624335925 2045 _nsdl_handle->ep_information_ptr->location_len);
MACRUM 0:119624335925 2046 // Get last part of the location path.
MACRUM 0:119624335925 2047 // In mbed Cloud environment full path is /rd/accountid/internal_endpoint
MACRUM 0:119624335925 2048 int location = temp.find_last_of('/') + 1;
MACRUM 0:119624335925 2049 iep.append_raw((const char*)_nsdl_handle->ep_information_ptr->location_ptr + location,
MACRUM 0:119624335925 2050 _nsdl_handle->ep_information_ptr->location_len - location);
MACRUM 0:119624335925 2051 }
MACRUM 0:119624335925 2052 return iep;
MACRUM 0:119624335925 2053 }
MACRUM 0:119624335925 2054
MACRUM 0:119624335925 2055 void M2MNsdlInterface::change_operation_mode(M2MObject *object, M2MBase::Operation operation)
MACRUM 0:119624335925 2056 {
MACRUM 0:119624335925 2057 M2MObjectInstanceList instances = object->instances();
MACRUM 0:119624335925 2058 M2MObjectInstanceList::const_iterator inst = instances.begin();
MACRUM 0:119624335925 2059 for (; inst != instances.end(); inst++ ) {
MACRUM 0:119624335925 2060 (*inst)->set_operation(operation);
MACRUM 0:119624335925 2061 M2MResourceList list = (*inst)->resources();
MACRUM 0:119624335925 2062 if(!list.empty()) {
MACRUM 0:119624335925 2063 M2MResourceList::const_iterator it;
MACRUM 0:119624335925 2064 it = list.begin();
MACRUM 0:119624335925 2065 for ( ; it != list.end(); it++ ) {
MACRUM 0:119624335925 2066 (*it)->set_operation(operation);
MACRUM 0:119624335925 2067 }
MACRUM 0:119624335925 2068 }
MACRUM 0:119624335925 2069 }
MACRUM 0:119624335925 2070 }
MACRUM 0:119624335925 2071
MACRUM 0:119624335925 2072 void M2MNsdlInterface::set_server_address(const char* server_address)
MACRUM 0:119624335925 2073 {
MACRUM 0:119624335925 2074 free(_server_address);
MACRUM 0:119624335925 2075 _server_address = M2MBase::alloc_string_copy(server_address);
MACRUM 0:119624335925 2076 }
MACRUM 0:119624335925 2077
MACRUM 0:119624335925 2078 M2MTimer &M2MNsdlInterface::get_nsdl_execution_timer()
MACRUM 0:119624335925 2079 {
MACRUM 0:119624335925 2080 return _nsdl_exceution_timer;
MACRUM 0:119624335925 2081 }
MACRUM 0:119624335925 2082
MACRUM 0:119624335925 2083 bool M2MNsdlInterface::get_unregister_ongoing() const
MACRUM 0:119624335925 2084 {
MACRUM 0:119624335925 2085 return _unregister_ongoing;
MACRUM 0:119624335925 2086 }
MACRUM 0:119624335925 2087
MACRUM 0:119624335925 2088 bool M2MNsdlInterface::parse_and_send_uri_query_parameters()
MACRUM 0:119624335925 2089 {
MACRUM 0:119624335925 2090 bool msg_sent = false;
MACRUM 0:119624335925 2091 char *address_copy = M2MBase::alloc_string_copy(_server_address);
MACRUM 0:119624335925 2092 if (address_copy) {
MACRUM 0:119624335925 2093 char* query = query_string(_server_address);
MACRUM 0:119624335925 2094 if (query != NULL) {
MACRUM 0:119624335925 2095 int param_count = query_param_count(query);
MACRUM 0:119624335925 2096 if (param_count) {
MACRUM 0:119624335925 2097 char* uri_query_params[MAX_QUERY_COUNT] = {};
MACRUM 0:119624335925 2098 if (uri_query_parameters(query, uri_query_params, 0)) {
MACRUM 0:119624335925 2099 uri_query_parameters((char*)MCC_VERSION, uri_query_params, param_count);
MACRUM 0:119624335925 2100 param_count += query_param_count((char*)MCC_VERSION);
MACRUM 0:119624335925 2101
MACRUM 0:119624335925 2102 sn_nsdl_clear_coap_resending_queue(_nsdl_handle);
MACRUM 0:119624335925 2103 msg_sent = sn_nsdl_register_endpoint(_nsdl_handle,_endpoint,uri_query_params, param_count) != 0;
MACRUM 0:119624335925 2104 }
MACRUM 0:119624335925 2105 free(_server_address);
MACRUM 0:119624335925 2106 _server_address = M2MBase::alloc_string_copy(address_copy);
MACRUM 0:119624335925 2107 }
MACRUM 0:119624335925 2108 }
MACRUM 0:119624335925 2109 free(address_copy);
MACRUM 0:119624335925 2110 }
MACRUM 0:119624335925 2111 return msg_sent;
MACRUM 0:119624335925 2112 }
MACRUM 0:119624335925 2113
MACRUM 0:119624335925 2114 void M2MNsdlInterface::claim_mutex()
MACRUM 0:119624335925 2115 {
MACRUM 0:119624335925 2116 _connection_handler.claim_mutex();
MACRUM 0:119624335925 2117 }
MACRUM 0:119624335925 2118
MACRUM 0:119624335925 2119 void M2MNsdlInterface::release_mutex()
MACRUM 0:119624335925 2120 {
MACRUM 0:119624335925 2121 _connection_handler.release_mutex();
MACRUM 0:119624335925 2122 }
MACRUM 0:119624335925 2123
MACRUM 0:119624335925 2124 void M2MNsdlInterface::start_nsdl_execution_timer()
MACRUM 0:119624335925 2125 {
MACRUM 0:119624335925 2126 tr_debug("M2MNsdlInterface::start_nsdl_execution_timer");
MACRUM 0:119624335925 2127 _nsdl_exceution_timer_running = true;
MACRUM 0:119624335925 2128 _nsdl_exceution_timer.stop_timer();
MACRUM 0:119624335925 2129 _nsdl_exceution_timer.start_timer(ONE_SECOND_TIMER * 1000,
MACRUM 0:119624335925 2130 M2MTimerObserver::NsdlExecution,
MACRUM 0:119624335925 2131 false);
MACRUM 0:119624335925 2132 }
MACRUM 0:119624335925 2133
MACRUM 0:119624335925 2134 void M2MNsdlInterface::handle_pending_notifications(bool clear)
MACRUM 0:119624335925 2135 {
MACRUM 0:119624335925 2136 // TODO! This logic does not work if there are multiple pending notifications.
MACRUM 0:119624335925 2137 // CoAP resend queue will fill up and message sending will fail.
MACRUM 0:119624335925 2138 // Need to have a better queuing system.
MACRUM 0:119624335925 2139 if(!_object_list.empty()) {
MACRUM 0:119624335925 2140 M2MObjectList::const_iterator object_iterator;
MACRUM 0:119624335925 2141 object_iterator = _object_list.begin();
MACRUM 0:119624335925 2142 // Object level
MACRUM 0:119624335925 2143 for ( ; object_iterator != _object_list.end(); object_iterator++ ) {
MACRUM 0:119624335925 2144 const M2MObjectInstanceList &object_instance_list = (*object_iterator)->instances();
MACRUM 0:119624335925 2145 // Clears all the pending notifications
MACRUM 0:119624335925 2146 if (clear) {
MACRUM 0:119624335925 2147 (*object_iterator)->clear_notification_delivery_status();
MACRUM 0:119624335925 2148 // Send all the pending notifications
MACRUM 0:119624335925 2149 } else {
MACRUM 0:119624335925 2150 M2MReportHandler* reporter = (*object_iterator)->report_handler();
MACRUM 0:119624335925 2151 if (((*object_iterator)->get_notification_delivery_status() == NOTIFICATION_STATUS_SENT ||
MACRUM 0:119624335925 2152 (*object_iterator)->get_notification_delivery_status() == NOTIFICATION_STATUS_SEND_FAILED) &&
MACRUM 0:119624335925 2153 reporter &&
MACRUM 0:119624335925 2154 reporter->is_under_observation()) {
MACRUM 0:119624335925 2155 // Send the whole object in case of resend
MACRUM 0:119624335925 2156 m2m::Vector<uint16_t> changed_instance_ids;
MACRUM 0:119624335925 2157 send_object_observation((*object_iterator),
MACRUM 0:119624335925 2158 reporter->observation_number(),
MACRUM 0:119624335925 2159 changed_instance_ids, true, true);
MACRUM 0:119624335925 2160 }
MACRUM 0:119624335925 2161 }
MACRUM 0:119624335925 2162
MACRUM 0:119624335925 2163 if(!object_instance_list.empty()) {
MACRUM 0:119624335925 2164 M2MObjectInstanceList::const_iterator object_instance_iterator;
MACRUM 0:119624335925 2165 object_instance_iterator = object_instance_list.begin();
MACRUM 0:119624335925 2166 // Object instance level
MACRUM 0:119624335925 2167 for ( ; object_instance_iterator != object_instance_list.end(); object_instance_iterator++ ) {
MACRUM 0:119624335925 2168 // Clears all the pending notifications
MACRUM 0:119624335925 2169 if (clear) {
MACRUM 0:119624335925 2170 (*object_instance_iterator)->clear_notification_delivery_status();
MACRUM 0:119624335925 2171 // Send all the pending notifications
MACRUM 0:119624335925 2172 } else {
MACRUM 0:119624335925 2173 M2MReportHandler* reporter = (*object_instance_iterator)->report_handler();
MACRUM 0:119624335925 2174 if (((*object_instance_iterator)->get_notification_delivery_status() == NOTIFICATION_STATUS_SENT ||
MACRUM 0:119624335925 2175 (*object_instance_iterator)->get_notification_delivery_status() == NOTIFICATION_STATUS_SEND_FAILED) &&
MACRUM 0:119624335925 2176 reporter &&
MACRUM 0:119624335925 2177 reporter->is_under_observation()) {
MACRUM 0:119624335925 2178 send_object_instance_observation((*object_instance_iterator), reporter->observation_number(), true);
MACRUM 0:119624335925 2179 }
MACRUM 0:119624335925 2180 }
MACRUM 0:119624335925 2181 const M2MResourceList &resource_list = (*object_instance_iterator)->resources();
MACRUM 0:119624335925 2182 if(!resource_list.empty()) {
MACRUM 0:119624335925 2183 M2MResourceList::const_iterator resource_iterator;
MACRUM 0:119624335925 2184 resource_iterator = resource_list.begin();
MACRUM 0:119624335925 2185 // Resource level
MACRUM 0:119624335925 2186 for ( ; resource_iterator != resource_list.end(); resource_iterator++) {
MACRUM 0:119624335925 2187 // Clears all the pending notifications
MACRUM 0:119624335925 2188 if (clear) {
MACRUM 0:119624335925 2189 (*resource_iterator)->clear_notification_delivery_status();
MACRUM 0:119624335925 2190 // Send all the pending notifications
MACRUM 0:119624335925 2191 } else {
MACRUM 0:119624335925 2192 M2MReportHandler* reporter = (*resource_iterator)->report_handler();
MACRUM 0:119624335925 2193 if (((*resource_iterator)->get_notification_delivery_status() == NOTIFICATION_STATUS_SENT ||
MACRUM 0:119624335925 2194 (*resource_iterator)->get_notification_delivery_status() == NOTIFICATION_STATUS_SEND_FAILED) &&
MACRUM 0:119624335925 2195 reporter &&
MACRUM 0:119624335925 2196 reporter->is_under_observation()) {
MACRUM 0:119624335925 2197 send_resource_observation( (*resource_iterator), reporter->observation_number(), true);
MACRUM 0:119624335925 2198 }
MACRUM 0:119624335925 2199 }
MACRUM 0:119624335925 2200 }
MACRUM 0:119624335925 2201 }
MACRUM 0:119624335925 2202 }
MACRUM 0:119624335925 2203 }
MACRUM 0:119624335925 2204 }
MACRUM 0:119624335925 2205 }
MACRUM 0:119624335925 2206 }
MACRUM 0:119624335925 2207
MACRUM 0:119624335925 2208 M2MSecurity* M2MNsdlInterface::get_security_object()
MACRUM 0:119624335925 2209 {
MACRUM 0:119624335925 2210 return _security;
MACRUM 0:119624335925 2211 }
MACRUM 0:119624335925 2212
MACRUM 0:119624335925 2213 void M2MNsdlInterface::update_trigger_callback(void */*argument*/)
MACRUM 0:119624335925 2214 {
MACRUM 0:119624335925 2215 if (lifetime_value_changed()) {
MACRUM 0:119624335925 2216 send_update_registration(_server->resource_value_int(M2MServer::Lifetime));
MACRUM 0:119624335925 2217 } else {
MACRUM 0:119624335925 2218 send_update_registration();
MACRUM 0:119624335925 2219 }
MACRUM 0:119624335925 2220 }
MACRUM 0:119624335925 2221
MACRUM 0:119624335925 2222 bool M2MNsdlInterface::lifetime_value_changed() const
MACRUM 0:119624335925 2223 {
MACRUM 0:119624335925 2224 uint64_t value = 0;
MACRUM 0:119624335925 2225 if (_endpoint && _endpoint->lifetime_ptr) {
MACRUM 0:119624335925 2226 value = atol((const char*)_endpoint->lifetime_ptr);
MACRUM 0:119624335925 2227 }
MACRUM 0:119624335925 2228 if (_server->resource_value_int(M2MServer::Lifetime) != value) {
MACRUM 0:119624335925 2229 return true;
MACRUM 0:119624335925 2230 }
MACRUM 0:119624335925 2231 return false;
MACRUM 0:119624335925 2232 }
MACRUM 0:119624335925 2233
MACRUM 0:119624335925 2234 void M2MNsdlInterface::execute_notification_delivery_status_cb(M2MBase* object, int32_t msgid)
MACRUM 0:119624335925 2235 {
MACRUM 0:119624335925 2236 if (msgid > 0) {
MACRUM 0:119624335925 2237 object->send_notification_delivery_status(*object, NOTIFICATION_STATUS_SENT);
MACRUM 0:119624335925 2238 object->set_notification_msgid(msgid);
MACRUM 0:119624335925 2239 } else if (msgid == SN_NSDL_RESEND_QUEUE_FULL) {
MACRUM 0:119624335925 2240 object->send_notification_delivery_status(*object, NOTIFICATION_STATUS_RESEND_QUEUE_FULL);
MACRUM 0:119624335925 2241 } else {
MACRUM 0:119624335925 2242 object->send_notification_delivery_status(*object, NOTIFICATION_STATUS_BUILD_ERROR);
MACRUM 0:119624335925 2243 }
MACRUM 0:119624335925 2244 }
MACRUM 0:119624335925 2245
MACRUM 0:119624335925 2246 uint8_t M2MNsdlInterface::find_auto_obs_token(const char *path, uint8_t *token) const
MACRUM 0:119624335925 2247 {
MACRUM 0:119624335925 2248 uint8_t token_len = 0;
MACRUM 0:119624335925 2249 const String name(path);
MACRUM 0:119624335925 2250 M2MBase *object = find_resource(name, 0);
MACRUM 0:119624335925 2251 if (object) {
MACRUM 0:119624335925 2252 object->get_observation_token(token, token_len);
MACRUM 0:119624335925 2253 }
MACRUM 0:119624335925 2254 return token_len;
MACRUM 0:119624335925 2255 }
MACRUM 0:119624335925 2256
MACRUM 0:119624335925 2257 bool M2MNsdlInterface::is_response_to_get_req(const sn_coap_hdr_s *coap_header, get_data_request_s &get_data)
MACRUM 0:119624335925 2258 {
MACRUM 0:119624335925 2259 // ns_list_foreach() replacement since it does not compile with IAR 7.x versions.
MACRUM 0:119624335925 2260 get_data_request_s *data = (get_data_request_s *)ns_list_get_first(&_get_request_list);
MACRUM 0:119624335925 2261 while (data) {
MACRUM 0:119624335925 2262 if (memcmp(coap_header->token_ptr, &data->msg_token, sizeof(data->msg_token)) == 0) {
MACRUM 0:119624335925 2263 get_data = *data;
MACRUM 0:119624335925 2264 return true;
MACRUM 0:119624335925 2265 }
MACRUM 0:119624335925 2266 data = (get_data_request_s *)ns_list_get_next(&_get_request_list, data);
MACRUM 0:119624335925 2267 }
MACRUM 0:119624335925 2268
MACRUM 0:119624335925 2269 return false;
MACRUM 0:119624335925 2270 }
MACRUM 0:119624335925 2271
MACRUM 0:119624335925 2272 void M2MNsdlInterface::free_get_request_list(const sn_coap_hdr_s *coap_header)
MACRUM 0:119624335925 2273 {
MACRUM 0:119624335925 2274 // Clean up whole list
MACRUM 0:119624335925 2275 if (coap_header == NULL) {
MACRUM 0:119624335925 2276 // ns_list_foreach() replacement since it does not compile with IAR 7.x versions.
MACRUM 0:119624335925 2277 while (!ns_list_is_empty(&_get_request_list)) {
MACRUM 0:119624335925 2278 get_data_request_s* data = (get_data_request_s*)ns_list_get_first(&_get_request_list);
MACRUM 0:119624335925 2279 ns_list_remove(&_get_request_list, data);
MACRUM 0:119624335925 2280 memory_free(data->uri_path);
MACRUM 0:119624335925 2281 memory_free(data);
MACRUM 0:119624335925 2282 }
MACRUM 0:119624335925 2283
MACRUM 0:119624335925 2284 // Clean just one item from the list
MACRUM 0:119624335925 2285 } else {
MACRUM 0:119624335925 2286 // ns_list_foreach() replacement since it does not compile with IAR 7.x versions.
MACRUM 0:119624335925 2287 get_data_request_s *data = (get_data_request_s *)ns_list_get_first(&_get_request_list);
MACRUM 0:119624335925 2288 while (data) {
MACRUM 0:119624335925 2289 if (memcmp(coap_header->token_ptr, &data->msg_token, sizeof(data->msg_token)) == 0) {
MACRUM 0:119624335925 2290 ns_list_remove(&_get_request_list, data);
MACRUM 0:119624335925 2291 memory_free(data->uri_path);
MACRUM 0:119624335925 2292 memory_free(data);
MACRUM 0:119624335925 2293 return;
MACRUM 0:119624335925 2294 }
MACRUM 0:119624335925 2295 data = (get_data_request_s *)ns_list_get_next(&_get_request_list, data);
MACRUM 0:119624335925 2296 }
MACRUM 0:119624335925 2297 }
MACRUM 0:119624335925 2298 }