Toyomasa Watarai
/
Mbed-example-WS-W27
simple-mbed-cloud-client/mbed-cloud-client/mbed-client/source/m2mnsdlinterface.cpp@0:119624335925, 2018-06-30 (annotated)
- Committer:
- MACRUM
- Date:
- Sat Jun 30 01:40:30 2018 +0000
- Revision:
- 0:119624335925
Initial commit
Who changed what in which revision?
User | Revision | Line number | New 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 | } |