Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
m2minterfaceimpl.cpp
00001 /* 00002 * Copyright (c) 2015 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 // Needed for PRIu64 on FreeRTOS 00018 #include <stdio.h> 00019 // Note: this macro is needed on armcc to get the the PRI*32 macros 00020 // from inttypes.h in a C++ code. 00021 #ifndef __STDC_FORMAT_MACROS 00022 #define __STDC_FORMAT_MACROS 00023 #endif 00024 #include <inttypes.h> 00025 00026 #include <assert.h> 00027 #include <stdlib.h> 00028 #include <stdio.h> 00029 #include <time.h> 00030 #include "include/m2minterfaceimpl.h" 00031 #include "include/eventdata.h" 00032 #include "mbed-client/m2minterfaceobserver.h" 00033 #include "mbed-client/m2mconnectionhandler.h" 00034 #include "mbed-client/m2mconnectionsecurity.h" 00035 #include "include/m2mnsdlinterface.h" 00036 #include "mbed-client/m2msecurity.h" 00037 #include "mbed-client/m2mtimer.h" 00038 #include "mbed-trace/mbed_trace.h" 00039 #include "randLIB.h" 00040 00041 #include <stdlib.h> 00042 00043 #define TRACE_GROUP "mClt" 00044 00045 #define RESOLVE_SEC_MODE(mode) ((mode == M2MInterface::TCP || mode == M2MInterface::TCP_QUEUE) ? M2MConnectionSecurity::TLS : M2MConnectionSecurity::DTLS) 00046 00047 M2MInterfaceImpl::M2MInterfaceImpl(M2MInterfaceObserver& observer, 00048 const String &ep_name, 00049 const String &ep_type, 00050 const int32_t l_time, 00051 const uint16_t listen_port, 00052 const String &dmn, 00053 M2MInterface::BindingMode mode, 00054 M2MInterface::NetworkStack stack, 00055 const String &con_addr) 00056 : _event_data(NULL), 00057 _registration_flow_timer(NULL), 00058 _server_port(0), 00059 _listen_port(listen_port), 00060 _life_time(l_time), 00061 _register_server(NULL), 00062 _queue_sleep_timer(*this), 00063 _retry_timer(*this), 00064 _callback_handler(NULL), 00065 _max_states( STATE_MAX_STATES ), 00066 _event_ignored(false), 00067 _event_generated(false), 00068 _reconnecting(false), 00069 _retry_timer_expired(false), 00070 _bootstrapped(true), // True as default to get it working with connector only configuration 00071 _queue_mode_timer_ongoing(false), 00072 _current_state(0), 00073 _binding_mode(mode), 00074 _reconnection_state(M2MInterfaceImpl::None), 00075 _observer(observer), 00076 _security_connection( new M2MConnectionSecurity( RESOLVE_SEC_MODE(mode) )), 00077 _connection_handler(*this, _security_connection, mode, stack), 00078 _nsdl_interface(*this, _connection_handler), 00079 _security(NULL) 00080 { 00081 tr_debug("M2MInterfaceImpl::M2MInterfaceImpl() -IN"); 00082 //TODO:Increase the range from 1 to 100 seconds 00083 randLIB_seed_random(); 00084 // Range is from 2 to 10 00085 _initial_reconnection_time = randLIB_get_random_in_range(2, 10); 00086 00087 tr_info("M2MInterfaceImpl::M2MInterfaceImpl() initial random time %d\n", _initial_reconnection_time); 00088 _reconnection_time = _initial_reconnection_time; 00089 00090 #ifndef DISABLE_ERROR_DESCRIPTION 00091 memset(_error_description, 0, sizeof(_error_description)); 00092 #endif 00093 00094 _nsdl_interface.create_endpoint(ep_name, 00095 ep_type, 00096 _life_time, 00097 dmn, 00098 (uint8_t)_binding_mode, 00099 con_addr); 00100 00101 //Here we must use TCP still 00102 _connection_handler.bind_connection(_listen_port); 00103 00104 // We need this timer only in case of TCP 00105 if (_binding_mode == M2MInterface::TCP || 00106 _binding_mode == M2MInterface::TCP_QUEUE ) { 00107 _registration_flow_timer = new M2MTimer(*this); 00108 } 00109 tr_debug("M2MInterfaceImpl::M2MInterfaceImpl() -OUT"); 00110 } 00111 00112 00113 M2MInterfaceImpl::~M2MInterfaceImpl() 00114 { 00115 tr_debug("M2MInterfaceImpl::~M2MInterfaceImpl() - IN"); 00116 delete _registration_flow_timer; 00117 _security_connection = NULL; 00118 tr_debug("M2MInterfaceImpl::~M2MInterfaceImpl() - OUT"); 00119 } 00120 00121 void M2MInterfaceImpl::bootstrap(M2MSecurity *security) 00122 { 00123 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00124 tr_debug("M2MInterfaceImpl::bootstrap(M2MSecurity *security) - IN"); 00125 _retry_timer.stop_timer(); 00126 _security = NULL; 00127 if(!security) { 00128 set_error_description(ERROR_REASON_1); 00129 _observer.error(M2MInterface::InvalidParameters); 00130 return; 00131 } 00132 // Transition to a new state based upon 00133 // the current state of the state machine 00134 M2MSecurityData data; 00135 data._object = security; 00136 BEGIN_TRANSITION_MAP // - Current State - 00137 TRANSITION_MAP_ENTRY (STATE_BOOTSTRAP) // state_idle 00138 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap 00139 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state__bootstrap_address_resolved 00140 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_resource_created 00141 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_wait 00142 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_error_wait 00143 TRANSITION_MAP_ENTRY (STATE_BOOTSTRAP) // state_bootstrapped 00144 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register 00145 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_address_resolved 00146 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_registered 00147 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_update_registration 00148 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregister 00149 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregistered 00150 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_sending_coap_data 00151 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_sent 00152 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_received 00153 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_processing_coap_data 00154 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_processed 00155 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_waiting 00156 END_TRANSITION_MAP(&data) 00157 if(_event_ignored) { 00158 _event_ignored = false; 00159 set_error_description(ERROR_REASON_2); 00160 _observer.error(M2MInterface::NotAllowed); 00161 } 00162 tr_debug("M2MInterfaceImpl::bootstrap(M2MSecurity *security) - OUT"); 00163 #else 00164 set_error_description(ERROR_REASON_3); 00165 _observer.error(M2MInterface::NotAllowed); 00166 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00167 } 00168 00169 void M2MInterfaceImpl::cancel_bootstrap() 00170 { 00171 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00172 //TODO: Do we need this ? 00173 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00174 } 00175 00176 void M2MInterfaceImpl::register_object(M2MSecurity *security, const M2MObjectList &object_list) 00177 { 00178 tr_debug("M2MInterfaceImpl::register_object - IN"); 00179 if(!security) { 00180 set_error_description(ERROR_REASON_4); 00181 _observer.error(M2MInterface::InvalidParameters); 00182 return; 00183 } 00184 // Transition to a new state based upon 00185 // the current state of the state machine 00186 //TODO: manage register object in a list. 00187 _connection_handler.claim_mutex(); 00188 _register_server = security; 00189 M2MRegisterData data; 00190 data._object = security; 00191 data._object_list = object_list; 00192 BEGIN_TRANSITION_MAP // - Current State - 00193 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_idle 00194 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap 00195 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state__bootstrap_address_resolved 00196 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_resource_created 00197 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_wait 00198 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_error_wait 00199 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_bootstrapped 00200 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register 00201 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_address_resolved 00202 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_registered 00203 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_update_registration 00204 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregister 00205 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregistered 00206 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_sending_coap_data 00207 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_sent 00208 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_received 00209 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_processing_coap_data 00210 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_processed 00211 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_waiting 00212 END_TRANSITION_MAP(&data) 00213 if(_event_ignored) { 00214 _event_ignored = false; 00215 set_error_description(ERROR_REASON_5); 00216 _observer.error(M2MInterface::NotAllowed); 00217 } 00218 _connection_handler.release_mutex(); 00219 tr_debug("M2MInterfaceImpl::register_object - OUT"); 00220 } 00221 00222 void M2MInterfaceImpl::update_registration(M2MSecurity *security_object, const uint32_t lifetime) 00223 { 00224 tr_debug("M2MInterfaceImpl::update_registration()"); 00225 _connection_handler.claim_mutex(); 00226 M2MUpdateRegisterData data; 00227 data._object = security_object; 00228 data._lifetime = lifetime; 00229 start_register_update(&data); 00230 _connection_handler.release_mutex(); 00231 } 00232 00233 void M2MInterfaceImpl::update_registration(M2MSecurity *security_object, 00234 const M2MObjectList &object_list, 00235 const uint32_t lifetime) 00236 { 00237 tr_debug("M2MInterfaceImpl::update_registration - with object list"); 00238 _connection_handler.claim_mutex(); 00239 M2MUpdateRegisterData data; 00240 data._object = security_object; 00241 data._lifetime = lifetime; 00242 data._object_list = object_list; 00243 start_register_update(&data); 00244 _connection_handler.release_mutex(); 00245 } 00246 00247 void M2MInterfaceImpl::unregister_object(M2MSecurity* /*security*/) 00248 { 00249 tr_debug("M2MInterfaceImpl::unregister_object - current state %d", _current_state); 00250 _connection_handler.claim_mutex(); 00251 // Transition to a new state based upon 00252 // the current state of the state machine 00253 BEGIN_TRANSITION_MAP // - Current State - 00254 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_idle 00255 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap 00256 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state__bootstrap_address_resolved 00257 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_resource_created 00258 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_wait 00259 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_error_wait 00260 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrapped 00261 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register 00262 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_address_resolved 00263 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_registered 00264 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_update_registration 00265 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregister 00266 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregistered 00267 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_sending_coap_data 00268 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_coap_data_sent 00269 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_coap_data_received 00270 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_processing_coap_data 00271 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_coap_data_processed 00272 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_waiting 00273 END_TRANSITION_MAP(NULL) 00274 if(_event_ignored) { 00275 _event_ignored = false; 00276 set_error_description(ERROR_REASON_6); 00277 _observer.error(M2MInterface::NotAllowed); 00278 } 00279 _connection_handler.release_mutex(); 00280 tr_debug("M2MInterfaceImpl::unregister_object - OUT"); 00281 } 00282 00283 void M2MInterfaceImpl::set_queue_sleep_handler(callback_handler handler) 00284 { 00285 _callback_handler = handler; 00286 } 00287 00288 void M2MInterfaceImpl::set_random_number_callback(random_number_cb callback) 00289 { 00290 if(_security_connection) { 00291 _security_connection->set_random_number_callback(callback); 00292 } 00293 } 00294 00295 void M2MInterfaceImpl::set_entropy_callback(entropy_cb callback) 00296 { 00297 if(_security_connection) { 00298 _security_connection->set_entropy_callback(callback); 00299 } 00300 } 00301 00302 void M2MInterfaceImpl::set_platform_network_handler(void *handler) 00303 { 00304 _connection_handler.set_platform_network_handler(handler); 00305 } 00306 00307 void M2MInterfaceImpl::coap_message_ready(uint8_t *data_ptr, 00308 uint16_t data_len, 00309 sn_nsdl_addr_s *address_ptr) 00310 { 00311 tr_debug("M2MInterfaceImpl::coap_message_ready"); 00312 if (_current_state != STATE_IDLE) { 00313 internal_event(STATE_SENDING_COAP_DATA); 00314 if(!_connection_handler.send_data(data_ptr,data_len,address_ptr)) { 00315 internal_event( STATE_IDLE); 00316 tr_error("M2MInterfaceImpl::coap_message_ready() - M2MInterface::NetworkError"); 00317 if (!_reconnecting) { 00318 _queue_mode_timer_ongoing = false; 00319 socket_error(M2MConnectionHandler::SOCKET_SEND_ERROR, true); 00320 } else { 00321 socket_error(M2MConnectionHandler::SOCKET_ABORT); 00322 } 00323 } 00324 } 00325 } 00326 00327 void M2MInterfaceImpl::client_registered(M2MServer *server_object) 00328 { 00329 tr_info("M2MInterfaceImpl::client_registered"); 00330 internal_event(STATE_REGISTERED); 00331 //Inform client is registered. 00332 //TODO: manage register object in a list. 00333 _observer.object_registered(_register_server,*server_object); 00334 } 00335 00336 void M2MInterfaceImpl::registration_updated(const M2MServer &server_object) 00337 { 00338 tr_info("M2MInterfaceImpl::registration_updated"); 00339 internal_event(STATE_REGISTERED); 00340 _observer.registration_updated(_register_server,server_object); 00341 } 00342 00343 void M2MInterfaceImpl::registration_error(uint8_t error_code, bool retry) 00344 { 00345 tr_error("M2MInterfaceImpl::registration_error code [%d]", error_code); 00346 // Try to register again 00347 if (retry) { 00348 _queue_mode_timer_ongoing = false; 00349 if (error_code == M2MInterface::UnregistrationFailed) { 00350 _reconnection_state = M2MInterfaceImpl::Unregistration; 00351 } 00352 socket_error(M2MConnectionHandler::SOCKET_SEND_ERROR); 00353 } else { 00354 _security = NULL; 00355 internal_event(STATE_IDLE); 00356 if (error_code == M2MInterface::UnregistrationFailed) { 00357 set_error_description(ERROR_REASON_24); 00358 } else { 00359 set_error_description(ERROR_REASON_8); 00360 } 00361 _observer.error((M2MInterface::Error)error_code); 00362 } 00363 } 00364 00365 void M2MInterfaceImpl::client_unregistered() 00366 { 00367 tr_info("M2MInterfaceImpl::client_unregistered()"); 00368 internal_event(STATE_UNREGISTERED); 00369 //TODO: manage register object in a list. 00370 _observer.object_unregistered(_register_server); 00371 } 00372 00373 void M2MInterfaceImpl::bootstrap_done() 00374 { 00375 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00376 tr_info("M2MInterfaceImpl::bootstrap_done"); 00377 _reconnection_time = _initial_reconnection_time; 00378 _reconnecting = false; 00379 _reconnection_state = M2MInterfaceImpl::None; 00380 _bootstrapped = true; 00381 if (_registration_flow_timer) { 00382 _registration_flow_timer->stop_timer(); 00383 } 00384 internal_event(STATE_BOOTSTRAPPED); 00385 _observer.bootstrap_done(_nsdl_interface.get_security_object()); 00386 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00387 } 00388 00389 void M2MInterfaceImpl::bootstrap_wait() 00390 { 00391 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00392 tr_info("M2MInterfaceImpl::bootstrap_wait"); 00393 internal_event(STATE_BOOTSTRAP_WAIT); 00394 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00395 } 00396 00397 void M2MInterfaceImpl::bootstrap_error_wait(const char *reason) 00398 { 00399 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00400 tr_error("M2MInterfaceImpl::bootstrap_error_wait"); 00401 set_error_description(reason); 00402 internal_event(STATE_BOOTSTRAP_ERROR_WAIT); 00403 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00404 } 00405 00406 void M2MInterfaceImpl::bootstrap_error(const char *reason) 00407 { 00408 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00409 tr_error("M2MInterfaceImpl::bootstrap_error(%s)", reason); 00410 _bootstrapped = false; 00411 if (_registration_flow_timer) { 00412 _registration_flow_timer->stop_timer(); 00413 } 00414 00415 _reconnection_state = M2MInterfaceImpl::None; 00416 00417 set_error_description(reason); 00418 00419 _observer.error(M2MInterface::BootstrapFailed); 00420 00421 internal_event(STATE_IDLE); 00422 _reconnecting = true; 00423 _connection_handler.stop_listening(); 00424 00425 _retry_timer_expired = false; 00426 _retry_timer.start_timer(_reconnection_time * 1000, 00427 M2MTimerObserver::RetryTimer); 00428 tr_info("M2MInterfaceImpl::bootstrap_error - reconnecting in %" PRIu64 "(s)", _reconnection_time); 00429 _reconnection_time = _reconnection_time * RECONNECT_INCREMENT_FACTOR; 00430 if(_reconnection_time >= MAX_RECONNECT_TIMEOUT) { 00431 _reconnection_time = MAX_RECONNECT_TIMEOUT; 00432 } 00433 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00434 } 00435 00436 void M2MInterfaceImpl::coap_data_processed() 00437 { 00438 tr_debug("M2MInterfaceImpl::coap_data_processed()"); 00439 internal_event(STATE_COAP_DATA_PROCESSED); 00440 } 00441 00442 void M2MInterfaceImpl::value_updated(M2MBase *base) 00443 { 00444 tr_debug("M2MInterfaceImpl::value_updated"); 00445 if(base) { 00446 M2MBase::BaseType type = base->base_type(); 00447 _observer.value_updated(base, type); 00448 } 00449 } 00450 00451 void M2MInterfaceImpl::data_available(uint8_t* data, 00452 uint16_t data_size, 00453 const M2MConnectionObserver::SocketAddress &address) 00454 { 00455 tr_debug("M2MInterfaceImpl::data_available"); 00456 ReceivedData event; 00457 event._data = data; 00458 event._size = data_size; 00459 event._address = &address; 00460 internal_event(STATE_COAP_DATA_RECEIVED, &event); 00461 } 00462 00463 void M2MInterfaceImpl::socket_error(uint8_t error_code, bool retry) 00464 { 00465 // Bootstrap completed once PEER CLOSE notify received from the server. 00466 if (_current_state == STATE_BOOTSTRAP_WAIT && 00467 error_code == M2MConnectionHandler::SSL_PEER_CLOSED) { 00468 _security = NULL; 00469 bootstrap_done(); 00470 return; 00471 } 00472 00473 tr_error("M2MInterfaceImpl::socket_error: (%d), retry (%d), reconnecting (%d), reconnection_state (%d)", 00474 error_code, retry, _reconnecting, (int)_reconnection_state); 00475 00476 // Ignore errors while client is sleeping 00477 if(queue_mode()) { 00478 if(_callback_handler && _queue_mode_timer_ongoing) { 00479 tr_info("M2MInterfaceImpl::socket_error - Queue Mode - don't try to reconnect while in QueueMode"); 00480 return; 00481 } 00482 } 00483 _queue_sleep_timer.stop_timer(); 00484 00485 if (_registration_flow_timer) { 00486 _registration_flow_timer->stop_timer(); 00487 } 00488 00489 _queue_sleep_timer.stop_timer(); 00490 00491 // Don't change flag state if unregistration has failed. 00492 // This info is needed for continuing unregistration process after client is registered again. 00493 if (_reconnection_state != M2MInterfaceImpl::Unregistration && _reconnection_state != M2MInterfaceImpl::FullRegistration) { 00494 _reconnection_state = M2MInterfaceImpl::WithUpdate; 00495 } 00496 00497 const char *error_code_des; 00498 M2MInterface::Error error = M2MInterface::ErrorNone; 00499 switch (error_code) { 00500 case M2MConnectionHandler::SSL_CONNECTION_ERROR: 00501 error = M2MInterface::SecureConnectionFailed; 00502 error_code_des = ERROR_SECURE_CONNECTION; 00503 break; 00504 case M2MConnectionHandler::DNS_RESOLVING_ERROR: 00505 error = M2MInterface::DnsResolvingFailed; 00506 error_code_des = ERROR_DNS; 00507 break; 00508 case M2MConnectionHandler::SOCKET_READ_ERROR: 00509 error = M2MInterface::NetworkError; 00510 error_code_des = ERROR_NETWORK; 00511 break; 00512 case M2MConnectionHandler::SOCKET_SEND_ERROR: 00513 error = M2MInterface::NetworkError; 00514 error_code_des = ERROR_NETWORK; 00515 break; 00516 case M2MConnectionHandler::SSL_HANDSHAKE_ERROR: 00517 error = M2MInterface::SecureConnectionFailed; 00518 error_code_des = ERROR_SECURE_CONNECTION; 00519 break; 00520 case M2MConnectionHandler::SOCKET_ABORT: 00521 error = M2MInterface::NetworkError; 00522 error_code_des = ERROR_NETWORK; 00523 break; 00524 default: 00525 error_code_des = ERROR_NO; 00526 break; 00527 } 00528 00529 internal_event(STATE_IDLE); 00530 // Try to do reconnecting 00531 if (retry) { 00532 _reconnecting = true; 00533 _connection_handler.stop_listening(); 00534 _retry_timer_expired = false; 00535 _retry_timer.start_timer(_reconnection_time * 1000, 00536 M2MTimerObserver::RetryTimer); 00537 tr_info("M2MInterfaceImpl::socket_error - reconnecting in %" PRIu64 "(s)", _reconnection_time); 00538 _reconnection_time = _reconnection_time * RECONNECT_INCREMENT_FACTOR; 00539 if(_reconnection_time >= MAX_RECONNECT_TIMEOUT) { 00540 _reconnection_time = MAX_RECONNECT_TIMEOUT; 00541 } 00542 #ifndef DISABLE_ERROR_DESCRIPTION 00543 snprintf(_error_description, sizeof(_error_description), ERROR_REASON_9, error_code_des); 00544 #endif 00545 } 00546 // Inform application 00547 if (!retry && M2MInterface::ErrorNone != error) { 00548 tr_info("M2MInterfaceImpl::socket_error - send error to application"); 00549 _connection_handler.stop_listening(); 00550 _retry_timer.stop_timer(); 00551 _security = NULL; 00552 _reconnecting = false; 00553 _reconnection_time = _initial_reconnection_time; 00554 _reconnection_state = M2MInterfaceImpl::None; 00555 #ifndef DISABLE_ERROR_DESCRIPTION 00556 snprintf(_error_description, sizeof(_error_description), ERROR_REASON_10, error_code_des); 00557 #endif 00558 } 00559 if(M2MInterface::ErrorNone != error) { 00560 _observer.error(error); 00561 } 00562 } 00563 00564 void M2MInterfaceImpl::address_ready(const M2MConnectionObserver::SocketAddress &address, 00565 M2MConnectionObserver::ServerType server_type, 00566 const uint16_t server_port) 00567 { 00568 tr_debug("M2MInterfaceImpl::address_ready"); 00569 ResolvedAddressData data; 00570 data._address = &address; 00571 data._port = server_port; 00572 if( M2MConnectionObserver::Bootstrap == server_type) { 00573 tr_info("M2MInterfaceImpl::address_ready() Server Type Bootstrap"); 00574 internal_event(STATE_BOOTSTRAP_ADDRESS_RESOLVED, &data); 00575 } else { 00576 tr_info("M2MInterfaceImpl::address_ready() Server Type LWM2M"); 00577 internal_event(STATE_REGISTER_ADDRESS_RESOLVED, &data); 00578 } 00579 } 00580 00581 void M2MInterfaceImpl::data_sent() 00582 { 00583 tr_debug("M2MInterfaceImpl::data_sent()"); 00584 if(queue_mode()) { 00585 if(_callback_handler && (_nsdl_interface.get_unregister_ongoing() == false)) { 00586 _queue_sleep_timer.stop_timer(); 00587 // Multiply by two to get enough time for coap retransmissions. 00588 _queue_sleep_timer.start_timer(MBED_CLIENT_RECONNECTION_COUNT*MBED_CLIENT_RECONNECTION_INTERVAL*1000*2, 00589 M2MTimerObserver::QueueSleep); 00590 } 00591 } 00592 00593 if (_current_state == STATE_BOOTSTRAP_ERROR_WAIT) { 00594 // bootstrap_error to be called only after we have sent the last ACK. 00595 // Otherwise client will goto reconnection mode before ACK has sent. 00596 bootstrap_error(_error_description); 00597 } else if (_current_state != STATE_BOOTSTRAP_WAIT) { 00598 internal_event(STATE_COAP_DATA_SENT); 00599 } 00600 } 00601 00602 void M2MInterfaceImpl::timer_expired(M2MTimerObserver::Type type) 00603 { 00604 if(M2MTimerObserver::QueueSleep == type) { 00605 tr_debug("M2MInterfaceImpl::timer_expired() - sleep"); 00606 M2MTimer &timer = _nsdl_interface.get_nsdl_execution_timer(); 00607 timer.stop_timer(); 00608 _queue_mode_timer_ongoing = true; 00609 if(_callback_handler) { 00610 _callback_handler(); 00611 } 00612 } 00613 else if (M2MTimerObserver::RetryTimer == type) { 00614 tr_debug("M2MInterfaceImpl::timer_expired() - retry"); 00615 _retry_timer_expired = true; 00616 if (_bootstrapped) { 00617 internal_event(STATE_REGISTER); 00618 } else { 00619 internal_event(STATE_BOOTSTRAP); 00620 } 00621 } 00622 else if (M2MTimerObserver::BootstrapFlowTimer == type) { 00623 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00624 tr_debug("M2MInterfaceImpl::timer_expired() - bootstrap"); 00625 _bootstrapped = false; 00626 if (_registration_flow_timer) { 00627 _registration_flow_timer->stop_timer(); 00628 } 00629 bootstrap_error(ERROR_REASON_23); 00630 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00631 } 00632 else if (M2MTimerObserver::RegistrationFlowTimer == type) { 00633 tr_debug("M2MInterfaceImpl::timer_expired() - register"); 00634 registration_error(M2MInterface::Timeout, true); 00635 } 00636 } 00637 00638 // state machine sits here. 00639 void M2MInterfaceImpl::state_idle(EventData* /*data*/) 00640 { 00641 tr_debug("M2MInterfaceImpl::state_idle"); 00642 _nsdl_interface.stop_timers(); 00643 _nsdl_interface.clear_sent_blockwise_messages(); 00644 _queue_sleep_timer.stop_timer(); 00645 } 00646 00647 void M2MInterfaceImpl::state_bootstrap(EventData *data) 00648 { 00649 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00650 tr_debug("M2MInterfaceImpl::state_bootstrap"); 00651 // Start with bootstrapping preparation 00652 _bootstrapped = false; 00653 M2MSecurityData *event = static_cast<M2MSecurityData *> (data); 00654 if(!_security) { 00655 M2MInterface::Error error = M2MInterface::InvalidParameters; 00656 if (event) { 00657 _security = event->_object; 00658 if(_security) { 00659 int32_t bs_id = _security->get_security_instance_id(M2MSecurity::Bootstrap); 00660 tr_info("M2MInterfaceImpl::state_bootstrap - bs_id = %d", bs_id); 00661 if(bs_id >= 0) { 00662 String server_address = _security->resource_value_string(M2MSecurity::M2MServerUri, bs_id); 00663 _nsdl_interface.set_server_address(server_address.c_str()); 00664 tr_info("M2MInterfaceImpl::state_bootstrap - server_address %s", server_address.c_str()); 00665 String coap; 00666 if(server_address.compare(0,sizeof(COAP)-1,COAP) == 0) { 00667 coap = COAP; 00668 } 00669 else if(server_address.compare(0,sizeof(COAPS)-1,COAPS) == 0) { 00670 _security->resource_value_int(M2MSecurity::SecurityMode, bs_id) != M2MSecurity::NoSecurity ? coap = COAPS: coap = ""; 00671 } 00672 if(!coap.empty()) { 00673 server_address = server_address.substr(coap.size(), 00674 server_address.size()-coap.size()); 00675 00676 process_address(server_address, _server_ip_address, _server_port); 00677 00678 tr_info("M2MInterfaceImpl::state_bootstrap - IP address %s, Port %d", _server_ip_address.c_str(), _server_port); 00679 // If bind and resolving server address succeed then proceed else 00680 // return error to the application and go to Idle state. 00681 if(!_server_ip_address.empty()) { 00682 error = M2MInterface::ErrorNone; 00683 if (_registration_flow_timer) { 00684 _registration_flow_timer->stop_timer(); 00685 _registration_flow_timer->start_timer(MBED_CLIENT_RECONNECTION_COUNT * MBED_CLIENT_RECONNECTION_INTERVAL * 8 * 1000, 00686 M2MTimerObserver::BootstrapFlowTimer); 00687 } 00688 _connection_handler.resolve_server_address(_server_ip_address, 00689 _server_port, 00690 M2MConnectionObserver::Bootstrap, 00691 _security); 00692 } 00693 } 00694 } 00695 } 00696 } 00697 if (error != M2MInterface::ErrorNone) { 00698 tr_error("M2MInterfaceImpl::state_bootstrap - set error as M2MInterface::InvalidParameters"); 00699 internal_event(STATE_IDLE); 00700 set_error_description(ERROR_REASON_11); 00701 _observer.error(error); 00702 } 00703 } else { 00704 _listen_port = 0; 00705 _connection_handler.bind_connection(_listen_port); 00706 if (_registration_flow_timer) { 00707 _registration_flow_timer->stop_timer(); 00708 _registration_flow_timer->start_timer(MBED_CLIENT_RECONNECTION_COUNT * MBED_CLIENT_RECONNECTION_INTERVAL * 8 * 1000, 00709 M2MTimerObserver::BootstrapFlowTimer); 00710 } 00711 tr_info("M2MInterfaceImpl::state_bootstrap (reconnect) - IP address %s, Port %d", _server_ip_address.c_str(), _server_port); 00712 _connection_handler.resolve_server_address(_server_ip_address, 00713 _server_port, 00714 M2MConnectionObserver::Bootstrap, 00715 _security); 00716 } 00717 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00718 } 00719 00720 void M2MInterfaceImpl::state_bootstrap_address_resolved( EventData *data) 00721 { 00722 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00723 tr_debug("M2MInterfaceImpl::state_bootstrap_address_resolved"); 00724 if (data) { 00725 ResolvedAddressData *event = static_cast<ResolvedAddressData *> (data); 00726 sn_nsdl_addr_s address; 00727 00728 M2MInterface::NetworkStack stack = event->_address->_stack; 00729 00730 if(M2MInterface::LwIP_IPv4 == stack) { 00731 tr_info("M2MInterfaceImpl::state_bootstrap_address_resolved : IPv4 address"); 00732 address.type = SN_NSDL_ADDRESS_TYPE_IPV4; 00733 } else if((M2MInterface::LwIP_IPv6 == stack) || 00734 (M2MInterface::Nanostack_IPv6 == stack)) { 00735 tr_info("M2MInterfaceImpl::state_bootstrap_address_resolved : IPv6 address"); 00736 address.type = SN_NSDL_ADDRESS_TYPE_IPV6; 00737 } 00738 address.port = event->_port; 00739 address.addr_ptr = (uint8_t*)event->_address->_address; 00740 address.addr_len = event->_address->_length; 00741 _connection_handler.start_listening_for_data(); 00742 00743 if(_nsdl_interface.create_bootstrap_resource(&address)) { 00744 internal_event(STATE_BOOTSTRAP_RESOURCE_CREATED); 00745 } else{ 00746 // If resource creation fails then inform error to application 00747 tr_error("M2MInterfaceImpl::state_bootstrap_address_resolved : M2MInterface::InvalidParameters"); 00748 internal_event(STATE_IDLE); 00749 set_error_description(ERROR_REASON_12); 00750 _observer.error(M2MInterface::InvalidParameters); 00751 } 00752 } 00753 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00754 } 00755 00756 void M2MInterfaceImpl::state_bootstrap_resource_created( EventData */*data*/) 00757 { 00758 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00759 tr_debug("M2MInterfaceImpl::state_bootstrap_resource_created"); 00760 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00761 } 00762 00763 void M2MInterfaceImpl::state_bootstrapped( EventData */*data*/) 00764 { 00765 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00766 tr_debug("M2MInterfaceImpl::state_bootstrapped"); 00767 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00768 } 00769 00770 void M2MInterfaceImpl::state_register(EventData *data) 00771 { 00772 tr_debug("M2MInterfaceImpl::state_register"); 00773 M2MRegisterData *event = static_cast<M2MRegisterData *> (data); 00774 if (!_security) { 00775 M2MInterface::Error error = M2MInterface::InvalidParameters; 00776 // Start with registration preparation 00777 if(event) { 00778 _security = event->_object; 00779 if(_security) { 00780 int32_t m2m_id = _security->get_security_instance_id(M2MSecurity::M2MServer); 00781 if(m2m_id >= 0) { 00782 if(_nsdl_interface.create_nsdl_list_structure(event->_object_list)) { 00783 // If the nsdl resource structure is created successfully 00784 String server_address = _security->resource_value_string(M2MSecurity::M2MServerUri, m2m_id); 00785 _nsdl_interface.set_server_address(server_address.c_str()); 00786 tr_info("M2MInterfaceImpl::state_register - server_address %s", server_address.c_str()); 00787 String coap; 00788 if(server_address.compare(0,sizeof(COAP)-1,COAP) == 0) { 00789 coap = COAP; 00790 } 00791 else if(server_address.compare(0,sizeof(COAPS)-1,COAPS) == 0) { 00792 _security->resource_value_int(M2MSecurity::SecurityMode, m2m_id) != M2MSecurity::NoSecurity ? coap = COAPS: coap = ""; 00793 } 00794 if(!coap.empty()) { 00795 server_address = server_address.substr(coap.size(), 00796 server_address.size() - coap.size()); 00797 process_address(server_address, _server_ip_address, _server_port); 00798 00799 tr_info("M2MInterfaceImpl::state_register - IP address %s, Port %d", _server_ip_address.c_str(), _server_port); 00800 if(!_server_ip_address.empty()) { 00801 // Connection related errors are coming through callback 00802 if (_registration_flow_timer) { 00803 _registration_flow_timer->stop_timer(); 00804 _registration_flow_timer->start_timer(MBED_CLIENT_RECONNECTION_COUNT * MBED_CLIENT_RECONNECTION_INTERVAL * 8 * 1000, 00805 M2MTimerObserver::RegistrationFlowTimer); 00806 } 00807 _reconnection_state = M2MInterfaceImpl::FullRegistration; 00808 error = M2MInterface::ErrorNone; 00809 _connection_handler.resolve_server_address(_server_ip_address,_server_port, 00810 M2MConnectionObserver::LWM2MServer, 00811 _security); 00812 } 00813 } 00814 } else { 00815 tr_error("M2MInterfaceImpl::state_register - fail to create nsdl list structure!"); 00816 } 00817 } 00818 } 00819 } 00820 if (error != M2MInterface::ErrorNone) { 00821 tr_error("M2MInterfaceImpl::state_register - set error as M2MInterface::InvalidParameters"); 00822 internal_event(STATE_IDLE); 00823 set_error_description(ERROR_REASON_13); 00824 _observer.error(error); 00825 } 00826 } else { 00827 _listen_port = 0; 00828 if (event) { 00829 _nsdl_interface.create_nsdl_list_structure(event->_object_list); 00830 } 00831 _connection_handler.bind_connection(_listen_port); 00832 if (_registration_flow_timer) { 00833 _registration_flow_timer->stop_timer(); 00834 _registration_flow_timer->start_timer(MBED_CLIENT_RECONNECTION_COUNT * MBED_CLIENT_RECONNECTION_INTERVAL * 8 * 1000, 00835 M2MTimerObserver::RegistrationFlowTimer); 00836 } 00837 _reconnection_state = M2MInterfaceImpl::FullRegistration; 00838 tr_info("M2MInterfaceImpl::state_register (reconnect) - IP address %s, Port %d", _server_ip_address.c_str(), _server_port); 00839 _connection_handler.resolve_server_address(_server_ip_address,_server_port, 00840 M2MConnectionObserver::LWM2MServer, 00841 _security); 00842 } 00843 } 00844 00845 void M2MInterfaceImpl::process_address(const String& server_address, String& ip_address, uint16_t& port) { 00846 00847 int colonFound = server_address.find_last_of(':'); //10 00848 if(colonFound != -1) { 00849 ip_address = server_address.substr(0,colonFound); 00850 port = atoi(server_address.substr(colonFound+1, 00851 server_address.size()-ip_address.size()).c_str()); 00852 colonFound = ip_address.find_last_of(']'); 00853 if(ip_address.compare(0,1,"[") == 0) { 00854 if(colonFound == -1) { 00855 ip_address.clear(); 00856 } else { 00857 ip_address = ip_address.substr(1,colonFound-1); 00858 } 00859 } else if(colonFound != -1) { 00860 ip_address.clear(); 00861 } 00862 } 00863 } 00864 00865 void M2MInterfaceImpl::state_register_address_resolved( EventData *data) 00866 { 00867 tr_debug("M2MInterfaceImpl::state_register_address_resolved"); 00868 if(data) { 00869 ResolvedAddressData *event = static_cast<ResolvedAddressData *> (data); 00870 00871 sn_nsdl_addr_type_e address_type = SN_NSDL_ADDRESS_TYPE_IPV6; 00872 00873 M2MInterface::NetworkStack stack = event->_address->_stack; 00874 00875 if(M2MInterface::LwIP_IPv4 == stack) { 00876 tr_info("M2MInterfaceImpl::state_register_address_resolved : IPv4 address"); 00877 address_type = SN_NSDL_ADDRESS_TYPE_IPV4; 00878 } else if((M2MInterface::LwIP_IPv6 == stack) || 00879 (M2MInterface::Nanostack_IPv6 == stack)) { 00880 tr_info("M2MInterfaceImpl::state_register_address_resolved : IPv6 address"); 00881 address_type = SN_NSDL_ADDRESS_TYPE_IPV6; 00882 } 00883 _connection_handler.start_listening_for_data(); 00884 _nsdl_interface.set_server_address((uint8_t*)event->_address->_address,event->_address->_length, 00885 event->_port, address_type); 00886 switch (_reconnection_state) { 00887 case M2MInterfaceImpl::None: 00888 case M2MInterfaceImpl::FullRegistration: 00889 if(!_nsdl_interface.send_register_message()) { 00890 // If resource creation fails then inform error to application 00891 tr_error("M2MInterfaceImpl::state_register_address_resolved : M2MInterface::MemoryFail"); 00892 internal_event(STATE_IDLE); 00893 set_error_description(ERROR_REASON_25); 00894 _observer.error(M2MInterface::MemoryFail); 00895 } 00896 break; 00897 case M2MInterfaceImpl::Unregistration: 00898 case M2MInterfaceImpl::WithUpdate: 00899 // Start registration update in case it is reconnection logic because of network issue. 00900 internal_event(STATE_UPDATE_REGISTRATION); 00901 break; 00902 } 00903 } 00904 } 00905 00906 void M2MInterfaceImpl::state_registered( EventData */*data*/) 00907 { 00908 tr_info("M2MInterfaceImpl::state_registered"); 00909 if (_registration_flow_timer) { 00910 _registration_flow_timer->stop_timer(); 00911 } 00912 _reconnection_time = _initial_reconnection_time; 00913 _reconnecting = false; 00914 00915 // Continue with the unregistration process if it has failed due to connection lost 00916 if (_reconnection_state == M2MInterfaceImpl::Unregistration) { 00917 internal_event(STATE_UNREGISTER); 00918 } 00919 00920 _reconnection_state = M2MInterfaceImpl::None; 00921 } 00922 00923 void M2MInterfaceImpl::state_update_registration(EventData *data) 00924 { 00925 tr_debug("M2MInterfaceImpl::state_update_registration"); 00926 uint32_t lifetime = 0; 00927 bool clear_queue = false; 00928 // Set to false to allow reconnection to work. 00929 _queue_mode_timer_ongoing = false; 00930 00931 if(data) { 00932 M2MUpdateRegisterData *event = static_cast<M2MUpdateRegisterData *> (data); 00933 // Create new resources if any 00934 if (!event->_object_list.empty()) { 00935 _nsdl_interface.create_nsdl_list_structure(event->_object_list); 00936 } 00937 lifetime = event->_lifetime; 00938 } else { 00939 clear_queue = true; 00940 } 00941 00942 bool success = _nsdl_interface.send_update_registration(lifetime, clear_queue); 00943 if(!success) { 00944 if(_reconnection_state == M2MInterfaceImpl::WithUpdate) { 00945 if (_reconnection_state != M2MInterfaceImpl::Unregistration) { 00946 _reconnection_state = M2MInterfaceImpl::FullRegistration; 00947 if(!_nsdl_interface.send_register_message()) { 00948 tr_error("M2MInterfaceImpl::state_update_registration : M2MInterface::MemoryFail"); 00949 internal_event(STATE_IDLE); 00950 set_error_description(ERROR_REASON_25); 00951 _observer.error(M2MInterface::MemoryFail); 00952 } 00953 } 00954 } 00955 } 00956 } 00957 00958 void M2MInterfaceImpl::state_unregister(EventData */*data*/) 00959 { 00960 tr_debug("M2MInterfaceImpl::state_unregister"); 00961 internal_event(STATE_SENDING_COAP_DATA); 00962 if(!_nsdl_interface.send_unregister_message()) { 00963 tr_error("M2MInterfaceImpl::state_unregister : M2MInterface::NotRegistered"); 00964 internal_event(STATE_IDLE); 00965 set_error_description(ERROR_REASON_16); 00966 _observer.error(M2MInterface::NotRegistered); 00967 } 00968 } 00969 00970 void M2MInterfaceImpl::state_unregistered( EventData */*data*/) 00971 { 00972 tr_info("M2MInterfaceImpl::state_unregistered"); 00973 _reconnection_time = _initial_reconnection_time; 00974 _connection_handler.stop_listening(); 00975 internal_event(STATE_IDLE); 00976 } 00977 00978 void M2MInterfaceImpl::state_sending_coap_data( EventData */*data*/) 00979 { 00980 tr_debug("M2MInterfaceImpl::state_sending_coap_data"); 00981 _nsdl_interface.start_nsdl_execution_timer(); 00982 internal_event(STATE_WAITING); 00983 } 00984 00985 void M2MInterfaceImpl::state_coap_data_sent( EventData */*data*/) 00986 { 00987 tr_debug("M2MInterfaceImpl::state_coap_data_sent"); 00988 internal_event(STATE_WAITING); 00989 } 00990 00991 void M2MInterfaceImpl::state_coap_data_received( EventData *data) 00992 { 00993 tr_debug("M2MInterfaceImpl::state_coap_data_received"); 00994 if(data) { 00995 ReceivedData *event = static_cast<ReceivedData*> (data); 00996 sn_nsdl_addr_s address; 00997 00998 M2MInterface::NetworkStack stack = event->_address->_stack; 00999 01000 if(M2MInterface::LwIP_IPv4 == stack) { 01001 address.type = SN_NSDL_ADDRESS_TYPE_IPV4; 01002 address.addr_len = 4; 01003 } else if((M2MInterface::LwIP_IPv6 == stack) || 01004 (M2MInterface::Nanostack_IPv6 == stack)) { 01005 address.type = SN_NSDL_ADDRESS_TYPE_IPV6; 01006 address.addr_len = 16; 01007 } 01008 address.port = event->_address->_port; 01009 address.addr_ptr = (uint8_t*)event->_address->_address; 01010 address.addr_len = event->_address->_length; 01011 01012 // Process received data 01013 internal_event(STATE_PROCESSING_COAP_DATA); 01014 if(!_nsdl_interface.process_received_data(event->_data, 01015 event->_size, 01016 &address)) { 01017 tr_error("M2MInterfaceImpl::state_coap_data_received : M2MInterface::ResponseParseFailed"); 01018 set_error_description(ERROR_REASON_17); 01019 _observer.error(M2MInterface::ResponseParseFailed); 01020 } 01021 } 01022 } 01023 01024 void M2MInterfaceImpl::state_processing_coap_data( EventData */*data*/) 01025 { 01026 tr_debug("M2MInterfaceImpl::state_processing_coap_data"); 01027 internal_event(STATE_WAITING); 01028 } 01029 01030 void M2MInterfaceImpl::state_coap_data_processed( EventData */*data*/) 01031 { 01032 tr_debug("M2MInterfaceImpl::state_coap_data_processed"); 01033 internal_event(STATE_WAITING); 01034 } 01035 01036 void M2MInterfaceImpl::state_waiting( EventData */*data*/) 01037 { 01038 tr_debug("M2MInterfaceImpl::state_waiting"); 01039 } 01040 01041 // generates an external event. called once per external event 01042 // to start the state machine executing 01043 void M2MInterfaceImpl::external_event(uint8_t new_state, 01044 EventData* p_data) 01045 { 01046 tr_debug("M2MInterfaceImpl::external_event : new state %d", new_state); 01047 // if we are supposed to ignore this event 01048 if (new_state == EVENT_IGNORED) { 01049 tr_debug("M2MInterfaceImpl::external_event : new state is EVENT_IGNORED"); 01050 _event_ignored = true; 01051 } 01052 else { 01053 tr_debug("M2MInterfaceImpl::external_event : handle new state"); 01054 // generate the event and execute the state engine 01055 internal_event(new_state, p_data); 01056 } 01057 } 01058 01059 // generates an internal event. called from within a state 01060 // function to transition to a new state 01061 void M2MInterfaceImpl::internal_event(uint8_t new_state, 01062 EventData* p_data) 01063 { 01064 tr_debug("M2MInterfaceImpl::internal_event : new state %d", new_state); 01065 _event_data = p_data; 01066 _event_generated = true; 01067 _current_state = new_state; 01068 state_engine(); 01069 } 01070 01071 // the state engine executes the state machine states 01072 void M2MInterfaceImpl::state_engine (void) 01073 { 01074 tr_debug("M2MInterfaceImpl::state_engine"); 01075 EventData* p_data_temp = NULL; 01076 01077 // while events are being generated keep executing states 01078 while (_event_generated) { 01079 p_data_temp = _event_data; // copy of event data pointer 01080 _event_data = NULL; // event data used up, reset ptr 01081 _event_generated = false; // event used up, reset flag 01082 01083 assert(_current_state < _max_states); 01084 01085 state_function( _current_state, p_data_temp ); 01086 } 01087 } 01088 01089 void M2MInterfaceImpl::state_function( uint8_t current_state, EventData* data ) 01090 { 01091 switch( current_state ) { 01092 case STATE_IDLE: 01093 M2MInterfaceImpl::state_idle(data); 01094 break; 01095 case STATE_BOOTSTRAP: 01096 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01097 M2MInterfaceImpl::state_bootstrap(data); 01098 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01099 break; 01100 case STATE_BOOTSTRAP_ADDRESS_RESOLVED: 01101 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01102 M2MInterfaceImpl::state_bootstrap_address_resolved(data); 01103 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01104 break; 01105 case STATE_BOOTSTRAP_RESOURCE_CREATED: 01106 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01107 M2MInterfaceImpl::state_bootstrap_resource_created(data); 01108 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01109 break; 01110 case STATE_BOOTSTRAP_WAIT: 01111 case STATE_BOOTSTRAP_ERROR_WAIT: 01112 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01113 // Do nothing, we're just waiting for data_sent callback 01114 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01115 break; 01116 case STATE_BOOTSTRAPPED: 01117 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01118 M2MInterfaceImpl::state_bootstrapped(data); 01119 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01120 break; 01121 case STATE_REGISTER: 01122 M2MInterfaceImpl::state_register(data); 01123 break; 01124 case STATE_REGISTER_ADDRESS_RESOLVED: 01125 M2MInterfaceImpl::state_register_address_resolved(data); 01126 break; 01127 case STATE_REGISTERED: 01128 M2MInterfaceImpl::state_registered(data); 01129 break; 01130 case STATE_UPDATE_REGISTRATION: 01131 M2MInterfaceImpl::state_update_registration(data); 01132 break; 01133 case STATE_UNREGISTER: 01134 M2MInterfaceImpl::state_unregister(data); 01135 break; 01136 case STATE_UNREGISTERED: 01137 M2MInterfaceImpl::state_unregistered(data); 01138 break; 01139 case STATE_SENDING_COAP_DATA: 01140 M2MInterfaceImpl::state_sending_coap_data(data); 01141 break; 01142 case STATE_COAP_DATA_SENT: 01143 M2MInterfaceImpl::state_coap_data_sent(data); 01144 break; 01145 case STATE_COAP_DATA_RECEIVED: 01146 M2MInterfaceImpl::state_coap_data_received(data); 01147 break; 01148 case STATE_PROCESSING_COAP_DATA: 01149 M2MInterfaceImpl::state_processing_coap_data(data); 01150 break; 01151 case STATE_COAP_DATA_PROCESSED: 01152 M2MInterfaceImpl::state_coap_data_processed(data); 01153 break; 01154 case STATE_WAITING: 01155 M2MInterfaceImpl::state_waiting(data); 01156 break; 01157 } 01158 } 01159 01160 void M2MInterfaceImpl::start_register_update(M2MUpdateRegisterData *data) { 01161 tr_debug("M2MInterfaceImpl::start_register_update()"); 01162 if(!data || (data->_lifetime != 0 && (data->_lifetime < MINIMUM_REGISTRATION_TIME))) { 01163 set_error_description(ERROR_REASON_18); 01164 _observer.error(M2MInterface::InvalidParameters); 01165 } 01166 01167 if (_reconnecting) { 01168 //If client is in reconnection mode, ignore this call, state machine will reconnect on its own. 01169 return; 01170 } 01171 01172 _reconnection_state = M2MInterfaceImpl::WithUpdate; 01173 BEGIN_TRANSITION_MAP // - Current State - 01174 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_idle 01175 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap 01176 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state__bootstrap_address_resolved 01177 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_resource_created 01178 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_wait 01179 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_error_wait 01180 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrapped 01181 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register 01182 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_address_resolved 01183 TRANSITION_MAP_ENTRY (STATE_UPDATE_REGISTRATION) // state_registered 01184 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_update_registration 01185 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregister 01186 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregistered 01187 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_sending_coap_data 01188 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_sent 01189 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_received 01190 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_processing_coap_data 01191 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_processed 01192 TRANSITION_MAP_ENTRY (STATE_UPDATE_REGISTRATION) // state_waiting 01193 END_TRANSITION_MAP(data) 01194 if(_event_ignored) { 01195 _event_ignored = false; 01196 if (!_reconnecting) { 01197 set_error_description(ERROR_REASON_19); 01198 _observer.error(M2MInterface::NotAllowed); 01199 } 01200 } 01201 } 01202 01203 void M2MInterfaceImpl::update_endpoint(String &name) { 01204 _nsdl_interface.update_endpoint(name); 01205 } 01206 01207 void M2MInterfaceImpl::update_domain(String &domain) 01208 { 01209 _nsdl_interface.update_domain(domain); 01210 } 01211 01212 const String M2MInterfaceImpl::internal_endpoint_name() const 01213 { 01214 return _nsdl_interface.internal_endpoint_name(); 01215 } 01216 01217 const char *M2MInterfaceImpl::error_description() const 01218 { 01219 #ifndef DISABLE_ERROR_DESCRIPTION 01220 return _error_description; 01221 #else 01222 return ""; 01223 #endif 01224 } 01225 01226 void M2MInterfaceImpl::set_error_description(const char *description) 01227 { 01228 #ifndef DISABLE_ERROR_DESCRIPTION 01229 if (strncmp(_error_description, description, sizeof(_error_description)) != 0) { 01230 strncpy(_error_description, description, MAX_ALLOWED_ERROR_STRING_LENGTH - 1); 01231 } 01232 #endif 01233 } 01234 01235 bool M2MInterfaceImpl::queue_mode() const 01236 { 01237 return (_binding_mode == M2MInterface::UDP_QUEUE || 01238 _binding_mode == M2MInterface::TCP_QUEUE || 01239 _binding_mode == M2MInterface::SMS_QUEUE || 01240 _binding_mode == M2MInterface::UDP_SMS_QUEUE); 01241 } 01242 01243 void M2MInterfaceImpl::get_data_request(const char *uri, 01244 const size_t offset, 01245 const bool async, 01246 get_data_cb data_cb, 01247 get_data_error_cb error_cb, 01248 void *context) 01249 { 01250 get_data_req_error_e error = FAILED_TO_SEND_MSG; 01251 if(_current_state != STATE_IDLE && uri) { 01252 if (!_nsdl_interface.send_get_data_request(uri, offset, async, data_cb, error_cb, context)) { 01253 error_cb(error, context); 01254 } 01255 } 01256 else { 01257 error_cb(error, context); 01258 } 01259 } 01260 01261 bool M2MInterfaceImpl::set_uri_query_parameters(const char *uri_query_params) 01262 { 01263 return _nsdl_interface.set_uri_query_parameters(uri_query_params); 01264 }
Generated on Tue Jul 12 2022 19:01:35 by
1.7.2