Example

Dependencies:   FXAS21002 FXOS8700Q

Committer:
maygup01
Date:
Tue Nov 19 09:49:38 2019 +0000
Revision:
0:11cc2b7889af
Example

Who changed what in which revision?

UserRevisionLine numberNew contents of line
maygup01 0:11cc2b7889af 1 /*
maygup01 0:11cc2b7889af 2 * Copyright (c) 2015 ARM Limited. All rights reserved.
maygup01 0:11cc2b7889af 3 * SPDX-License-Identifier: Apache-2.0
maygup01 0:11cc2b7889af 4 * Licensed under the Apache License, Version 2.0 (the License); you may
maygup01 0:11cc2b7889af 5 * not use this file except in compliance with the License.
maygup01 0:11cc2b7889af 6 * You may obtain a copy of the License at
maygup01 0:11cc2b7889af 7 *
maygup01 0:11cc2b7889af 8 * http://www.apache.org/licenses/LICENSE-2.0
maygup01 0:11cc2b7889af 9 *
maygup01 0:11cc2b7889af 10 * Unless required by applicable law or agreed to in writing, software
maygup01 0:11cc2b7889af 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
maygup01 0:11cc2b7889af 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
maygup01 0:11cc2b7889af 13 * See the License for the specific language governing permissions and
maygup01 0:11cc2b7889af 14 * limitations under the License.
maygup01 0:11cc2b7889af 15 */
maygup01 0:11cc2b7889af 16
maygup01 0:11cc2b7889af 17 // Needed for PRIu64 on FreeRTOS
maygup01 0:11cc2b7889af 18 #include <stdio.h>
maygup01 0:11cc2b7889af 19 // Note: this macro is needed on armcc to get the the PRI*32 macros
maygup01 0:11cc2b7889af 20 // from inttypes.h in a C++ code.
maygup01 0:11cc2b7889af 21 #ifndef __STDC_FORMAT_MACROS
maygup01 0:11cc2b7889af 22 #define __STDC_FORMAT_MACROS
maygup01 0:11cc2b7889af 23 #endif
maygup01 0:11cc2b7889af 24 #include <inttypes.h>
maygup01 0:11cc2b7889af 25
maygup01 0:11cc2b7889af 26 #include <assert.h>
maygup01 0:11cc2b7889af 27 #include <stdlib.h>
maygup01 0:11cc2b7889af 28 #include <stdio.h>
maygup01 0:11cc2b7889af 29 #include <time.h>
maygup01 0:11cc2b7889af 30 #include "include/m2minterfaceimpl.h"
maygup01 0:11cc2b7889af 31 #include "include/eventdata.h"
maygup01 0:11cc2b7889af 32 #include "mbed-client/m2minterfaceobserver.h"
maygup01 0:11cc2b7889af 33 #include "mbed-client/m2mconnectionhandler.h"
maygup01 0:11cc2b7889af 34 #include "mbed-client/m2mconnectionsecurity.h"
maygup01 0:11cc2b7889af 35 #include "include/m2mnsdlinterface.h"
maygup01 0:11cc2b7889af 36 #include "mbed-client/m2msecurity.h"
maygup01 0:11cc2b7889af 37 #include "mbed-client/m2mtimer.h"
maygup01 0:11cc2b7889af 38 #include "mbed-trace/mbed_trace.h"
maygup01 0:11cc2b7889af 39 #include "randLIB.h"
maygup01 0:11cc2b7889af 40
maygup01 0:11cc2b7889af 41 #include <stdlib.h>
maygup01 0:11cc2b7889af 42
maygup01 0:11cc2b7889af 43 #define TRACE_GROUP "mClt"
maygup01 0:11cc2b7889af 44
maygup01 0:11cc2b7889af 45 #define RESOLVE_SEC_MODE(mode) ((mode == M2MInterface::TCP || mode == M2MInterface::TCP_QUEUE) ? M2MConnectionSecurity::TLS : M2MConnectionSecurity::DTLS)
maygup01 0:11cc2b7889af 46
maygup01 0:11cc2b7889af 47 M2MInterfaceImpl::M2MInterfaceImpl(M2MInterfaceObserver& observer,
maygup01 0:11cc2b7889af 48 const String &ep_name,
maygup01 0:11cc2b7889af 49 const String &ep_type,
maygup01 0:11cc2b7889af 50 const int32_t l_time,
maygup01 0:11cc2b7889af 51 const uint16_t listen_port,
maygup01 0:11cc2b7889af 52 const String &dmn,
maygup01 0:11cc2b7889af 53 M2MInterface::BindingMode mode,
maygup01 0:11cc2b7889af 54 M2MInterface::NetworkStack stack,
maygup01 0:11cc2b7889af 55 const String &con_addr)
maygup01 0:11cc2b7889af 56 : _event_data(NULL),
maygup01 0:11cc2b7889af 57 _registration_flow_timer(NULL),
maygup01 0:11cc2b7889af 58 _server_port(0),
maygup01 0:11cc2b7889af 59 _listen_port(listen_port),
maygup01 0:11cc2b7889af 60 _life_time(l_time),
maygup01 0:11cc2b7889af 61 _register_server(NULL),
maygup01 0:11cc2b7889af 62 _queue_sleep_timer(*this),
maygup01 0:11cc2b7889af 63 _retry_timer(*this),
maygup01 0:11cc2b7889af 64 _callback_handler(NULL),
maygup01 0:11cc2b7889af 65 _max_states( STATE_MAX_STATES ),
maygup01 0:11cc2b7889af 66 _event_ignored(false),
maygup01 0:11cc2b7889af 67 _event_generated(false),
maygup01 0:11cc2b7889af 68 _reconnecting(false),
maygup01 0:11cc2b7889af 69 _retry_timer_expired(false),
maygup01 0:11cc2b7889af 70 _bootstrapped(true), // True as default to get it working with connector only configuration
maygup01 0:11cc2b7889af 71 _bootstrap_finished(false),
maygup01 0:11cc2b7889af 72 _queue_mode_timer_ongoing(false),
maygup01 0:11cc2b7889af 73 _current_state(0),
maygup01 0:11cc2b7889af 74 _binding_mode(mode),
maygup01 0:11cc2b7889af 75 _reconnection_state(M2MInterfaceImpl::None),
maygup01 0:11cc2b7889af 76 _observer(observer),
maygup01 0:11cc2b7889af 77 _security_connection( new M2MConnectionSecurity( RESOLVE_SEC_MODE(mode) )),
maygup01 0:11cc2b7889af 78 _connection_handler(*this, _security_connection, mode, stack),
maygup01 0:11cc2b7889af 79 _nsdl_interface(*this, _connection_handler),
maygup01 0:11cc2b7889af 80 _security(NULL)
maygup01 0:11cc2b7889af 81 {
maygup01 0:11cc2b7889af 82 tr_debug("M2MInterfaceImpl::M2MInterfaceImpl() -IN");
maygup01 0:11cc2b7889af 83 //TODO:Increase the range from 1 to 100 seconds
maygup01 0:11cc2b7889af 84 randLIB_seed_random();
maygup01 0:11cc2b7889af 85 // Range is from 2 to 10
maygup01 0:11cc2b7889af 86 _initial_reconnection_time = randLIB_get_random_in_range(2, 10);
maygup01 0:11cc2b7889af 87
maygup01 0:11cc2b7889af 88 tr_info("M2MInterfaceImpl::M2MInterfaceImpl() initial random time %d\n", _initial_reconnection_time);
maygup01 0:11cc2b7889af 89 _reconnection_time = _initial_reconnection_time;
maygup01 0:11cc2b7889af 90
maygup01 0:11cc2b7889af 91 #ifndef DISABLE_ERROR_DESCRIPTION
maygup01 0:11cc2b7889af 92 memset(_error_description, 0, sizeof(_error_description));
maygup01 0:11cc2b7889af 93 #endif
maygup01 0:11cc2b7889af 94
maygup01 0:11cc2b7889af 95 _nsdl_interface.create_endpoint(ep_name,
maygup01 0:11cc2b7889af 96 ep_type,
maygup01 0:11cc2b7889af 97 _life_time,
maygup01 0:11cc2b7889af 98 dmn,
maygup01 0:11cc2b7889af 99 (uint8_t)_binding_mode,
maygup01 0:11cc2b7889af 100 con_addr);
maygup01 0:11cc2b7889af 101
maygup01 0:11cc2b7889af 102 //Here we must use TCP still
maygup01 0:11cc2b7889af 103 _connection_handler.bind_connection(_listen_port);
maygup01 0:11cc2b7889af 104
maygup01 0:11cc2b7889af 105 // We need this timer only in case of TCP
maygup01 0:11cc2b7889af 106 if (_binding_mode == M2MInterface::TCP ||
maygup01 0:11cc2b7889af 107 _binding_mode == M2MInterface::TCP_QUEUE ) {
maygup01 0:11cc2b7889af 108 _registration_flow_timer = new M2MTimer(*this);
maygup01 0:11cc2b7889af 109 }
maygup01 0:11cc2b7889af 110 tr_debug("M2MInterfaceImpl::M2MInterfaceImpl() -OUT");
maygup01 0:11cc2b7889af 111 }
maygup01 0:11cc2b7889af 112
maygup01 0:11cc2b7889af 113
maygup01 0:11cc2b7889af 114 M2MInterfaceImpl::~M2MInterfaceImpl()
maygup01 0:11cc2b7889af 115 {
maygup01 0:11cc2b7889af 116 tr_debug("M2MInterfaceImpl::~M2MInterfaceImpl() - IN");
maygup01 0:11cc2b7889af 117 delete _registration_flow_timer;
maygup01 0:11cc2b7889af 118 _security_connection = NULL;
maygup01 0:11cc2b7889af 119 tr_debug("M2MInterfaceImpl::~M2MInterfaceImpl() - OUT");
maygup01 0:11cc2b7889af 120 }
maygup01 0:11cc2b7889af 121
maygup01 0:11cc2b7889af 122 void M2MInterfaceImpl::bootstrap(M2MSecurity *security)
maygup01 0:11cc2b7889af 123 {
maygup01 0:11cc2b7889af 124 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 125 tr_debug("M2MInterfaceImpl::bootstrap - IN - current state %d", _current_state);
maygup01 0:11cc2b7889af 126 _retry_timer.stop_timer();
maygup01 0:11cc2b7889af 127 _security = NULL;
maygup01 0:11cc2b7889af 128 if(!security) {
maygup01 0:11cc2b7889af 129 set_error_description(ERROR_REASON_1);
maygup01 0:11cc2b7889af 130 _observer.error(M2MInterface::InvalidParameters);
maygup01 0:11cc2b7889af 131 return;
maygup01 0:11cc2b7889af 132 }
maygup01 0:11cc2b7889af 133 // Transition to a new state based upon
maygup01 0:11cc2b7889af 134 // the current state of the state machine
maygup01 0:11cc2b7889af 135 _connection_handler.claim_mutex();
maygup01 0:11cc2b7889af 136 M2MSecurityData data;
maygup01 0:11cc2b7889af 137 data._object = security;
maygup01 0:11cc2b7889af 138 BEGIN_TRANSITION_MAP // - Current State -
maygup01 0:11cc2b7889af 139 TRANSITION_MAP_ENTRY (STATE_BOOTSTRAP) // state_idle
maygup01 0:11cc2b7889af 140 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap
maygup01 0:11cc2b7889af 141 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state__bootstrap_address_resolved
maygup01 0:11cc2b7889af 142 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_resource_created
maygup01 0:11cc2b7889af 143 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_wait
maygup01 0:11cc2b7889af 144 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_error_wait
maygup01 0:11cc2b7889af 145 TRANSITION_MAP_ENTRY (STATE_BOOTSTRAP) // state_bootstrapped
maygup01 0:11cc2b7889af 146 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register
maygup01 0:11cc2b7889af 147 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_address_resolved
maygup01 0:11cc2b7889af 148 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_registered
maygup01 0:11cc2b7889af 149 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_update_registration
maygup01 0:11cc2b7889af 150 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregister
maygup01 0:11cc2b7889af 151 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregistered
maygup01 0:11cc2b7889af 152 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_sending_coap_data
maygup01 0:11cc2b7889af 153 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_sent
maygup01 0:11cc2b7889af 154 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_received
maygup01 0:11cc2b7889af 155 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_processing_coap_data
maygup01 0:11cc2b7889af 156 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_processed
maygup01 0:11cc2b7889af 157 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_waiting
maygup01 0:11cc2b7889af 158 END_TRANSITION_MAP(&data)
maygup01 0:11cc2b7889af 159 if(_event_ignored) {
maygup01 0:11cc2b7889af 160 _event_ignored = false;
maygup01 0:11cc2b7889af 161 set_error_description(ERROR_REASON_2);
maygup01 0:11cc2b7889af 162 _observer.error(M2MInterface::NotAllowed);
maygup01 0:11cc2b7889af 163 }
maygup01 0:11cc2b7889af 164 _connection_handler.release_mutex();
maygup01 0:11cc2b7889af 165 tr_debug("M2MInterfaceImpl::bootstrap - OUT");
maygup01 0:11cc2b7889af 166 #else
maygup01 0:11cc2b7889af 167 set_error_description(ERROR_REASON_3);
maygup01 0:11cc2b7889af 168 _observer.error(M2MInterface::NotAllowed);
maygup01 0:11cc2b7889af 169 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 170
maygup01 0:11cc2b7889af 171 }
maygup01 0:11cc2b7889af 172
maygup01 0:11cc2b7889af 173 void M2MInterfaceImpl::cancel_bootstrap()
maygup01 0:11cc2b7889af 174 {
maygup01 0:11cc2b7889af 175 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 176 //TODO: Do we need this ?
maygup01 0:11cc2b7889af 177 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 178 }
maygup01 0:11cc2b7889af 179
maygup01 0:11cc2b7889af 180 void M2MInterfaceImpl::finish_bootstrap()
maygup01 0:11cc2b7889af 181 {
maygup01 0:11cc2b7889af 182 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 183 tr_debug("M2MInterfaceImpl::finish_bootstrap");
maygup01 0:11cc2b7889af 184 _security = NULL;
maygup01 0:11cc2b7889af 185 bootstrap_done();
maygup01 0:11cc2b7889af 186 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 187 }
maygup01 0:11cc2b7889af 188
maygup01 0:11cc2b7889af 189 void M2MInterfaceImpl::register_object(M2MSecurity *security, const M2MObjectList &object_list)
maygup01 0:11cc2b7889af 190 {
maygup01 0:11cc2b7889af 191 M2MBaseList list;
maygup01 0:11cc2b7889af 192 M2MObjectList::const_iterator it = object_list.begin();
maygup01 0:11cc2b7889af 193 for ( ; it != object_list.end(); it++ ) {
maygup01 0:11cc2b7889af 194 list.push_back(*it);
maygup01 0:11cc2b7889af 195 }
maygup01 0:11cc2b7889af 196 register_object(security, list);
maygup01 0:11cc2b7889af 197 }
maygup01 0:11cc2b7889af 198
maygup01 0:11cc2b7889af 199 void M2MInterfaceImpl::register_object(M2MSecurity *security, const M2MBaseList &list)
maygup01 0:11cc2b7889af 200 {
maygup01 0:11cc2b7889af 201 tr_debug("M2MInterfaceImpl::register_object - IN - current state %d", _current_state);
maygup01 0:11cc2b7889af 202 if(!security) {
maygup01 0:11cc2b7889af 203 set_error_description(ERROR_REASON_4);
maygup01 0:11cc2b7889af 204 _observer.error(M2MInterface::InvalidParameters);
maygup01 0:11cc2b7889af 205 return;
maygup01 0:11cc2b7889af 206 }
maygup01 0:11cc2b7889af 207 // Transition to a new state based upon
maygup01 0:11cc2b7889af 208 // the current state of the state machine
maygup01 0:11cc2b7889af 209 //TODO: manage register object in a list.
maygup01 0:11cc2b7889af 210 _connection_handler.claim_mutex();
maygup01 0:11cc2b7889af 211 _register_server = security;
maygup01 0:11cc2b7889af 212 M2MRegisterData data;
maygup01 0:11cc2b7889af 213 data._object = security;
maygup01 0:11cc2b7889af 214 data._base_list = list;
maygup01 0:11cc2b7889af 215 BEGIN_TRANSITION_MAP // - Current State -
maygup01 0:11cc2b7889af 216 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_idle
maygup01 0:11cc2b7889af 217 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap
maygup01 0:11cc2b7889af 218 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state__bootstrap_address_resolved
maygup01 0:11cc2b7889af 219 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_resource_created
maygup01 0:11cc2b7889af 220 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_wait
maygup01 0:11cc2b7889af 221 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_error_wait
maygup01 0:11cc2b7889af 222 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_bootstrapped
maygup01 0:11cc2b7889af 223 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register
maygup01 0:11cc2b7889af 224 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_address_resolved
maygup01 0:11cc2b7889af 225 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_registered
maygup01 0:11cc2b7889af 226 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_update_registration
maygup01 0:11cc2b7889af 227 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregister
maygup01 0:11cc2b7889af 228 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregistered
maygup01 0:11cc2b7889af 229 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_sending_coap_data
maygup01 0:11cc2b7889af 230 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_sent
maygup01 0:11cc2b7889af 231 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_received
maygup01 0:11cc2b7889af 232 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_processing_coap_data
maygup01 0:11cc2b7889af 233 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_processed
maygup01 0:11cc2b7889af 234 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_waiting
maygup01 0:11cc2b7889af 235 END_TRANSITION_MAP(&data)
maygup01 0:11cc2b7889af 236 if(_event_ignored) {
maygup01 0:11cc2b7889af 237 _event_ignored = false;
maygup01 0:11cc2b7889af 238 set_error_description(ERROR_REASON_5);
maygup01 0:11cc2b7889af 239 _observer.error(M2MInterface::NotAllowed);
maygup01 0:11cc2b7889af 240 }
maygup01 0:11cc2b7889af 241 _connection_handler.release_mutex();
maygup01 0:11cc2b7889af 242 tr_debug("M2MInterfaceImpl::register_object - OUT");
maygup01 0:11cc2b7889af 243 }
maygup01 0:11cc2b7889af 244
maygup01 0:11cc2b7889af 245 void M2MInterfaceImpl::update_registration(M2MSecurity *security_object, const uint32_t lifetime)
maygup01 0:11cc2b7889af 246 {
maygup01 0:11cc2b7889af 247 tr_debug("M2MInterfaceImpl::update_registration()");
maygup01 0:11cc2b7889af 248 _connection_handler.claim_mutex();
maygup01 0:11cc2b7889af 249 M2MUpdateRegisterData data;
maygup01 0:11cc2b7889af 250 data._object = security_object;
maygup01 0:11cc2b7889af 251 data._lifetime = lifetime;
maygup01 0:11cc2b7889af 252 start_register_update(&data);
maygup01 0:11cc2b7889af 253 _connection_handler.release_mutex();
maygup01 0:11cc2b7889af 254 }
maygup01 0:11cc2b7889af 255
maygup01 0:11cc2b7889af 256 void M2MInterfaceImpl::update_registration(M2MSecurity *security_object,
maygup01 0:11cc2b7889af 257 const M2MObjectList &object_list,
maygup01 0:11cc2b7889af 258 const uint32_t lifetime)
maygup01 0:11cc2b7889af 259 {
maygup01 0:11cc2b7889af 260 tr_debug("M2MInterfaceImpl::update_registration - with object list");
maygup01 0:11cc2b7889af 261 _connection_handler.claim_mutex();
maygup01 0:11cc2b7889af 262 M2MBaseList list;
maygup01 0:11cc2b7889af 263 M2MObjectList::const_iterator it = object_list.begin();
maygup01 0:11cc2b7889af 264 for ( ; it != object_list.end(); it++ ) {
maygup01 0:11cc2b7889af 265 list.push_back(*it);
maygup01 0:11cc2b7889af 266 }
maygup01 0:11cc2b7889af 267 update_registration(security_object, list, lifetime);
maygup01 0:11cc2b7889af 268 _connection_handler.release_mutex();
maygup01 0:11cc2b7889af 269 }
maygup01 0:11cc2b7889af 270
maygup01 0:11cc2b7889af 271 void M2MInterfaceImpl::update_registration(M2MSecurity *security_object,
maygup01 0:11cc2b7889af 272 const M2MBaseList &list,
maygup01 0:11cc2b7889af 273 const uint32_t lifetime)
maygup01 0:11cc2b7889af 274 {
maygup01 0:11cc2b7889af 275 tr_debug("M2MInterfaceImpl::update_registration(M2MSecurity *security_object, const M2MObjectList &object_list, const uint32_t lifetime)");
maygup01 0:11cc2b7889af 276 _connection_handler.claim_mutex();
maygup01 0:11cc2b7889af 277 M2MUpdateRegisterData data;
maygup01 0:11cc2b7889af 278 data._object = security_object;
maygup01 0:11cc2b7889af 279 data._lifetime = lifetime;
maygup01 0:11cc2b7889af 280 data._base_list = list;
maygup01 0:11cc2b7889af 281 start_register_update(&data);
maygup01 0:11cc2b7889af 282 _connection_handler.release_mutex();
maygup01 0:11cc2b7889af 283 }
maygup01 0:11cc2b7889af 284
maygup01 0:11cc2b7889af 285 void M2MInterfaceImpl::unregister_object(M2MSecurity* /*security*/)
maygup01 0:11cc2b7889af 286 {
maygup01 0:11cc2b7889af 287 tr_debug("M2MInterfaceImpl::unregister_object - IN - current state %d", _current_state);
maygup01 0:11cc2b7889af 288 if (_nsdl_interface.is_unregister_ongoing()) {
maygup01 0:11cc2b7889af 289 set_error_description(ERROR_REASON_27);
maygup01 0:11cc2b7889af 290 _observer.error(M2MInterface::NotAllowed);
maygup01 0:11cc2b7889af 291 return;
maygup01 0:11cc2b7889af 292 }
maygup01 0:11cc2b7889af 293
maygup01 0:11cc2b7889af 294 _connection_handler.claim_mutex();
maygup01 0:11cc2b7889af 295 // Transition to a new state based upon
maygup01 0:11cc2b7889af 296 // the current state of the state machine
maygup01 0:11cc2b7889af 297 BEGIN_TRANSITION_MAP // - Current State -
maygup01 0:11cc2b7889af 298 TRANSITION_MAP_ENTRY (STATE_UNREGISTERED) // state_idle
maygup01 0:11cc2b7889af 299 TRANSITION_MAP_ENTRY (STATE_UNREGISTERED) // state_bootstrap
maygup01 0:11cc2b7889af 300 TRANSITION_MAP_ENTRY (STATE_UNREGISTERED) // state__bootstrap_address_resolved
maygup01 0:11cc2b7889af 301 TRANSITION_MAP_ENTRY (STATE_UNREGISTERED) // state_bootstrap_resource_created
maygup01 0:11cc2b7889af 302 TRANSITION_MAP_ENTRY (STATE_UNREGISTERED) // state_bootstrap_wait
maygup01 0:11cc2b7889af 303 TRANSITION_MAP_ENTRY (STATE_UNREGISTERED) // state_bootstrap_error_wait
maygup01 0:11cc2b7889af 304 TRANSITION_MAP_ENTRY (STATE_UNREGISTERED) // state_bootstrapped
maygup01 0:11cc2b7889af 305 TRANSITION_MAP_ENTRY (STATE_UNREGISTERED) // state_register
maygup01 0:11cc2b7889af 306 TRANSITION_MAP_ENTRY (STATE_UNREGISTERED) // state_register_address_resolved
maygup01 0:11cc2b7889af 307 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_registered
maygup01 0:11cc2b7889af 308 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_update_registration
maygup01 0:11cc2b7889af 309 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregister
maygup01 0:11cc2b7889af 310 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregistered
maygup01 0:11cc2b7889af 311 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_sending_coap_data
maygup01 0:11cc2b7889af 312 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_coap_data_sent
maygup01 0:11cc2b7889af 313 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_coap_data_received
maygup01 0:11cc2b7889af 314 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_processing_coap_data
maygup01 0:11cc2b7889af 315 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_coap_data_processed
maygup01 0:11cc2b7889af 316 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_waiting
maygup01 0:11cc2b7889af 317 END_TRANSITION_MAP(NULL)
maygup01 0:11cc2b7889af 318
maygup01 0:11cc2b7889af 319 _connection_handler.release_mutex();
maygup01 0:11cc2b7889af 320 tr_debug("M2MInterfaceImpl::unregister_object - OUT");
maygup01 0:11cc2b7889af 321 }
maygup01 0:11cc2b7889af 322
maygup01 0:11cc2b7889af 323 void M2MInterfaceImpl::set_queue_sleep_handler(callback_handler handler)
maygup01 0:11cc2b7889af 324 {
maygup01 0:11cc2b7889af 325 _callback_handler = handler;
maygup01 0:11cc2b7889af 326 }
maygup01 0:11cc2b7889af 327
maygup01 0:11cc2b7889af 328 void M2MInterfaceImpl::set_random_number_callback(random_number_cb callback)
maygup01 0:11cc2b7889af 329 {
maygup01 0:11cc2b7889af 330 if(_security_connection) {
maygup01 0:11cc2b7889af 331 _security_connection->set_random_number_callback(callback);
maygup01 0:11cc2b7889af 332 }
maygup01 0:11cc2b7889af 333 }
maygup01 0:11cc2b7889af 334
maygup01 0:11cc2b7889af 335 void M2MInterfaceImpl::set_entropy_callback(entropy_cb callback)
maygup01 0:11cc2b7889af 336 {
maygup01 0:11cc2b7889af 337 if(_security_connection) {
maygup01 0:11cc2b7889af 338 _security_connection->set_entropy_callback(callback);
maygup01 0:11cc2b7889af 339 }
maygup01 0:11cc2b7889af 340 }
maygup01 0:11cc2b7889af 341
maygup01 0:11cc2b7889af 342 void M2MInterfaceImpl::set_platform_network_handler(void *handler)
maygup01 0:11cc2b7889af 343 {
maygup01 0:11cc2b7889af 344 _connection_handler.set_platform_network_handler(handler);
maygup01 0:11cc2b7889af 345 }
maygup01 0:11cc2b7889af 346
maygup01 0:11cc2b7889af 347 void M2MInterfaceImpl::coap_message_ready(uint8_t *data_ptr,
maygup01 0:11cc2b7889af 348 uint16_t data_len,
maygup01 0:11cc2b7889af 349 sn_nsdl_addr_s *address_ptr)
maygup01 0:11cc2b7889af 350 {
maygup01 0:11cc2b7889af 351 tr_debug("M2MInterfaceImpl::coap_message_ready");
maygup01 0:11cc2b7889af 352 if (_current_state != STATE_IDLE) {
maygup01 0:11cc2b7889af 353 internal_event(STATE_SENDING_COAP_DATA);
maygup01 0:11cc2b7889af 354 if(!_connection_handler.send_data(data_ptr,data_len,address_ptr)) {
maygup01 0:11cc2b7889af 355 internal_event( STATE_IDLE);
maygup01 0:11cc2b7889af 356 tr_error("M2MInterfaceImpl::coap_message_ready() - M2MInterface::NetworkError");
maygup01 0:11cc2b7889af 357 if (!_reconnecting) {
maygup01 0:11cc2b7889af 358 _queue_mode_timer_ongoing = false;
maygup01 0:11cc2b7889af 359 socket_error(M2MConnectionHandler::SOCKET_SEND_ERROR, true);
maygup01 0:11cc2b7889af 360 } else {
maygup01 0:11cc2b7889af 361 socket_error(M2MConnectionHandler::SOCKET_ABORT);
maygup01 0:11cc2b7889af 362 }
maygup01 0:11cc2b7889af 363 }
maygup01 0:11cc2b7889af 364 }
maygup01 0:11cc2b7889af 365 }
maygup01 0:11cc2b7889af 366
maygup01 0:11cc2b7889af 367 void M2MInterfaceImpl::client_registered(M2MServer *server_object)
maygup01 0:11cc2b7889af 368 {
maygup01 0:11cc2b7889af 369 tr_info("M2MInterfaceImpl::client_registered");
maygup01 0:11cc2b7889af 370 internal_event(STATE_REGISTERED);
maygup01 0:11cc2b7889af 371 //Inform client is registered.
maygup01 0:11cc2b7889af 372 //TODO: manage register object in a list.
maygup01 0:11cc2b7889af 373 _observer.object_registered(_register_server,*server_object);
maygup01 0:11cc2b7889af 374 }
maygup01 0:11cc2b7889af 375
maygup01 0:11cc2b7889af 376 void M2MInterfaceImpl::registration_updated(const M2MServer &server_object)
maygup01 0:11cc2b7889af 377 {
maygup01 0:11cc2b7889af 378 tr_info("M2MInterfaceImpl::registration_updated");
maygup01 0:11cc2b7889af 379 internal_event(STATE_REGISTERED);
maygup01 0:11cc2b7889af 380 _observer.registration_updated(_register_server,server_object);
maygup01 0:11cc2b7889af 381 }
maygup01 0:11cc2b7889af 382
maygup01 0:11cc2b7889af 383 void M2MInterfaceImpl::registration_error(uint8_t error_code, bool retry, bool full_registration)
maygup01 0:11cc2b7889af 384 {
maygup01 0:11cc2b7889af 385 tr_error("M2MInterfaceImpl::registration_error code [%d]", error_code);
maygup01 0:11cc2b7889af 386
maygup01 0:11cc2b7889af 387 _nsdl_interface.set_registration_status(false);
maygup01 0:11cc2b7889af 388
maygup01 0:11cc2b7889af 389 // Try to register again
maygup01 0:11cc2b7889af 390 if (retry) {
maygup01 0:11cc2b7889af 391 _queue_mode_timer_ongoing = false;
maygup01 0:11cc2b7889af 392
maygup01 0:11cc2b7889af 393 if (full_registration) {
maygup01 0:11cc2b7889af 394 _reconnection_state = M2MInterfaceImpl::None;
maygup01 0:11cc2b7889af 395 } else if (error_code == M2MInterface::UnregistrationFailed) {
maygup01 0:11cc2b7889af 396 _reconnection_state = M2MInterfaceImpl::Unregistration;
maygup01 0:11cc2b7889af 397 }
maygup01 0:11cc2b7889af 398
maygup01 0:11cc2b7889af 399 socket_error(M2MConnectionHandler::SOCKET_SEND_ERROR);
maygup01 0:11cc2b7889af 400 } else {
maygup01 0:11cc2b7889af 401 _security = NULL;
maygup01 0:11cc2b7889af 402 internal_event(STATE_IDLE);
maygup01 0:11cc2b7889af 403 if (error_code == M2MInterface::UnregistrationFailed) {
maygup01 0:11cc2b7889af 404 set_error_description(ERROR_REASON_24);
maygup01 0:11cc2b7889af 405 } else {
maygup01 0:11cc2b7889af 406 set_error_description(ERROR_REASON_8);
maygup01 0:11cc2b7889af 407 }
maygup01 0:11cc2b7889af 408 _observer.error((M2MInterface::Error)error_code);
maygup01 0:11cc2b7889af 409 }
maygup01 0:11cc2b7889af 410 }
maygup01 0:11cc2b7889af 411
maygup01 0:11cc2b7889af 412 void M2MInterfaceImpl::client_unregistered()
maygup01 0:11cc2b7889af 413 {
maygup01 0:11cc2b7889af 414 tr_info("M2MInterfaceImpl::client_unregistered()");
maygup01 0:11cc2b7889af 415 _nsdl_interface.set_registration_status(false);
maygup01 0:11cc2b7889af 416
maygup01 0:11cc2b7889af 417 // Zero the flag otherwise next registered response will start unregistration process
maygup01 0:11cc2b7889af 418 _reconnection_state = M2MInterfaceImpl::None;
maygup01 0:11cc2b7889af 419
maygup01 0:11cc2b7889af 420 internal_event(STATE_UNREGISTERED);
maygup01 0:11cc2b7889af 421 //TODO: manage register object in a list.
maygup01 0:11cc2b7889af 422 }
maygup01 0:11cc2b7889af 423
maygup01 0:11cc2b7889af 424 void M2MInterfaceImpl::bootstrap_done()
maygup01 0:11cc2b7889af 425 {
maygup01 0:11cc2b7889af 426 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 427 tr_info("M2MInterfaceImpl::bootstrap_done");
maygup01 0:11cc2b7889af 428 _reconnection_time = _initial_reconnection_time;
maygup01 0:11cc2b7889af 429 _reconnecting = false;
maygup01 0:11cc2b7889af 430 _reconnection_state = M2MInterfaceImpl::None;
maygup01 0:11cc2b7889af 431 _bootstrapped = true;
maygup01 0:11cc2b7889af 432
maygup01 0:11cc2b7889af 433 if (_registration_flow_timer) {
maygup01 0:11cc2b7889af 434 _registration_flow_timer->stop_timer();
maygup01 0:11cc2b7889af 435 }
maygup01 0:11cc2b7889af 436
maygup01 0:11cc2b7889af 437 // Force close connection since either server already closed (sent PEER_CLOSE_NOTIFY)
maygup01 0:11cc2b7889af 438 // or bootstrap flow has finished.
maygup01 0:11cc2b7889af 439 _connection_handler.force_close();
maygup01 0:11cc2b7889af 440
maygup01 0:11cc2b7889af 441 if (_bootstrap_finished) {
maygup01 0:11cc2b7889af 442 // Inform to observer only if bootstrap has already been finished
maygup01 0:11cc2b7889af 443 // This has to be done like this since we might get bootstrap_done
maygup01 0:11cc2b7889af 444 // callback BEFORE bootstrap_finish
maygup01 0:11cc2b7889af 445 internal_event(STATE_BOOTSTRAPPED);
maygup01 0:11cc2b7889af 446 _observer.bootstrap_done(_nsdl_interface.get_security_object());
maygup01 0:11cc2b7889af 447 }
maygup01 0:11cc2b7889af 448 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 449 }
maygup01 0:11cc2b7889af 450
maygup01 0:11cc2b7889af 451 void M2MInterfaceImpl::bootstrap_finish()
maygup01 0:11cc2b7889af 452 {
maygup01 0:11cc2b7889af 453 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 454 tr_info("M2MInterfaceImpl::bootstrap_finish");
maygup01 0:11cc2b7889af 455 internal_event(STATE_BOOTSTRAP_WAIT);
maygup01 0:11cc2b7889af 456 _observer.bootstrap_data_ready(_nsdl_interface.get_security_object());
maygup01 0:11cc2b7889af 457 _bootstrap_finished = true;
maygup01 0:11cc2b7889af 458
maygup01 0:11cc2b7889af 459 if (_bootstrapped) {
maygup01 0:11cc2b7889af 460 // If _bootstrapped is set, we have already received the bootstrap_done
maygup01 0:11cc2b7889af 461 // callback so we must inform observer now
maygup01 0:11cc2b7889af 462 bootstrap_done();
maygup01 0:11cc2b7889af 463 }
maygup01 0:11cc2b7889af 464 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 465 }
maygup01 0:11cc2b7889af 466
maygup01 0:11cc2b7889af 467 void M2MInterfaceImpl::bootstrap_wait()
maygup01 0:11cc2b7889af 468 {
maygup01 0:11cc2b7889af 469 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 470 tr_info("M2MInterfaceImpl::bootstrap_wait");
maygup01 0:11cc2b7889af 471 internal_event(STATE_BOOTSTRAP_WAIT);
maygup01 0:11cc2b7889af 472 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 473 }
maygup01 0:11cc2b7889af 474
maygup01 0:11cc2b7889af 475 void M2MInterfaceImpl::bootstrap_error_wait(const char *reason)
maygup01 0:11cc2b7889af 476 {
maygup01 0:11cc2b7889af 477 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 478 tr_error("M2MInterfaceImpl::bootstrap_error_wait");
maygup01 0:11cc2b7889af 479 set_error_description(reason);
maygup01 0:11cc2b7889af 480 internal_event(STATE_BOOTSTRAP_ERROR_WAIT);
maygup01 0:11cc2b7889af 481 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 482 }
maygup01 0:11cc2b7889af 483
maygup01 0:11cc2b7889af 484 void M2MInterfaceImpl::bootstrap_error(const char *reason)
maygup01 0:11cc2b7889af 485 {
maygup01 0:11cc2b7889af 486 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 487 tr_error("M2MInterfaceImpl::bootstrap_error(%s)", reason);
maygup01 0:11cc2b7889af 488 _bootstrapped = false;
maygup01 0:11cc2b7889af 489 if (_registration_flow_timer) {
maygup01 0:11cc2b7889af 490 _registration_flow_timer->stop_timer();
maygup01 0:11cc2b7889af 491 }
maygup01 0:11cc2b7889af 492
maygup01 0:11cc2b7889af 493 _reconnection_state = M2MInterfaceImpl::None;
maygup01 0:11cc2b7889af 494
maygup01 0:11cc2b7889af 495 set_error_description(reason);
maygup01 0:11cc2b7889af 496
maygup01 0:11cc2b7889af 497 _observer.error(M2MInterface::BootstrapFailed);
maygup01 0:11cc2b7889af 498
maygup01 0:11cc2b7889af 499 internal_event(STATE_IDLE);
maygup01 0:11cc2b7889af 500 _reconnecting = true;
maygup01 0:11cc2b7889af 501 _connection_handler.stop_listening();
maygup01 0:11cc2b7889af 502
maygup01 0:11cc2b7889af 503 _retry_timer_expired = false;
maygup01 0:11cc2b7889af 504 _retry_timer.start_timer(_reconnection_time * 1000,
maygup01 0:11cc2b7889af 505 M2MTimerObserver::RetryTimer);
maygup01 0:11cc2b7889af 506 tr_info("M2MInterfaceImpl::bootstrap_error - reconnecting in %" PRIu64 "(s)", _reconnection_time);
maygup01 0:11cc2b7889af 507 _reconnection_time = _reconnection_time * RECONNECT_INCREMENT_FACTOR;
maygup01 0:11cc2b7889af 508 if(_reconnection_time >= MAX_RECONNECT_TIMEOUT) {
maygup01 0:11cc2b7889af 509 _reconnection_time = MAX_RECONNECT_TIMEOUT;
maygup01 0:11cc2b7889af 510 }
maygup01 0:11cc2b7889af 511 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 512 }
maygup01 0:11cc2b7889af 513
maygup01 0:11cc2b7889af 514 void M2MInterfaceImpl::coap_data_processed()
maygup01 0:11cc2b7889af 515 {
maygup01 0:11cc2b7889af 516 tr_debug("M2MInterfaceImpl::coap_data_processed()");
maygup01 0:11cc2b7889af 517 internal_event(STATE_COAP_DATA_PROCESSED);
maygup01 0:11cc2b7889af 518 }
maygup01 0:11cc2b7889af 519
maygup01 0:11cc2b7889af 520 void M2MInterfaceImpl::value_updated(M2MBase *base)
maygup01 0:11cc2b7889af 521 {
maygup01 0:11cc2b7889af 522 tr_debug("M2MInterfaceImpl::value_updated");
maygup01 0:11cc2b7889af 523 if(base) {
maygup01 0:11cc2b7889af 524 M2MBase::BaseType type = base->base_type();
maygup01 0:11cc2b7889af 525 _observer.value_updated(base, type);
maygup01 0:11cc2b7889af 526 }
maygup01 0:11cc2b7889af 527 }
maygup01 0:11cc2b7889af 528
maygup01 0:11cc2b7889af 529 void M2MInterfaceImpl::data_available(uint8_t* data,
maygup01 0:11cc2b7889af 530 uint16_t data_size,
maygup01 0:11cc2b7889af 531 const M2MConnectionObserver::SocketAddress &address)
maygup01 0:11cc2b7889af 532 {
maygup01 0:11cc2b7889af 533 tr_debug("M2MInterfaceImpl::data_available");
maygup01 0:11cc2b7889af 534 ReceivedData event;
maygup01 0:11cc2b7889af 535 event._data = data;
maygup01 0:11cc2b7889af 536 event._size = data_size;
maygup01 0:11cc2b7889af 537 event._address = &address;
maygup01 0:11cc2b7889af 538 internal_event(STATE_COAP_DATA_RECEIVED, &event);
maygup01 0:11cc2b7889af 539 }
maygup01 0:11cc2b7889af 540
maygup01 0:11cc2b7889af 541 void M2MInterfaceImpl::socket_error(int error_code, bool retry)
maygup01 0:11cc2b7889af 542 {
maygup01 0:11cc2b7889af 543 // Bootstrap completed once PEER CLOSE notify received from the server.
maygup01 0:11cc2b7889af 544 if (_current_state == STATE_BOOTSTRAP_WAIT &&
maygup01 0:11cc2b7889af 545 error_code == M2MConnectionHandler::SSL_PEER_CLOSE_NOTIFY) {
maygup01 0:11cc2b7889af 546 _security = NULL;
maygup01 0:11cc2b7889af 547 bootstrap_done();
maygup01 0:11cc2b7889af 548 return;
maygup01 0:11cc2b7889af 549 }
maygup01 0:11cc2b7889af 550
maygup01 0:11cc2b7889af 551 tr_error("M2MInterfaceImpl::socket_error: (%d), retry (%d), reconnecting (%d), reconnection_state (%d)",
maygup01 0:11cc2b7889af 552 error_code, retry, _reconnecting, (int)_reconnection_state);
maygup01 0:11cc2b7889af 553
maygup01 0:11cc2b7889af 554 // Ignore errors while client is sleeping
maygup01 0:11cc2b7889af 555 if (queue_mode()) {
maygup01 0:11cc2b7889af 556 if (_callback_handler && _queue_mode_timer_ongoing) {
maygup01 0:11cc2b7889af 557 tr_info("M2MInterfaceImpl::socket_error - Queue Mode - don't try to reconnect while in QueueMode");
maygup01 0:11cc2b7889af 558 return;
maygup01 0:11cc2b7889af 559 }
maygup01 0:11cc2b7889af 560 }
maygup01 0:11cc2b7889af 561 _queue_sleep_timer.stop_timer();
maygup01 0:11cc2b7889af 562
maygup01 0:11cc2b7889af 563 if (_registration_flow_timer) {
maygup01 0:11cc2b7889af 564 _registration_flow_timer->stop_timer();
maygup01 0:11cc2b7889af 565 }
maygup01 0:11cc2b7889af 566
maygup01 0:11cc2b7889af 567 const char *error_code_des;
maygup01 0:11cc2b7889af 568 M2MInterface::Error error = M2MInterface::ErrorNone;
maygup01 0:11cc2b7889af 569 switch (error_code) {
maygup01 0:11cc2b7889af 570 case M2MConnectionHandler::SSL_CONNECTION_ERROR:
maygup01 0:11cc2b7889af 571 error = M2MInterface::SecureConnectionFailed;
maygup01 0:11cc2b7889af 572 error_code_des = ERROR_SECURE_CONNECTION;
maygup01 0:11cc2b7889af 573 break;
maygup01 0:11cc2b7889af 574 case M2MConnectionHandler::DNS_RESOLVING_ERROR:
maygup01 0:11cc2b7889af 575 error = M2MInterface::DnsResolvingFailed;
maygup01 0:11cc2b7889af 576 error_code_des = ERROR_DNS;
maygup01 0:11cc2b7889af 577 break;
maygup01 0:11cc2b7889af 578 case M2MConnectionHandler::SOCKET_READ_ERROR:
maygup01 0:11cc2b7889af 579 error = M2MInterface::NetworkError;
maygup01 0:11cc2b7889af 580 error_code_des = ERROR_NETWORK;
maygup01 0:11cc2b7889af 581 break;
maygup01 0:11cc2b7889af 582 case M2MConnectionHandler::SOCKET_SEND_ERROR:
maygup01 0:11cc2b7889af 583 error = M2MInterface::NetworkError;
maygup01 0:11cc2b7889af 584 error_code_des = ERROR_NETWORK;
maygup01 0:11cc2b7889af 585 break;
maygup01 0:11cc2b7889af 586 case M2MConnectionHandler::SSL_HANDSHAKE_ERROR:
maygup01 0:11cc2b7889af 587 error = M2MInterface::SecureConnectionFailed;
maygup01 0:11cc2b7889af 588 error_code_des = ERROR_SECURE_CONNECTION;
maygup01 0:11cc2b7889af 589 break;
maygup01 0:11cc2b7889af 590 case M2MConnectionHandler::SOCKET_ABORT:
maygup01 0:11cc2b7889af 591 error = M2MInterface::NetworkError;
maygup01 0:11cc2b7889af 592 error_code_des = ERROR_NETWORK;
maygup01 0:11cc2b7889af 593 break;
maygup01 0:11cc2b7889af 594 case M2MConnectionHandler::MEMORY_ALLOCATION_FAILED:
maygup01 0:11cc2b7889af 595 error = M2MInterface::MemoryFail;
maygup01 0:11cc2b7889af 596 error_code_des = ERROR_NO_MEMORY;
maygup01 0:11cc2b7889af 597 break;
maygup01 0:11cc2b7889af 598 case M2MConnectionHandler::FAILED_TO_READ_CREDENTIALS:
maygup01 0:11cc2b7889af 599 error = M2MInterface::FailedToReadCredentials;
maygup01 0:11cc2b7889af 600 error_code_des = ERROR_FAILED_TO_READ_CREDENTIALS;
maygup01 0:11cc2b7889af 601 break;
maygup01 0:11cc2b7889af 602 default:
maygup01 0:11cc2b7889af 603 error_code_des = ERROR_NO;
maygup01 0:11cc2b7889af 604 break;
maygup01 0:11cc2b7889af 605 }
maygup01 0:11cc2b7889af 606
maygup01 0:11cc2b7889af 607 internal_event(STATE_IDLE);
maygup01 0:11cc2b7889af 608
maygup01 0:11cc2b7889af 609 // Do a reconnect
maygup01 0:11cc2b7889af 610 if (retry) {
maygup01 0:11cc2b7889af 611 if ((error == M2MInterface::SecureConnectionFailed || error == M2MInterface::InvalidParameters) &&
maygup01 0:11cc2b7889af 612 _bootstrapped) {
maygup01 0:11cc2b7889af 613 // Connector client will start the bootstrap flow again
maygup01 0:11cc2b7889af 614 tr_info("M2MInterfaceImpl::socket_error - goes to re-bootstrap");
maygup01 0:11cc2b7889af 615 _observer.error(M2MInterface::SecureConnectionFailed);
maygup01 0:11cc2b7889af 616 return;
maygup01 0:11cc2b7889af 617 }
maygup01 0:11cc2b7889af 618
maygup01 0:11cc2b7889af 619 _nsdl_interface.set_request_context_to_be_resend(NULL, 0);
maygup01 0:11cc2b7889af 620 _reconnecting = true;
maygup01 0:11cc2b7889af 621 _connection_handler.stop_listening();
maygup01 0:11cc2b7889af 622 _retry_timer_expired = false;
maygup01 0:11cc2b7889af 623 _retry_timer.start_timer(_reconnection_time * 1000,
maygup01 0:11cc2b7889af 624 M2MTimerObserver::RetryTimer);
maygup01 0:11cc2b7889af 625
maygup01 0:11cc2b7889af 626 tr_info("M2MInterfaceImpl::socket_error - reconnecting in %" PRIu64 "(s)", _reconnection_time);
maygup01 0:11cc2b7889af 627
maygup01 0:11cc2b7889af 628 _reconnection_time = _reconnection_time * RECONNECT_INCREMENT_FACTOR;
maygup01 0:11cc2b7889af 629 if (_reconnection_time >= MAX_RECONNECT_TIMEOUT) {
maygup01 0:11cc2b7889af 630 _reconnection_time = MAX_RECONNECT_TIMEOUT;
maygup01 0:11cc2b7889af 631 }
maygup01 0:11cc2b7889af 632 #ifndef DISABLE_ERROR_DESCRIPTION
maygup01 0:11cc2b7889af 633 snprintf(_error_description, sizeof(_error_description), ERROR_REASON_9, error_code_des);
maygup01 0:11cc2b7889af 634 #endif
maygup01 0:11cc2b7889af 635 }
maygup01 0:11cc2b7889af 636 // Inform application
maygup01 0:11cc2b7889af 637 if (!retry && M2MInterface::ErrorNone != error) {
maygup01 0:11cc2b7889af 638 tr_info("M2MInterfaceImpl::socket_error - send error to application");
maygup01 0:11cc2b7889af 639 _connection_handler.stop_listening();
maygup01 0:11cc2b7889af 640 _retry_timer.stop_timer();
maygup01 0:11cc2b7889af 641 _security = NULL;
maygup01 0:11cc2b7889af 642 _reconnecting = false;
maygup01 0:11cc2b7889af 643 _reconnection_time = _initial_reconnection_time;
maygup01 0:11cc2b7889af 644 _reconnection_state = M2MInterfaceImpl::None;
maygup01 0:11cc2b7889af 645 #ifndef DISABLE_ERROR_DESCRIPTION
maygup01 0:11cc2b7889af 646 snprintf(_error_description, sizeof(_error_description), ERROR_REASON_10, error_code_des);
maygup01 0:11cc2b7889af 647 #endif
maygup01 0:11cc2b7889af 648 }
maygup01 0:11cc2b7889af 649 if (M2MInterface::ErrorNone != error) {
maygup01 0:11cc2b7889af 650 _observer.error(error);
maygup01 0:11cc2b7889af 651 }
maygup01 0:11cc2b7889af 652 }
maygup01 0:11cc2b7889af 653
maygup01 0:11cc2b7889af 654 void M2MInterfaceImpl::address_ready(const M2MConnectionObserver::SocketAddress &address,
maygup01 0:11cc2b7889af 655 M2MConnectionObserver::ServerType server_type,
maygup01 0:11cc2b7889af 656 const uint16_t server_port)
maygup01 0:11cc2b7889af 657 {
maygup01 0:11cc2b7889af 658 tr_debug("M2MInterfaceImpl::address_ready");
maygup01 0:11cc2b7889af 659 ResolvedAddressData data;
maygup01 0:11cc2b7889af 660 data._address = &address;
maygup01 0:11cc2b7889af 661 data._port = server_port;
maygup01 0:11cc2b7889af 662 if( M2MConnectionObserver::Bootstrap == server_type) {
maygup01 0:11cc2b7889af 663 tr_info("M2MInterfaceImpl::address_ready() Server Type Bootstrap");
maygup01 0:11cc2b7889af 664 internal_event(STATE_BOOTSTRAP_ADDRESS_RESOLVED, &data);
maygup01 0:11cc2b7889af 665 } else {
maygup01 0:11cc2b7889af 666 tr_info("M2MInterfaceImpl::address_ready() Server Type LWM2M");
maygup01 0:11cc2b7889af 667 internal_event(STATE_REGISTER_ADDRESS_RESOLVED, &data);
maygup01 0:11cc2b7889af 668 }
maygup01 0:11cc2b7889af 669 }
maygup01 0:11cc2b7889af 670
maygup01 0:11cc2b7889af 671 void M2MInterfaceImpl::data_sent()
maygup01 0:11cc2b7889af 672 {
maygup01 0:11cc2b7889af 673 tr_debug("M2MInterfaceImpl::data_sent()");
maygup01 0:11cc2b7889af 674 if(queue_mode()) {
maygup01 0:11cc2b7889af 675 if(_callback_handler && (_nsdl_interface.is_unregister_ongoing() == false)) {
maygup01 0:11cc2b7889af 676 _queue_sleep_timer.stop_timer();
maygup01 0:11cc2b7889af 677 _queue_sleep_timer.start_timer(_nsdl_interface.total_retransmission_time(_nsdl_interface.get_resend_count()) * (uint64_t)1000,
maygup01 0:11cc2b7889af 678 M2MTimerObserver::QueueSleep);
maygup01 0:11cc2b7889af 679 }
maygup01 0:11cc2b7889af 680 }
maygup01 0:11cc2b7889af 681
maygup01 0:11cc2b7889af 682 if (_current_state == STATE_BOOTSTRAP_ERROR_WAIT) {
maygup01 0:11cc2b7889af 683 // bootstrap_error to be called only after we have sent the last ACK.
maygup01 0:11cc2b7889af 684 // Otherwise client will goto reconnection mode before ACK has sent.
maygup01 0:11cc2b7889af 685 bootstrap_error(error_description());
maygup01 0:11cc2b7889af 686 } else if (_current_state != STATE_BOOTSTRAP_WAIT) {
maygup01 0:11cc2b7889af 687 internal_event(STATE_COAP_DATA_SENT);
maygup01 0:11cc2b7889af 688 }
maygup01 0:11cc2b7889af 689
maygup01 0:11cc2b7889af 690 // Delay the time when CoAP ping will be send.
maygup01 0:11cc2b7889af 691 _nsdl_interface.calculate_new_coap_ping_send_time();
maygup01 0:11cc2b7889af 692 }
maygup01 0:11cc2b7889af 693
maygup01 0:11cc2b7889af 694 void M2MInterfaceImpl::timer_expired(M2MTimerObserver::Type type)
maygup01 0:11cc2b7889af 695 {
maygup01 0:11cc2b7889af 696 if (M2MTimerObserver::QueueSleep == type) {
maygup01 0:11cc2b7889af 697 if (_reconnecting) {
maygup01 0:11cc2b7889af 698 tr_debug("M2MInterfaceImpl::timer_expired() - reconnection ongoing, continue sleep timer");
maygup01 0:11cc2b7889af 699 _queue_sleep_timer.start_timer(_nsdl_interface.total_retransmission_time(_nsdl_interface.get_resend_count()) * (uint64_t)1000,
maygup01 0:11cc2b7889af 700 M2MTimerObserver::QueueSleep);
maygup01 0:11cc2b7889af 701 } else {
maygup01 0:11cc2b7889af 702 tr_debug("M2MInterfaceImpl::timer_expired() - sleep");
maygup01 0:11cc2b7889af 703 M2MTimer &timer = _nsdl_interface.get_nsdl_execution_timer();
maygup01 0:11cc2b7889af 704 timer.stop_timer();
maygup01 0:11cc2b7889af 705 _queue_mode_timer_ongoing = true;
maygup01 0:11cc2b7889af 706 if(_callback_handler) {
maygup01 0:11cc2b7889af 707 _callback_handler();
maygup01 0:11cc2b7889af 708 }
maygup01 0:11cc2b7889af 709 }
maygup01 0:11cc2b7889af 710 } else if (M2MTimerObserver::RetryTimer == type) {
maygup01 0:11cc2b7889af 711 tr_debug("M2MInterfaceImpl::timer_expired() - retry");
maygup01 0:11cc2b7889af 712 _retry_timer_expired = true;
maygup01 0:11cc2b7889af 713 if (_bootstrapped) {
maygup01 0:11cc2b7889af 714 internal_event(STATE_REGISTER);
maygup01 0:11cc2b7889af 715 } else {
maygup01 0:11cc2b7889af 716 internal_event(STATE_BOOTSTRAP);
maygup01 0:11cc2b7889af 717 }
maygup01 0:11cc2b7889af 718 } else if (M2MTimerObserver::BootstrapFlowTimer == type) {
maygup01 0:11cc2b7889af 719 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 720 tr_debug("M2MInterfaceImpl::timer_expired() - bootstrap");
maygup01 0:11cc2b7889af 721 _bootstrapped = false;
maygup01 0:11cc2b7889af 722 if (_registration_flow_timer) {
maygup01 0:11cc2b7889af 723 _registration_flow_timer->stop_timer();
maygup01 0:11cc2b7889af 724 }
maygup01 0:11cc2b7889af 725 bootstrap_error(ERROR_REASON_23);
maygup01 0:11cc2b7889af 726 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 727 } else if (M2MTimerObserver::RegistrationFlowTimer == type) {
maygup01 0:11cc2b7889af 728 tr_debug("M2MInterfaceImpl::timer_expired() - register");
maygup01 0:11cc2b7889af 729 registration_error(M2MInterface::Timeout, true);
maygup01 0:11cc2b7889af 730 }
maygup01 0:11cc2b7889af 731 }
maygup01 0:11cc2b7889af 732
maygup01 0:11cc2b7889af 733 // state machine sits here.
maygup01 0:11cc2b7889af 734 void M2MInterfaceImpl::state_idle(EventData* /*data*/)
maygup01 0:11cc2b7889af 735 {
maygup01 0:11cc2b7889af 736 tr_debug("M2MInterfaceImpl::state_idle");
maygup01 0:11cc2b7889af 737 _nsdl_interface.stop_timers();
maygup01 0:11cc2b7889af 738 _nsdl_interface.clear_sent_blockwise_messages();
maygup01 0:11cc2b7889af 739 _nsdl_interface.clear_received_blockwise_messages();
maygup01 0:11cc2b7889af 740 _queue_sleep_timer.stop_timer();
maygup01 0:11cc2b7889af 741 }
maygup01 0:11cc2b7889af 742
maygup01 0:11cc2b7889af 743 void M2MInterfaceImpl::state_bootstrap(EventData *data)
maygup01 0:11cc2b7889af 744 {
maygup01 0:11cc2b7889af 745 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 746 tr_debug("M2MInterfaceImpl::state_bootstrap");
maygup01 0:11cc2b7889af 747 // Start with bootstrapping preparation
maygup01 0:11cc2b7889af 748 _bootstrapped = false;
maygup01 0:11cc2b7889af 749 _bootstrap_finished = false;
maygup01 0:11cc2b7889af 750 _nsdl_interface.set_registration_status(false);
maygup01 0:11cc2b7889af 751 M2MSecurityData *event = static_cast<M2MSecurityData *> (data);
maygup01 0:11cc2b7889af 752 if(!_security) {
maygup01 0:11cc2b7889af 753 M2MInterface::Error error = M2MInterface::InvalidParameters;
maygup01 0:11cc2b7889af 754 if (event) {
maygup01 0:11cc2b7889af 755 _security = event->_object;
maygup01 0:11cc2b7889af 756 if(_security) {
maygup01 0:11cc2b7889af 757 int32_t bs_id = _security->get_security_instance_id(M2MSecurity::Bootstrap);
maygup01 0:11cc2b7889af 758 tr_info("M2MInterfaceImpl::state_bootstrap - bs_id = %" PRId32 "(s)", bs_id);
maygup01 0:11cc2b7889af 759 if(bs_id >= 0) {
maygup01 0:11cc2b7889af 760 String server_address = _security->resource_value_string(M2MSecurity::M2MServerUri, bs_id);
maygup01 0:11cc2b7889af 761 _nsdl_interface.set_server_address(server_address.c_str());
maygup01 0:11cc2b7889af 762 tr_info("M2MInterfaceImpl::state_bootstrap - server_address %s", server_address.c_str());
maygup01 0:11cc2b7889af 763 String coap;
maygup01 0:11cc2b7889af 764 if(server_address.compare(0,sizeof(COAP)-1,COAP) == 0) {
maygup01 0:11cc2b7889af 765 coap = COAP;
maygup01 0:11cc2b7889af 766 }
maygup01 0:11cc2b7889af 767 else if(server_address.compare(0,sizeof(COAPS)-1,COAPS) == 0) {
maygup01 0:11cc2b7889af 768 _security->resource_value_int(M2MSecurity::SecurityMode, bs_id) != M2MSecurity::NoSecurity ? coap = COAPS: coap = "";
maygup01 0:11cc2b7889af 769 }
maygup01 0:11cc2b7889af 770 if(!coap.empty()) {
maygup01 0:11cc2b7889af 771 server_address = server_address.substr(coap.size(),
maygup01 0:11cc2b7889af 772 server_address.size()-coap.size());
maygup01 0:11cc2b7889af 773
maygup01 0:11cc2b7889af 774 process_address(server_address, _server_ip_address, _server_port);
maygup01 0:11cc2b7889af 775
maygup01 0:11cc2b7889af 776 tr_info("M2MInterfaceImpl::state_bootstrap - IP address %s, Port %d", _server_ip_address.c_str(), _server_port);
maygup01 0:11cc2b7889af 777 // If bind and resolving server address succeed then proceed else
maygup01 0:11cc2b7889af 778 // return error to the application and go to Idle state.
maygup01 0:11cc2b7889af 779 if(!_server_ip_address.empty()) {
maygup01 0:11cc2b7889af 780 error = M2MInterface::ErrorNone;
maygup01 0:11cc2b7889af 781 if (_registration_flow_timer) {
maygup01 0:11cc2b7889af 782 _registration_flow_timer->stop_timer();
maygup01 0:11cc2b7889af 783 _registration_flow_timer->start_timer(MBED_CLIENT_RECONNECTION_COUNT * MBED_CLIENT_RECONNECTION_INTERVAL * 8 * 1000,
maygup01 0:11cc2b7889af 784 M2MTimerObserver::BootstrapFlowTimer);
maygup01 0:11cc2b7889af 785 }
maygup01 0:11cc2b7889af 786 _connection_handler.resolve_server_address(_server_ip_address,
maygup01 0:11cc2b7889af 787 _server_port,
maygup01 0:11cc2b7889af 788 M2MConnectionObserver::Bootstrap,
maygup01 0:11cc2b7889af 789 _security);
maygup01 0:11cc2b7889af 790 }
maygup01 0:11cc2b7889af 791 }
maygup01 0:11cc2b7889af 792 }
maygup01 0:11cc2b7889af 793 }
maygup01 0:11cc2b7889af 794 }
maygup01 0:11cc2b7889af 795 if (error != M2MInterface::ErrorNone) {
maygup01 0:11cc2b7889af 796 tr_error("M2MInterfaceImpl::state_bootstrap - set error as M2MInterface::InvalidParameters");
maygup01 0:11cc2b7889af 797 internal_event(STATE_IDLE);
maygup01 0:11cc2b7889af 798 set_error_description(ERROR_REASON_11);
maygup01 0:11cc2b7889af 799 _observer.error(error);
maygup01 0:11cc2b7889af 800 }
maygup01 0:11cc2b7889af 801 } else {
maygup01 0:11cc2b7889af 802 _listen_port = 0;
maygup01 0:11cc2b7889af 803 _connection_handler.bind_connection(_listen_port);
maygup01 0:11cc2b7889af 804 if (_registration_flow_timer) {
maygup01 0:11cc2b7889af 805 _registration_flow_timer->stop_timer();
maygup01 0:11cc2b7889af 806 _registration_flow_timer->start_timer(MBED_CLIENT_RECONNECTION_COUNT * MBED_CLIENT_RECONNECTION_INTERVAL * 8 * 1000,
maygup01 0:11cc2b7889af 807 M2MTimerObserver::BootstrapFlowTimer);
maygup01 0:11cc2b7889af 808 }
maygup01 0:11cc2b7889af 809 tr_info("M2MInterfaceImpl::state_bootstrap (reconnect) - IP address %s, Port %d", _server_ip_address.c_str(), _server_port);
maygup01 0:11cc2b7889af 810 _connection_handler.resolve_server_address(_server_ip_address,
maygup01 0:11cc2b7889af 811 _server_port,
maygup01 0:11cc2b7889af 812 M2MConnectionObserver::Bootstrap,
maygup01 0:11cc2b7889af 813 _security);
maygup01 0:11cc2b7889af 814 }
maygup01 0:11cc2b7889af 815 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 816 }
maygup01 0:11cc2b7889af 817
maygup01 0:11cc2b7889af 818 void M2MInterfaceImpl::state_bootstrap_address_resolved( EventData *data)
maygup01 0:11cc2b7889af 819 {
maygup01 0:11cc2b7889af 820 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 821 tr_debug("M2MInterfaceImpl::state_bootstrap_address_resolved");
maygup01 0:11cc2b7889af 822 if (data) {
maygup01 0:11cc2b7889af 823 ResolvedAddressData *event = static_cast<ResolvedAddressData *> (data);
maygup01 0:11cc2b7889af 824 sn_nsdl_addr_s address;
maygup01 0:11cc2b7889af 825
maygup01 0:11cc2b7889af 826 M2MInterface::NetworkStack stack = event->_address->_stack;
maygup01 0:11cc2b7889af 827
maygup01 0:11cc2b7889af 828 if(M2MInterface::LwIP_IPv4 == stack) {
maygup01 0:11cc2b7889af 829 tr_info("M2MInterfaceImpl::state_bootstrap_address_resolved : IPv4 address");
maygup01 0:11cc2b7889af 830 address.type = SN_NSDL_ADDRESS_TYPE_IPV4;
maygup01 0:11cc2b7889af 831 } else if((M2MInterface::LwIP_IPv6 == stack) ||
maygup01 0:11cc2b7889af 832 (M2MInterface::Nanostack_IPv6 == stack)) {
maygup01 0:11cc2b7889af 833 tr_info("M2MInterfaceImpl::state_bootstrap_address_resolved : IPv6 address");
maygup01 0:11cc2b7889af 834 address.type = SN_NSDL_ADDRESS_TYPE_IPV6;
maygup01 0:11cc2b7889af 835 }
maygup01 0:11cc2b7889af 836 address.port = event->_port;
maygup01 0:11cc2b7889af 837 address.addr_ptr = (uint8_t*)event->_address->_address;
maygup01 0:11cc2b7889af 838 address.addr_len = event->_address->_length;
maygup01 0:11cc2b7889af 839 _connection_handler.start_listening_for_data();
maygup01 0:11cc2b7889af 840
maygup01 0:11cc2b7889af 841 if(_nsdl_interface.create_bootstrap_resource(&address)) {
maygup01 0:11cc2b7889af 842 internal_event(STATE_BOOTSTRAP_RESOURCE_CREATED);
maygup01 0:11cc2b7889af 843 } else{
maygup01 0:11cc2b7889af 844 // If resource creation fails then inform error to application
maygup01 0:11cc2b7889af 845 tr_error("M2MInterfaceImpl::state_bootstrap_address_resolved : M2MInterface::InvalidParameters");
maygup01 0:11cc2b7889af 846 internal_event(STATE_IDLE);
maygup01 0:11cc2b7889af 847 set_error_description(ERROR_REASON_12);
maygup01 0:11cc2b7889af 848 _observer.error(M2MInterface::InvalidParameters);
maygup01 0:11cc2b7889af 849 }
maygup01 0:11cc2b7889af 850 }
maygup01 0:11cc2b7889af 851 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 852 }
maygup01 0:11cc2b7889af 853
maygup01 0:11cc2b7889af 854 void M2MInterfaceImpl::state_bootstrap_resource_created( EventData */*data*/)
maygup01 0:11cc2b7889af 855 {
maygup01 0:11cc2b7889af 856 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 857 tr_debug("M2MInterfaceImpl::state_bootstrap_resource_created");
maygup01 0:11cc2b7889af 858 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 859 }
maygup01 0:11cc2b7889af 860
maygup01 0:11cc2b7889af 861 void M2MInterfaceImpl::state_bootstrapped( EventData */*data*/)
maygup01 0:11cc2b7889af 862 {
maygup01 0:11cc2b7889af 863 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 864 tr_debug("M2MInterfaceImpl::state_bootstrapped");
maygup01 0:11cc2b7889af 865 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 866 }
maygup01 0:11cc2b7889af 867
maygup01 0:11cc2b7889af 868 void M2MInterfaceImpl::state_register(EventData *data)
maygup01 0:11cc2b7889af 869 {
maygup01 0:11cc2b7889af 870 tr_debug("M2MInterfaceImpl::state_register");
maygup01 0:11cc2b7889af 871 _nsdl_interface.set_registration_status(false);
maygup01 0:11cc2b7889af 872 M2MRegisterData *event = static_cast<M2MRegisterData *> (data);
maygup01 0:11cc2b7889af 873 if (!_security) {
maygup01 0:11cc2b7889af 874 M2MInterface::Error error = M2MInterface::InvalidParameters;
maygup01 0:11cc2b7889af 875 // Start with registration preparation
maygup01 0:11cc2b7889af 876 if(event) {
maygup01 0:11cc2b7889af 877 _security = event->_object;
maygup01 0:11cc2b7889af 878 if(_security) {
maygup01 0:11cc2b7889af 879 int32_t m2m_id = _security->get_security_instance_id(M2MSecurity::M2MServer);
maygup01 0:11cc2b7889af 880 if(m2m_id >= 0) {
maygup01 0:11cc2b7889af 881 if(_nsdl_interface.create_nsdl_list_structure(event->_base_list)) {
maygup01 0:11cc2b7889af 882 // If the nsdl resource structure is created successfully
maygup01 0:11cc2b7889af 883 String server_address = _security->resource_value_string(M2MSecurity::M2MServerUri, m2m_id);
maygup01 0:11cc2b7889af 884 _nsdl_interface.set_server_address(server_address.c_str());
maygup01 0:11cc2b7889af 885 tr_info("M2MInterfaceImpl::state_register - server_address %s", server_address.c_str());
maygup01 0:11cc2b7889af 886 String coap;
maygup01 0:11cc2b7889af 887 if(server_address.compare(0,sizeof(COAP)-1,COAP) == 0) {
maygup01 0:11cc2b7889af 888 coap = COAP;
maygup01 0:11cc2b7889af 889 }
maygup01 0:11cc2b7889af 890 else if(server_address.compare(0,sizeof(COAPS)-1,COAPS) == 0) {
maygup01 0:11cc2b7889af 891 _security->resource_value_int(M2MSecurity::SecurityMode, m2m_id) != M2MSecurity::NoSecurity ? coap = COAPS: coap = "";
maygup01 0:11cc2b7889af 892 }
maygup01 0:11cc2b7889af 893 if(!coap.empty()) {
maygup01 0:11cc2b7889af 894 server_address = server_address.substr(coap.size(),
maygup01 0:11cc2b7889af 895 server_address.size() - coap.size());
maygup01 0:11cc2b7889af 896 process_address(server_address, _server_ip_address, _server_port);
maygup01 0:11cc2b7889af 897
maygup01 0:11cc2b7889af 898 tr_info("M2MInterfaceImpl::state_register - IP address %s, Port %d", _server_ip_address.c_str(), _server_port);
maygup01 0:11cc2b7889af 899 if(!_server_ip_address.empty()) {
maygup01 0:11cc2b7889af 900 // Connection related errors are coming through callback
maygup01 0:11cc2b7889af 901 if (_registration_flow_timer) {
maygup01 0:11cc2b7889af 902 _registration_flow_timer->stop_timer();
maygup01 0:11cc2b7889af 903 _registration_flow_timer->start_timer(MBED_CLIENT_RECONNECTION_COUNT * MBED_CLIENT_RECONNECTION_INTERVAL * 8 * 1000,
maygup01 0:11cc2b7889af 904 M2MTimerObserver::RegistrationFlowTimer);
maygup01 0:11cc2b7889af 905 }
maygup01 0:11cc2b7889af 906 error = M2MInterface::ErrorNone;
maygup01 0:11cc2b7889af 907 _connection_handler.resolve_server_address(_server_ip_address,_server_port,
maygup01 0:11cc2b7889af 908 M2MConnectionObserver::LWM2MServer,
maygup01 0:11cc2b7889af 909 _security);
maygup01 0:11cc2b7889af 910 }
maygup01 0:11cc2b7889af 911 }
maygup01 0:11cc2b7889af 912 } else {
maygup01 0:11cc2b7889af 913 tr_error("M2MInterfaceImpl::state_register - fail to create nsdl list structure!");
maygup01 0:11cc2b7889af 914 }
maygup01 0:11cc2b7889af 915 }
maygup01 0:11cc2b7889af 916 }
maygup01 0:11cc2b7889af 917 }
maygup01 0:11cc2b7889af 918 if (error != M2MInterface::ErrorNone) {
maygup01 0:11cc2b7889af 919 tr_error("M2MInterfaceImpl::state_register - set error as M2MInterface::InvalidParameters");
maygup01 0:11cc2b7889af 920 internal_event(STATE_IDLE);
maygup01 0:11cc2b7889af 921 set_error_description(ERROR_REASON_13);
maygup01 0:11cc2b7889af 922 _observer.error(error);
maygup01 0:11cc2b7889af 923 }
maygup01 0:11cc2b7889af 924 } else {
maygup01 0:11cc2b7889af 925 _listen_port = 0;
maygup01 0:11cc2b7889af 926 if (event) {
maygup01 0:11cc2b7889af 927 _nsdl_interface.create_nsdl_list_structure(event->_base_list);
maygup01 0:11cc2b7889af 928 }
maygup01 0:11cc2b7889af 929 _connection_handler.bind_connection(_listen_port);
maygup01 0:11cc2b7889af 930 if (_registration_flow_timer) {
maygup01 0:11cc2b7889af 931 _registration_flow_timer->stop_timer();
maygup01 0:11cc2b7889af 932 _registration_flow_timer->start_timer(MBED_CLIENT_RECONNECTION_COUNT * MBED_CLIENT_RECONNECTION_INTERVAL * 8 * 1000,
maygup01 0:11cc2b7889af 933 M2MTimerObserver::RegistrationFlowTimer);
maygup01 0:11cc2b7889af 934 }
maygup01 0:11cc2b7889af 935 tr_info("M2MInterfaceImpl::state_register (reconnect) - IP address %s, Port %d", _server_ip_address.c_str(), _server_port);
maygup01 0:11cc2b7889af 936 _connection_handler.resolve_server_address(_server_ip_address,_server_port,
maygup01 0:11cc2b7889af 937 M2MConnectionObserver::LWM2MServer,
maygup01 0:11cc2b7889af 938 _security);
maygup01 0:11cc2b7889af 939 }
maygup01 0:11cc2b7889af 940 }
maygup01 0:11cc2b7889af 941
maygup01 0:11cc2b7889af 942 void M2MInterfaceImpl::process_address(const String& server_address, String& ip_address, uint16_t& port) {
maygup01 0:11cc2b7889af 943
maygup01 0:11cc2b7889af 944 int colonFound = server_address.find_last_of(':'); //10
maygup01 0:11cc2b7889af 945 if(colonFound != -1) {
maygup01 0:11cc2b7889af 946 ip_address = server_address.substr(0,colonFound);
maygup01 0:11cc2b7889af 947 port = atoi(server_address.substr(colonFound+1,
maygup01 0:11cc2b7889af 948 server_address.size()-ip_address.size()).c_str());
maygup01 0:11cc2b7889af 949 colonFound = ip_address.find_last_of(']');
maygup01 0:11cc2b7889af 950 if(ip_address.compare(0,1,"[") == 0) {
maygup01 0:11cc2b7889af 951 if(colonFound == -1) {
maygup01 0:11cc2b7889af 952 ip_address.clear();
maygup01 0:11cc2b7889af 953 } else {
maygup01 0:11cc2b7889af 954 ip_address = ip_address.substr(1,colonFound-1);
maygup01 0:11cc2b7889af 955 }
maygup01 0:11cc2b7889af 956 } else if(colonFound != -1) {
maygup01 0:11cc2b7889af 957 ip_address.clear();
maygup01 0:11cc2b7889af 958 }
maygup01 0:11cc2b7889af 959 }
maygup01 0:11cc2b7889af 960 }
maygup01 0:11cc2b7889af 961
maygup01 0:11cc2b7889af 962 void M2MInterfaceImpl::state_register_address_resolved( EventData *data)
maygup01 0:11cc2b7889af 963 {
maygup01 0:11cc2b7889af 964 tr_debug("M2MInterfaceImpl::state_register_address_resolved - reconnect status %d", _reconnection_state);
maygup01 0:11cc2b7889af 965 if(data) {
maygup01 0:11cc2b7889af 966 ResolvedAddressData *event = static_cast<ResolvedAddressData *> (data);
maygup01 0:11cc2b7889af 967
maygup01 0:11cc2b7889af 968 sn_nsdl_addr_type_e address_type = SN_NSDL_ADDRESS_TYPE_IPV6;
maygup01 0:11cc2b7889af 969
maygup01 0:11cc2b7889af 970 M2MInterface::NetworkStack stack = event->_address->_stack;
maygup01 0:11cc2b7889af 971
maygup01 0:11cc2b7889af 972 if(M2MInterface::LwIP_IPv4 == stack) {
maygup01 0:11cc2b7889af 973 tr_info("M2MInterfaceImpl::state_register_address_resolved : IPv4 address");
maygup01 0:11cc2b7889af 974 address_type = SN_NSDL_ADDRESS_TYPE_IPV4;
maygup01 0:11cc2b7889af 975 } else if((M2MInterface::LwIP_IPv6 == stack) ||
maygup01 0:11cc2b7889af 976 (M2MInterface::Nanostack_IPv6 == stack)) {
maygup01 0:11cc2b7889af 977 tr_info("M2MInterfaceImpl::state_register_address_resolved : IPv6 address");
maygup01 0:11cc2b7889af 978 address_type = SN_NSDL_ADDRESS_TYPE_IPV6;
maygup01 0:11cc2b7889af 979 }
maygup01 0:11cc2b7889af 980 _connection_handler.start_listening_for_data();
maygup01 0:11cc2b7889af 981 _nsdl_interface.set_server_address((uint8_t*)event->_address->_address,event->_address->_length,
maygup01 0:11cc2b7889af 982 event->_port, address_type);
maygup01 0:11cc2b7889af 983 switch (_reconnection_state) {
maygup01 0:11cc2b7889af 984 case M2MInterfaceImpl::None:
maygup01 0:11cc2b7889af 985 if (!_nsdl_interface.send_register_message()) {
maygup01 0:11cc2b7889af 986 // If resource creation fails then inform error to application
maygup01 0:11cc2b7889af 987 tr_error("M2MInterfaceImpl::state_register_address_resolved : M2MInterface::MemoryFail");
maygup01 0:11cc2b7889af 988 internal_event(STATE_IDLE);
maygup01 0:11cc2b7889af 989 set_error_description(ERROR_REASON_25);
maygup01 0:11cc2b7889af 990 _observer.error(M2MInterface::MemoryFail);
maygup01 0:11cc2b7889af 991 }
maygup01 0:11cc2b7889af 992 break;
maygup01 0:11cc2b7889af 993 case M2MInterfaceImpl::Unregistration:
maygup01 0:11cc2b7889af 994 case M2MInterfaceImpl::WithUpdate:
maygup01 0:11cc2b7889af 995 // Start registration update in case it is reconnection logic because of network issue.
maygup01 0:11cc2b7889af 996 internal_event(STATE_UPDATE_REGISTRATION);
maygup01 0:11cc2b7889af 997 break;
maygup01 0:11cc2b7889af 998 }
maygup01 0:11cc2b7889af 999 }
maygup01 0:11cc2b7889af 1000 }
maygup01 0:11cc2b7889af 1001
maygup01 0:11cc2b7889af 1002 void M2MInterfaceImpl::state_registered( EventData */*data*/)
maygup01 0:11cc2b7889af 1003 {
maygup01 0:11cc2b7889af 1004 tr_info("M2MInterfaceImpl::state_registered");
maygup01 0:11cc2b7889af 1005 if (_registration_flow_timer) {
maygup01 0:11cc2b7889af 1006 _registration_flow_timer->stop_timer();
maygup01 0:11cc2b7889af 1007 }
maygup01 0:11cc2b7889af 1008 _reconnection_time = _initial_reconnection_time;
maygup01 0:11cc2b7889af 1009 _reconnecting = false;
maygup01 0:11cc2b7889af 1010 _nsdl_interface.set_registration_status(true);
maygup01 0:11cc2b7889af 1011 // Continue with the unregistration process if it has failed due to connection lost
maygup01 0:11cc2b7889af 1012 if (_reconnection_state == M2MInterfaceImpl::Unregistration) {
maygup01 0:11cc2b7889af 1013 internal_event(STATE_UNREGISTER);
maygup01 0:11cc2b7889af 1014 } else {
maygup01 0:11cc2b7889af 1015 _reconnection_state = M2MInterfaceImpl::WithUpdate;
maygup01 0:11cc2b7889af 1016 }
maygup01 0:11cc2b7889af 1017 }
maygup01 0:11cc2b7889af 1018
maygup01 0:11cc2b7889af 1019 void M2MInterfaceImpl::state_update_registration(EventData *data)
maygup01 0:11cc2b7889af 1020 {
maygup01 0:11cc2b7889af 1021 tr_debug("M2MInterfaceImpl::state_update_registration");
maygup01 0:11cc2b7889af 1022 uint32_t lifetime = 0;
maygup01 0:11cc2b7889af 1023 // Set to false to allow reconnection to work.
maygup01 0:11cc2b7889af 1024 _queue_mode_timer_ongoing = false;
maygup01 0:11cc2b7889af 1025
maygup01 0:11cc2b7889af 1026 if (data) {
maygup01 0:11cc2b7889af 1027 M2MUpdateRegisterData *event = static_cast<M2MUpdateRegisterData *> (data);
maygup01 0:11cc2b7889af 1028 // Create new resources if any
maygup01 0:11cc2b7889af 1029 if (!event->_base_list.empty()) {
maygup01 0:11cc2b7889af 1030 _nsdl_interface.create_nsdl_list_structure(event->_base_list);
maygup01 0:11cc2b7889af 1031 }
maygup01 0:11cc2b7889af 1032 lifetime = event->_lifetime;
maygup01 0:11cc2b7889af 1033 }
maygup01 0:11cc2b7889af 1034
maygup01 0:11cc2b7889af 1035 bool success = _nsdl_interface.send_update_registration(lifetime);
maygup01 0:11cc2b7889af 1036 if (!success) {
maygup01 0:11cc2b7889af 1037 tr_error("M2MInterfaceImpl::state_update_registration : M2MInterface::MemoryFail");
maygup01 0:11cc2b7889af 1038 internal_event(STATE_IDLE);
maygup01 0:11cc2b7889af 1039 set_error_description(ERROR_REASON_25);
maygup01 0:11cc2b7889af 1040 _observer.error(M2MInterface::MemoryFail);
maygup01 0:11cc2b7889af 1041 }
maygup01 0:11cc2b7889af 1042 }
maygup01 0:11cc2b7889af 1043
maygup01 0:11cc2b7889af 1044 void M2MInterfaceImpl::state_unregister(EventData */*data*/)
maygup01 0:11cc2b7889af 1045 {
maygup01 0:11cc2b7889af 1046 tr_debug("M2MInterfaceImpl::state_unregister");
maygup01 0:11cc2b7889af 1047 internal_event(STATE_SENDING_COAP_DATA);
maygup01 0:11cc2b7889af 1048 if(!_nsdl_interface.send_unregister_message()) {
maygup01 0:11cc2b7889af 1049 tr_error("M2MInterfaceImpl::state_unregister : M2MInterface::NotRegistered");
maygup01 0:11cc2b7889af 1050 internal_event(STATE_IDLE);
maygup01 0:11cc2b7889af 1051 set_error_description(ERROR_REASON_16);
maygup01 0:11cc2b7889af 1052 _observer.error(M2MInterface::NotRegistered);
maygup01 0:11cc2b7889af 1053 }
maygup01 0:11cc2b7889af 1054 }
maygup01 0:11cc2b7889af 1055
maygup01 0:11cc2b7889af 1056 void M2MInterfaceImpl::state_unregistered( EventData */*data*/)
maygup01 0:11cc2b7889af 1057 {
maygup01 0:11cc2b7889af 1058 tr_info("M2MInterfaceImpl::state_unregistered");
maygup01 0:11cc2b7889af 1059 _reconnection_time = _initial_reconnection_time;
maygup01 0:11cc2b7889af 1060 _connection_handler.force_close();
maygup01 0:11cc2b7889af 1061 _security = NULL;
maygup01 0:11cc2b7889af 1062 _observer.object_unregistered(_register_server);
maygup01 0:11cc2b7889af 1063 internal_event(STATE_IDLE);
maygup01 0:11cc2b7889af 1064 }
maygup01 0:11cc2b7889af 1065
maygup01 0:11cc2b7889af 1066 void M2MInterfaceImpl::state_sending_coap_data( EventData */*data*/)
maygup01 0:11cc2b7889af 1067 {
maygup01 0:11cc2b7889af 1068 tr_debug("M2MInterfaceImpl::state_sending_coap_data");
maygup01 0:11cc2b7889af 1069 _nsdl_interface.start_nsdl_execution_timer();
maygup01 0:11cc2b7889af 1070 internal_event(STATE_WAITING);
maygup01 0:11cc2b7889af 1071 }
maygup01 0:11cc2b7889af 1072
maygup01 0:11cc2b7889af 1073 void M2MInterfaceImpl::state_coap_data_sent( EventData */*data*/)
maygup01 0:11cc2b7889af 1074 {
maygup01 0:11cc2b7889af 1075 tr_debug("M2MInterfaceImpl::state_coap_data_sent");
maygup01 0:11cc2b7889af 1076 internal_event(STATE_WAITING);
maygup01 0:11cc2b7889af 1077 }
maygup01 0:11cc2b7889af 1078
maygup01 0:11cc2b7889af 1079 void M2MInterfaceImpl::state_coap_data_received(EventData *data)
maygup01 0:11cc2b7889af 1080 {
maygup01 0:11cc2b7889af 1081 tr_debug("M2MInterfaceImpl::state_coap_data_received");
maygup01 0:11cc2b7889af 1082 if(data) {
maygup01 0:11cc2b7889af 1083 ReceivedData *event = static_cast<ReceivedData*> (data);
maygup01 0:11cc2b7889af 1084 sn_nsdl_addr_s address;
maygup01 0:11cc2b7889af 1085
maygup01 0:11cc2b7889af 1086 M2MInterface::NetworkStack stack = event->_address->_stack;
maygup01 0:11cc2b7889af 1087
maygup01 0:11cc2b7889af 1088 if(M2MInterface::LwIP_IPv4 == stack) {
maygup01 0:11cc2b7889af 1089 address.type = SN_NSDL_ADDRESS_TYPE_IPV4;
maygup01 0:11cc2b7889af 1090 address.addr_len = 4;
maygup01 0:11cc2b7889af 1091 } else if((M2MInterface::LwIP_IPv6 == stack) ||
maygup01 0:11cc2b7889af 1092 (M2MInterface::Nanostack_IPv6 == stack)) {
maygup01 0:11cc2b7889af 1093 address.type = SN_NSDL_ADDRESS_TYPE_IPV6;
maygup01 0:11cc2b7889af 1094 address.addr_len = 16;
maygup01 0:11cc2b7889af 1095 }
maygup01 0:11cc2b7889af 1096 address.port = event->_address->_port;
maygup01 0:11cc2b7889af 1097 address.addr_ptr = (uint8_t*)event->_address->_address;
maygup01 0:11cc2b7889af 1098 address.addr_len = event->_address->_length;
maygup01 0:11cc2b7889af 1099
maygup01 0:11cc2b7889af 1100 // Process received data
maygup01 0:11cc2b7889af 1101 internal_event(STATE_PROCESSING_COAP_DATA);
maygup01 0:11cc2b7889af 1102 if(!_nsdl_interface.process_received_data(event->_data,
maygup01 0:11cc2b7889af 1103 event->_size,
maygup01 0:11cc2b7889af 1104 &address)) {
maygup01 0:11cc2b7889af 1105 tr_error("M2MInterfaceImpl::state_coap_data_received : M2MInterface::ResponseParseFailed");
maygup01 0:11cc2b7889af 1106 set_error_description(ERROR_REASON_17);
maygup01 0:11cc2b7889af 1107 _observer.error(M2MInterface::ResponseParseFailed);
maygup01 0:11cc2b7889af 1108 }
maygup01 0:11cc2b7889af 1109 }
maygup01 0:11cc2b7889af 1110 }
maygup01 0:11cc2b7889af 1111
maygup01 0:11cc2b7889af 1112 void M2MInterfaceImpl::state_processing_coap_data( EventData */*data*/)
maygup01 0:11cc2b7889af 1113 {
maygup01 0:11cc2b7889af 1114 tr_debug("M2MInterfaceImpl::state_processing_coap_data");
maygup01 0:11cc2b7889af 1115 internal_event(STATE_WAITING);
maygup01 0:11cc2b7889af 1116 }
maygup01 0:11cc2b7889af 1117
maygup01 0:11cc2b7889af 1118 void M2MInterfaceImpl::state_coap_data_processed( EventData */*data*/)
maygup01 0:11cc2b7889af 1119 {
maygup01 0:11cc2b7889af 1120 tr_debug("M2MInterfaceImpl::state_coap_data_processed");
maygup01 0:11cc2b7889af 1121 internal_event(STATE_WAITING);
maygup01 0:11cc2b7889af 1122 }
maygup01 0:11cc2b7889af 1123
maygup01 0:11cc2b7889af 1124 void M2MInterfaceImpl::state_waiting( EventData */*data*/)
maygup01 0:11cc2b7889af 1125 {
maygup01 0:11cc2b7889af 1126 tr_debug("M2MInterfaceImpl::state_waiting");
maygup01 0:11cc2b7889af 1127 }
maygup01 0:11cc2b7889af 1128
maygup01 0:11cc2b7889af 1129 // generates an external event. called once per external event
maygup01 0:11cc2b7889af 1130 // to start the state machine executing
maygup01 0:11cc2b7889af 1131 void M2MInterfaceImpl::external_event(uint8_t new_state,
maygup01 0:11cc2b7889af 1132 EventData* p_data)
maygup01 0:11cc2b7889af 1133 {
maygup01 0:11cc2b7889af 1134 tr_debug("M2MInterfaceImpl::external_event : new state %d", new_state);
maygup01 0:11cc2b7889af 1135 // if we are supposed to ignore this event
maygup01 0:11cc2b7889af 1136 if (new_state == EVENT_IGNORED) {
maygup01 0:11cc2b7889af 1137 tr_debug("M2MInterfaceImpl::external_event : new state is EVENT_IGNORED");
maygup01 0:11cc2b7889af 1138 _event_ignored = true;
maygup01 0:11cc2b7889af 1139 }
maygup01 0:11cc2b7889af 1140 else {
maygup01 0:11cc2b7889af 1141 tr_debug("M2MInterfaceImpl::external_event : handle new state");
maygup01 0:11cc2b7889af 1142 // generate the event and execute the state engine
maygup01 0:11cc2b7889af 1143 internal_event(new_state, p_data);
maygup01 0:11cc2b7889af 1144 }
maygup01 0:11cc2b7889af 1145 }
maygup01 0:11cc2b7889af 1146
maygup01 0:11cc2b7889af 1147 // generates an internal event. called from within a state
maygup01 0:11cc2b7889af 1148 // function to transition to a new state
maygup01 0:11cc2b7889af 1149 void M2MInterfaceImpl::internal_event(uint8_t new_state,
maygup01 0:11cc2b7889af 1150 EventData* p_data)
maygup01 0:11cc2b7889af 1151 {
maygup01 0:11cc2b7889af 1152 tr_debug("M2MInterfaceImpl::internal_event : new state %d", new_state);
maygup01 0:11cc2b7889af 1153 _event_data = p_data;
maygup01 0:11cc2b7889af 1154 _event_generated = true;
maygup01 0:11cc2b7889af 1155 _current_state = new_state;
maygup01 0:11cc2b7889af 1156 state_engine();
maygup01 0:11cc2b7889af 1157 }
maygup01 0:11cc2b7889af 1158
maygup01 0:11cc2b7889af 1159 // the state engine executes the state machine states
maygup01 0:11cc2b7889af 1160 void M2MInterfaceImpl::state_engine (void)
maygup01 0:11cc2b7889af 1161 {
maygup01 0:11cc2b7889af 1162 tr_debug("M2MInterfaceImpl::state_engine");
maygup01 0:11cc2b7889af 1163 EventData* p_data_temp = NULL;
maygup01 0:11cc2b7889af 1164
maygup01 0:11cc2b7889af 1165 // while events are being generated keep executing states
maygup01 0:11cc2b7889af 1166 while (_event_generated) {
maygup01 0:11cc2b7889af 1167 p_data_temp = _event_data; // copy of event data pointer
maygup01 0:11cc2b7889af 1168 _event_data = NULL; // event data used up, reset ptr
maygup01 0:11cc2b7889af 1169 _event_generated = false; // event used up, reset flag
maygup01 0:11cc2b7889af 1170
maygup01 0:11cc2b7889af 1171 assert(_current_state < _max_states);
maygup01 0:11cc2b7889af 1172
maygup01 0:11cc2b7889af 1173 state_function( _current_state, p_data_temp );
maygup01 0:11cc2b7889af 1174 }
maygup01 0:11cc2b7889af 1175 }
maygup01 0:11cc2b7889af 1176
maygup01 0:11cc2b7889af 1177 void M2MInterfaceImpl::state_function( uint8_t current_state, EventData* data )
maygup01 0:11cc2b7889af 1178 {
maygup01 0:11cc2b7889af 1179 switch( current_state ) {
maygup01 0:11cc2b7889af 1180 case STATE_IDLE:
maygup01 0:11cc2b7889af 1181 M2MInterfaceImpl::state_idle(data);
maygup01 0:11cc2b7889af 1182 break;
maygup01 0:11cc2b7889af 1183 case STATE_BOOTSTRAP:
maygup01 0:11cc2b7889af 1184 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 1185 M2MInterfaceImpl::state_bootstrap(data);
maygup01 0:11cc2b7889af 1186 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 1187 break;
maygup01 0:11cc2b7889af 1188 case STATE_BOOTSTRAP_ADDRESS_RESOLVED:
maygup01 0:11cc2b7889af 1189 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 1190 M2MInterfaceImpl::state_bootstrap_address_resolved(data);
maygup01 0:11cc2b7889af 1191 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 1192 break;
maygup01 0:11cc2b7889af 1193 case STATE_BOOTSTRAP_RESOURCE_CREATED:
maygup01 0:11cc2b7889af 1194 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 1195 M2MInterfaceImpl::state_bootstrap_resource_created(data);
maygup01 0:11cc2b7889af 1196 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 1197 break;
maygup01 0:11cc2b7889af 1198 case STATE_BOOTSTRAP_WAIT:
maygup01 0:11cc2b7889af 1199 case STATE_BOOTSTRAP_ERROR_WAIT:
maygup01 0:11cc2b7889af 1200 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 1201 // Do nothing, we're just waiting for data_sent callback
maygup01 0:11cc2b7889af 1202 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 1203 break;
maygup01 0:11cc2b7889af 1204 case STATE_BOOTSTRAPPED:
maygup01 0:11cc2b7889af 1205 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 1206 M2MInterfaceImpl::state_bootstrapped(data);
maygup01 0:11cc2b7889af 1207 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
maygup01 0:11cc2b7889af 1208 break;
maygup01 0:11cc2b7889af 1209 case STATE_REGISTER:
maygup01 0:11cc2b7889af 1210 M2MInterfaceImpl::state_register(data);
maygup01 0:11cc2b7889af 1211 break;
maygup01 0:11cc2b7889af 1212 case STATE_REGISTER_ADDRESS_RESOLVED:
maygup01 0:11cc2b7889af 1213 M2MInterfaceImpl::state_register_address_resolved(data);
maygup01 0:11cc2b7889af 1214 break;
maygup01 0:11cc2b7889af 1215 case STATE_REGISTERED:
maygup01 0:11cc2b7889af 1216 M2MInterfaceImpl::state_registered(data);
maygup01 0:11cc2b7889af 1217 break;
maygup01 0:11cc2b7889af 1218 case STATE_UPDATE_REGISTRATION:
maygup01 0:11cc2b7889af 1219 M2MInterfaceImpl::state_update_registration(data);
maygup01 0:11cc2b7889af 1220 break;
maygup01 0:11cc2b7889af 1221 case STATE_UNREGISTER:
maygup01 0:11cc2b7889af 1222 M2MInterfaceImpl::state_unregister(data);
maygup01 0:11cc2b7889af 1223 break;
maygup01 0:11cc2b7889af 1224 case STATE_UNREGISTERED:
maygup01 0:11cc2b7889af 1225 M2MInterfaceImpl::state_unregistered(data);
maygup01 0:11cc2b7889af 1226 break;
maygup01 0:11cc2b7889af 1227 case STATE_SENDING_COAP_DATA:
maygup01 0:11cc2b7889af 1228 M2MInterfaceImpl::state_sending_coap_data(data);
maygup01 0:11cc2b7889af 1229 break;
maygup01 0:11cc2b7889af 1230 case STATE_COAP_DATA_SENT:
maygup01 0:11cc2b7889af 1231 M2MInterfaceImpl::state_coap_data_sent(data);
maygup01 0:11cc2b7889af 1232 break;
maygup01 0:11cc2b7889af 1233 case STATE_COAP_DATA_RECEIVED:
maygup01 0:11cc2b7889af 1234 M2MInterfaceImpl::state_coap_data_received(data);
maygup01 0:11cc2b7889af 1235 break;
maygup01 0:11cc2b7889af 1236 case STATE_PROCESSING_COAP_DATA:
maygup01 0:11cc2b7889af 1237 M2MInterfaceImpl::state_processing_coap_data(data);
maygup01 0:11cc2b7889af 1238 break;
maygup01 0:11cc2b7889af 1239 case STATE_COAP_DATA_PROCESSED:
maygup01 0:11cc2b7889af 1240 M2MInterfaceImpl::state_coap_data_processed(data);
maygup01 0:11cc2b7889af 1241 break;
maygup01 0:11cc2b7889af 1242 case STATE_WAITING:
maygup01 0:11cc2b7889af 1243 M2MInterfaceImpl::state_waiting(data);
maygup01 0:11cc2b7889af 1244 break;
maygup01 0:11cc2b7889af 1245 }
maygup01 0:11cc2b7889af 1246 }
maygup01 0:11cc2b7889af 1247
maygup01 0:11cc2b7889af 1248 void M2MInterfaceImpl::start_register_update(M2MUpdateRegisterData *data) {
maygup01 0:11cc2b7889af 1249 tr_debug("M2MInterfaceImpl::start_register_update()");
maygup01 0:11cc2b7889af 1250 if(!data || (data->_lifetime != 0 && (data->_lifetime < MINIMUM_REGISTRATION_TIME))) {
maygup01 0:11cc2b7889af 1251 set_error_description(ERROR_REASON_18);
maygup01 0:11cc2b7889af 1252 _observer.error(M2MInterface::InvalidParameters);
maygup01 0:11cc2b7889af 1253 }
maygup01 0:11cc2b7889af 1254
maygup01 0:11cc2b7889af 1255 if (_reconnecting) {
maygup01 0:11cc2b7889af 1256 //If client is in reconnection mode, ignore this call, state machine will reconnect on its own.
maygup01 0:11cc2b7889af 1257 return;
maygup01 0:11cc2b7889af 1258 } else if (_nsdl_interface.is_update_register_ongoing()) {
maygup01 0:11cc2b7889af 1259 set_error_description(ERROR_REASON_27);
maygup01 0:11cc2b7889af 1260 _observer.error(M2MInterface::NotAllowed);
maygup01 0:11cc2b7889af 1261 return;
maygup01 0:11cc2b7889af 1262 }
maygup01 0:11cc2b7889af 1263
maygup01 0:11cc2b7889af 1264 _reconnection_state = M2MInterfaceImpl::WithUpdate;
maygup01 0:11cc2b7889af 1265 BEGIN_TRANSITION_MAP // - Current State -
maygup01 0:11cc2b7889af 1266 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_idle
maygup01 0:11cc2b7889af 1267 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap
maygup01 0:11cc2b7889af 1268 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state__bootstrap_address_resolved
maygup01 0:11cc2b7889af 1269 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_resource_created
maygup01 0:11cc2b7889af 1270 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_wait
maygup01 0:11cc2b7889af 1271 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_error_wait
maygup01 0:11cc2b7889af 1272 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrapped
maygup01 0:11cc2b7889af 1273 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register
maygup01 0:11cc2b7889af 1274 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_address_resolved
maygup01 0:11cc2b7889af 1275 TRANSITION_MAP_ENTRY (STATE_UPDATE_REGISTRATION) // state_registered
maygup01 0:11cc2b7889af 1276 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_update_registration
maygup01 0:11cc2b7889af 1277 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregister
maygup01 0:11cc2b7889af 1278 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregistered
maygup01 0:11cc2b7889af 1279 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_sending_coap_data
maygup01 0:11cc2b7889af 1280 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_sent
maygup01 0:11cc2b7889af 1281 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_received
maygup01 0:11cc2b7889af 1282 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_processing_coap_data
maygup01 0:11cc2b7889af 1283 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_processed
maygup01 0:11cc2b7889af 1284 TRANSITION_MAP_ENTRY (STATE_UPDATE_REGISTRATION) // state_waiting
maygup01 0:11cc2b7889af 1285 END_TRANSITION_MAP(data)
maygup01 0:11cc2b7889af 1286 if(_event_ignored) {
maygup01 0:11cc2b7889af 1287 _event_ignored = false;
maygup01 0:11cc2b7889af 1288 if (!_reconnecting) {
maygup01 0:11cc2b7889af 1289 set_error_description(ERROR_REASON_19);
maygup01 0:11cc2b7889af 1290 _observer.error(M2MInterface::NotAllowed);
maygup01 0:11cc2b7889af 1291 }
maygup01 0:11cc2b7889af 1292 }
maygup01 0:11cc2b7889af 1293 }
maygup01 0:11cc2b7889af 1294
maygup01 0:11cc2b7889af 1295 bool M2MInterfaceImpl::remove_object(M2MBase *object)
maygup01 0:11cc2b7889af 1296 {
maygup01 0:11cc2b7889af 1297 return _nsdl_interface.remove_object_from_list(object);
maygup01 0:11cc2b7889af 1298 }
maygup01 0:11cc2b7889af 1299
maygup01 0:11cc2b7889af 1300 void M2MInterfaceImpl::update_endpoint(const String &name) {
maygup01 0:11cc2b7889af 1301 _nsdl_interface.update_endpoint(name);
maygup01 0:11cc2b7889af 1302 }
maygup01 0:11cc2b7889af 1303
maygup01 0:11cc2b7889af 1304 void M2MInterfaceImpl::update_domain(const String &domain)
maygup01 0:11cc2b7889af 1305 {
maygup01 0:11cc2b7889af 1306 _nsdl_interface.update_domain(domain);
maygup01 0:11cc2b7889af 1307 }
maygup01 0:11cc2b7889af 1308
maygup01 0:11cc2b7889af 1309 const String M2MInterfaceImpl::internal_endpoint_name() const
maygup01 0:11cc2b7889af 1310 {
maygup01 0:11cc2b7889af 1311 return _nsdl_interface.internal_endpoint_name();
maygup01 0:11cc2b7889af 1312 }
maygup01 0:11cc2b7889af 1313
maygup01 0:11cc2b7889af 1314 const char *M2MInterfaceImpl::error_description() const
maygup01 0:11cc2b7889af 1315 {
maygup01 0:11cc2b7889af 1316 #ifndef DISABLE_ERROR_DESCRIPTION
maygup01 0:11cc2b7889af 1317 return _error_description;
maygup01 0:11cc2b7889af 1318 #else
maygup01 0:11cc2b7889af 1319 return "";
maygup01 0:11cc2b7889af 1320 #endif
maygup01 0:11cc2b7889af 1321 }
maygup01 0:11cc2b7889af 1322
maygup01 0:11cc2b7889af 1323 void M2MInterfaceImpl::set_error_description(const char *description)
maygup01 0:11cc2b7889af 1324 {
maygup01 0:11cc2b7889af 1325 #ifndef DISABLE_ERROR_DESCRIPTION
maygup01 0:11cc2b7889af 1326 if (strncmp(_error_description, description, sizeof(_error_description)) != 0) {
maygup01 0:11cc2b7889af 1327 strncpy(_error_description, description, MAX_ALLOWED_ERROR_STRING_LENGTH - 1);
maygup01 0:11cc2b7889af 1328 }
maygup01 0:11cc2b7889af 1329 #endif
maygup01 0:11cc2b7889af 1330 }
maygup01 0:11cc2b7889af 1331
maygup01 0:11cc2b7889af 1332 bool M2MInterfaceImpl::queue_mode() const
maygup01 0:11cc2b7889af 1333 {
maygup01 0:11cc2b7889af 1334 return (_binding_mode == M2MInterface::UDP_QUEUE ||
maygup01 0:11cc2b7889af 1335 _binding_mode == M2MInterface::TCP_QUEUE ||
maygup01 0:11cc2b7889af 1336 _binding_mode == M2MInterface::SMS_QUEUE ||
maygup01 0:11cc2b7889af 1337 _binding_mode == M2MInterface::UDP_SMS_QUEUE);
maygup01 0:11cc2b7889af 1338 }
maygup01 0:11cc2b7889af 1339
maygup01 0:11cc2b7889af 1340 void M2MInterfaceImpl::get_data_request(DownloadType type,
maygup01 0:11cc2b7889af 1341 const char *uri,
maygup01 0:11cc2b7889af 1342 const size_t offset,
maygup01 0:11cc2b7889af 1343 const bool async,
maygup01 0:11cc2b7889af 1344 get_data_cb data_cb,
maygup01 0:11cc2b7889af 1345 get_data_error_cb error_cb,
maygup01 0:11cc2b7889af 1346 void *context)
maygup01 0:11cc2b7889af 1347 {
maygup01 0:11cc2b7889af 1348 get_data_req_error_e error = FAILED_TO_SEND_MSG;
maygup01 0:11cc2b7889af 1349 if (uri) {
maygup01 0:11cc2b7889af 1350 _nsdl_interface.send_request(type, uri, COAP_MSG_CODE_REQUEST_GET, offset, async, 0, 0, NULL, data_cb, error_cb, context);
maygup01 0:11cc2b7889af 1351 } else {
maygup01 0:11cc2b7889af 1352 error_cb(error, context);
maygup01 0:11cc2b7889af 1353 }
maygup01 0:11cc2b7889af 1354 }
maygup01 0:11cc2b7889af 1355
maygup01 0:11cc2b7889af 1356 void M2MInterfaceImpl::post_data_request(const char *uri,
maygup01 0:11cc2b7889af 1357 const bool async,
maygup01 0:11cc2b7889af 1358 const uint16_t payload_len,
maygup01 0:11cc2b7889af 1359 uint8_t *payload_ptr,
maygup01 0:11cc2b7889af 1360 get_data_cb data_cb,
maygup01 0:11cc2b7889af 1361 get_data_error_cb error_cb,
maygup01 0:11cc2b7889af 1362 void *context)
maygup01 0:11cc2b7889af 1363 {
maygup01 0:11cc2b7889af 1364 get_data_req_error_e error = FAILED_TO_SEND_MSG;
maygup01 0:11cc2b7889af 1365 if (uri) {
maygup01 0:11cc2b7889af 1366 _nsdl_interface.send_request(GENERIC_DOWNLOAD, uri, COAP_MSG_CODE_REQUEST_POST, 0, async, 0, payload_len, payload_ptr, data_cb, error_cb, context);
maygup01 0:11cc2b7889af 1367 } else {
maygup01 0:11cc2b7889af 1368 error_cb(error, context);
maygup01 0:11cc2b7889af 1369 }
maygup01 0:11cc2b7889af 1370 }
maygup01 0:11cc2b7889af 1371
maygup01 0:11cc2b7889af 1372 bool M2MInterfaceImpl::set_uri_query_parameters(const char *uri_query_params)
maygup01 0:11cc2b7889af 1373 {
maygup01 0:11cc2b7889af 1374 return _nsdl_interface.set_uri_query_parameters(uri_query_params);
maygup01 0:11cc2b7889af 1375 }
maygup01 0:11cc2b7889af 1376
maygup01 0:11cc2b7889af 1377 void M2MInterfaceImpl::pause()
maygup01 0:11cc2b7889af 1378 {
maygup01 0:11cc2b7889af 1379 tr_debug("M2MInterfaceImpl::pause");
maygup01 0:11cc2b7889af 1380 _connection_handler.claim_mutex();
maygup01 0:11cc2b7889af 1381 _queue_sleep_timer.stop_timer();
maygup01 0:11cc2b7889af 1382 if (_registration_flow_timer) {
maygup01 0:11cc2b7889af 1383 _registration_flow_timer->stop_timer();
maygup01 0:11cc2b7889af 1384 }
maygup01 0:11cc2b7889af 1385 _connection_handler.unregister_network_handler();
maygup01 0:11cc2b7889af 1386 _nsdl_interface.set_request_context_to_be_resend(NULL, 0);
maygup01 0:11cc2b7889af 1387 _connection_handler.stop_listening();
maygup01 0:11cc2b7889af 1388 _retry_timer.stop_timer();
maygup01 0:11cc2b7889af 1389 _reconnecting = false;
maygup01 0:11cc2b7889af 1390 _reconnection_time = _initial_reconnection_time;
maygup01 0:11cc2b7889af 1391 _reconnection_state = M2MInterfaceImpl::WithUpdate;
maygup01 0:11cc2b7889af 1392
maygup01 0:11cc2b7889af 1393 sn_nsdl_clear_coap_resending_queue(_nsdl_interface.get_nsdl_handle());
maygup01 0:11cc2b7889af 1394 internal_event(STATE_IDLE);
maygup01 0:11cc2b7889af 1395 _connection_handler.release_mutex();
maygup01 0:11cc2b7889af 1396 }
maygup01 0:11cc2b7889af 1397
maygup01 0:11cc2b7889af 1398 void M2MInterfaceImpl::resume(void *iface, const M2MBaseList &list)
maygup01 0:11cc2b7889af 1399 {
maygup01 0:11cc2b7889af 1400 tr_debug("M2MInterfaceImpl::resume");
maygup01 0:11cc2b7889af 1401 _connection_handler.set_platform_network_handler(iface);
maygup01 0:11cc2b7889af 1402 register_object(_security, list);
maygup01 0:11cc2b7889af 1403 }