Toyomasa Watarai
/
Mbed-example-WS-W27
Mbed Cloud example program for workshop in W27 2018.
Embed:
(wiki syntax)
Show/hide line numbers
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 _queue_sleep_timer.stop_timer(); 00644 } 00645 00646 void M2MInterfaceImpl::state_bootstrap(EventData *data) 00647 { 00648 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00649 tr_debug("M2MInterfaceImpl::state_bootstrap"); 00650 // Start with bootstrapping preparation 00651 _bootstrapped = false; 00652 M2MSecurityData *event = static_cast<M2MSecurityData *> (data); 00653 if(!_security) { 00654 M2MInterface::Error error = M2MInterface::InvalidParameters; 00655 if (event) { 00656 _security = event->_object; 00657 if(_security) { 00658 int32_t bs_id = _security->get_security_instance_id(M2MSecurity::Bootstrap); 00659 tr_info("M2MInterfaceImpl::state_bootstrap - bs_id = %d", bs_id); 00660 if(bs_id >= 0) { 00661 String server_address = _security->resource_value_string(M2MSecurity::M2MServerUri, bs_id); 00662 _nsdl_interface.set_server_address(server_address.c_str()); 00663 tr_info("M2MInterfaceImpl::state_bootstrap - server_address %s", server_address.c_str()); 00664 String coap; 00665 if(server_address.compare(0,sizeof(COAP)-1,COAP) == 0) { 00666 coap = COAP; 00667 } 00668 else if(server_address.compare(0,sizeof(COAPS)-1,COAPS) == 0) { 00669 _security->resource_value_int(M2MSecurity::SecurityMode, bs_id) != M2MSecurity::NoSecurity ? coap = COAPS: coap = ""; 00670 } 00671 if(!coap.empty()) { 00672 server_address = server_address.substr(coap.size(), 00673 server_address.size()-coap.size()); 00674 00675 process_address(server_address, _server_ip_address, _server_port); 00676 00677 tr_info("M2MInterfaceImpl::state_bootstrap - IP address %s, Port %d", _server_ip_address.c_str(), _server_port); 00678 // If bind and resolving server address succeed then proceed else 00679 // return error to the application and go to Idle state. 00680 if(!_server_ip_address.empty()) { 00681 error = M2MInterface::ErrorNone; 00682 if (_registration_flow_timer) { 00683 _registration_flow_timer->stop_timer(); 00684 _registration_flow_timer->start_timer(MBED_CLIENT_RECONNECTION_COUNT * MBED_CLIENT_RECONNECTION_INTERVAL * 8 * 1000, 00685 M2MTimerObserver::BootstrapFlowTimer); 00686 } 00687 _connection_handler.resolve_server_address(_server_ip_address, 00688 _server_port, 00689 M2MConnectionObserver::Bootstrap, 00690 _security); 00691 } 00692 } 00693 } 00694 } 00695 } 00696 if (error != M2MInterface::ErrorNone) { 00697 tr_error("M2MInterfaceImpl::state_bootstrap - set error as M2MInterface::InvalidParameters"); 00698 internal_event(STATE_IDLE); 00699 set_error_description(ERROR_REASON_11); 00700 _observer.error(error); 00701 } 00702 } else { 00703 _listen_port = 0; 00704 _connection_handler.bind_connection(_listen_port); 00705 if (_registration_flow_timer) { 00706 _registration_flow_timer->stop_timer(); 00707 _registration_flow_timer->start_timer(MBED_CLIENT_RECONNECTION_COUNT * MBED_CLIENT_RECONNECTION_INTERVAL * 8 * 1000, 00708 M2MTimerObserver::BootstrapFlowTimer); 00709 } 00710 tr_info("M2MInterfaceImpl::state_bootstrap (reconnect) - IP address %s, Port %d", _server_ip_address.c_str(), _server_port); 00711 _connection_handler.resolve_server_address(_server_ip_address, 00712 _server_port, 00713 M2MConnectionObserver::Bootstrap, 00714 _security); 00715 } 00716 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00717 } 00718 00719 void M2MInterfaceImpl::state_bootstrap_address_resolved( EventData *data) 00720 { 00721 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00722 tr_debug("M2MInterfaceImpl::state_bootstrap_address_resolved"); 00723 if (data) { 00724 ResolvedAddressData *event = static_cast<ResolvedAddressData *> (data); 00725 sn_nsdl_addr_s address; 00726 00727 M2MInterface::NetworkStack stack = event->_address->_stack; 00728 00729 if(M2MInterface::LwIP_IPv4 == stack) { 00730 tr_info("M2MInterfaceImpl::state_bootstrap_address_resolved : IPv4 address"); 00731 address.type = SN_NSDL_ADDRESS_TYPE_IPV4; 00732 } else if((M2MInterface::LwIP_IPv6 == stack) || 00733 (M2MInterface::Nanostack_IPv6 == stack)) { 00734 tr_info("M2MInterfaceImpl::state_bootstrap_address_resolved : IPv6 address"); 00735 address.type = SN_NSDL_ADDRESS_TYPE_IPV6; 00736 } 00737 address.port = event->_port; 00738 address.addr_ptr = (uint8_t*)event->_address->_address; 00739 address.addr_len = event->_address->_length; 00740 _connection_handler.start_listening_for_data(); 00741 00742 if(_nsdl_interface.create_bootstrap_resource(&address)) { 00743 internal_event(STATE_BOOTSTRAP_RESOURCE_CREATED); 00744 } else{ 00745 // If resource creation fails then inform error to application 00746 tr_error("M2MInterfaceImpl::state_bootstrap_address_resolved : M2MInterface::InvalidParameters"); 00747 internal_event(STATE_IDLE); 00748 set_error_description(ERROR_REASON_12); 00749 _observer.error(M2MInterface::InvalidParameters); 00750 } 00751 } 00752 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00753 } 00754 00755 void M2MInterfaceImpl::state_bootstrap_resource_created( EventData */*data*/) 00756 { 00757 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00758 tr_debug("M2MInterfaceImpl::state_bootstrap_resource_created"); 00759 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00760 } 00761 00762 void M2MInterfaceImpl::state_bootstrapped( EventData */*data*/) 00763 { 00764 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00765 tr_debug("M2MInterfaceImpl::state_bootstrapped"); 00766 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00767 } 00768 00769 void M2MInterfaceImpl::state_register(EventData *data) 00770 { 00771 tr_debug("M2MInterfaceImpl::state_register"); 00772 M2MRegisterData *event = static_cast<M2MRegisterData *> (data); 00773 if (!_security) { 00774 M2MInterface::Error error = M2MInterface::InvalidParameters; 00775 // Start with registration preparation 00776 if(event) { 00777 _security = event->_object; 00778 if(_security) { 00779 int32_t m2m_id = _security->get_security_instance_id(M2MSecurity::M2MServer); 00780 if(m2m_id >= 0) { 00781 if(_nsdl_interface.create_nsdl_list_structure(event->_object_list)) { 00782 // If the nsdl resource structure is created successfully 00783 String server_address = _security->resource_value_string(M2MSecurity::M2MServerUri, m2m_id); 00784 _nsdl_interface.set_server_address(server_address.c_str()); 00785 tr_info("M2MInterfaceImpl::state_register - server_address %s", server_address.c_str()); 00786 String coap; 00787 if(server_address.compare(0,sizeof(COAP)-1,COAP) == 0) { 00788 coap = COAP; 00789 } 00790 else if(server_address.compare(0,sizeof(COAPS)-1,COAPS) == 0) { 00791 _security->resource_value_int(M2MSecurity::SecurityMode, m2m_id) != M2MSecurity::NoSecurity ? coap = COAPS: coap = ""; 00792 } 00793 if(!coap.empty()) { 00794 server_address = server_address.substr(coap.size(), 00795 server_address.size() - coap.size()); 00796 process_address(server_address, _server_ip_address, _server_port); 00797 00798 tr_info("M2MInterfaceImpl::state_register - IP address %s, Port %d", _server_ip_address.c_str(), _server_port); 00799 if(!_server_ip_address.empty()) { 00800 // Connection related errors are coming through callback 00801 if (_registration_flow_timer) { 00802 _registration_flow_timer->stop_timer(); 00803 _registration_flow_timer->start_timer(MBED_CLIENT_RECONNECTION_COUNT * MBED_CLIENT_RECONNECTION_INTERVAL * 8 * 1000, 00804 M2MTimerObserver::RegistrationFlowTimer); 00805 } 00806 _reconnection_state = M2MInterfaceImpl::FullRegistration; 00807 error = M2MInterface::ErrorNone; 00808 _connection_handler.resolve_server_address(_server_ip_address,_server_port, 00809 M2MConnectionObserver::LWM2MServer, 00810 _security); 00811 } 00812 } 00813 } else { 00814 tr_error("M2MInterfaceImpl::state_register - fail to create nsdl list structure!"); 00815 } 00816 } 00817 } 00818 } 00819 if (error != M2MInterface::ErrorNone) { 00820 tr_error("M2MInterfaceImpl::state_register - set error as M2MInterface::InvalidParameters"); 00821 internal_event(STATE_IDLE); 00822 set_error_description(ERROR_REASON_13); 00823 _observer.error(error); 00824 } 00825 } else { 00826 _listen_port = 0; 00827 if (event) { 00828 _nsdl_interface.create_nsdl_list_structure(event->_object_list); 00829 } 00830 _connection_handler.bind_connection(_listen_port); 00831 if (_registration_flow_timer) { 00832 _registration_flow_timer->stop_timer(); 00833 _registration_flow_timer->start_timer(MBED_CLIENT_RECONNECTION_COUNT * MBED_CLIENT_RECONNECTION_INTERVAL * 8 * 1000, 00834 M2MTimerObserver::RegistrationFlowTimer); 00835 } 00836 _reconnection_state = M2MInterfaceImpl::FullRegistration; 00837 tr_info("M2MInterfaceImpl::state_register (reconnect) - IP address %s, Port %d", _server_ip_address.c_str(), _server_port); 00838 _connection_handler.resolve_server_address(_server_ip_address,_server_port, 00839 M2MConnectionObserver::LWM2MServer, 00840 _security); 00841 } 00842 } 00843 00844 void M2MInterfaceImpl::process_address(const String& server_address, String& ip_address, uint16_t& port) { 00845 00846 int colonFound = server_address.find_last_of(':'); //10 00847 if(colonFound != -1) { 00848 ip_address = server_address.substr(0,colonFound); 00849 port = atoi(server_address.substr(colonFound+1, 00850 server_address.size()-ip_address.size()).c_str()); 00851 colonFound = ip_address.find_last_of(']'); 00852 if(ip_address.compare(0,1,"[") == 0) { 00853 if(colonFound == -1) { 00854 ip_address.clear(); 00855 } else { 00856 ip_address = ip_address.substr(1,colonFound-1); 00857 } 00858 } else if(colonFound != -1) { 00859 ip_address.clear(); 00860 } 00861 } 00862 } 00863 00864 void M2MInterfaceImpl::state_register_address_resolved( EventData *data) 00865 { 00866 tr_debug("M2MInterfaceImpl::state_register_address_resolved"); 00867 if(data) { 00868 ResolvedAddressData *event = static_cast<ResolvedAddressData *> (data); 00869 00870 sn_nsdl_addr_type_e address_type = SN_NSDL_ADDRESS_TYPE_IPV6; 00871 00872 M2MInterface::NetworkStack stack = event->_address->_stack; 00873 00874 if(M2MInterface::LwIP_IPv4 == stack) { 00875 tr_info("M2MInterfaceImpl::state_register_address_resolved : IPv4 address"); 00876 address_type = SN_NSDL_ADDRESS_TYPE_IPV4; 00877 } else if((M2MInterface::LwIP_IPv6 == stack) || 00878 (M2MInterface::Nanostack_IPv6 == stack)) { 00879 tr_info("M2MInterfaceImpl::state_register_address_resolved : IPv6 address"); 00880 address_type = SN_NSDL_ADDRESS_TYPE_IPV6; 00881 } 00882 _connection_handler.start_listening_for_data(); 00883 _nsdl_interface.set_server_address((uint8_t*)event->_address->_address,event->_address->_length, 00884 event->_port, address_type); 00885 switch (_reconnection_state) { 00886 case M2MInterfaceImpl::None: 00887 case M2MInterfaceImpl::FullRegistration: 00888 if(!_nsdl_interface.send_register_message()) { 00889 // If resource creation fails then inform error to application 00890 tr_error("M2MInterfaceImpl::state_register_address_resolved : M2MInterface::MemoryFail"); 00891 internal_event(STATE_IDLE); 00892 set_error_description(ERROR_REASON_25); 00893 _observer.error(M2MInterface::MemoryFail); 00894 } 00895 break; 00896 case M2MInterfaceImpl::Unregistration: 00897 case M2MInterfaceImpl::WithUpdate: 00898 // Start registration update in case it is reconnection logic because of network issue. 00899 internal_event(STATE_UPDATE_REGISTRATION); 00900 break; 00901 } 00902 } 00903 } 00904 00905 void M2MInterfaceImpl::state_registered( EventData */*data*/) 00906 { 00907 tr_info("M2MInterfaceImpl::state_registered"); 00908 if (_registration_flow_timer) { 00909 _registration_flow_timer->stop_timer(); 00910 } 00911 _reconnection_time = _initial_reconnection_time; 00912 _reconnecting = false; 00913 00914 // Continue with the unregistration process if it has failed due to connection lost 00915 if (_reconnection_state == M2MInterfaceImpl::Unregistration) { 00916 internal_event(STATE_UNREGISTER); 00917 } 00918 00919 _reconnection_state = M2MInterfaceImpl::None; 00920 } 00921 00922 void M2MInterfaceImpl::state_update_registration(EventData *data) 00923 { 00924 tr_debug("M2MInterfaceImpl::state_update_registration"); 00925 uint32_t lifetime = 0; 00926 bool clear_queue = false; 00927 // Set to false to allow reconnection to work. 00928 _queue_mode_timer_ongoing = false; 00929 00930 if(data) { 00931 M2MUpdateRegisterData *event = static_cast<M2MUpdateRegisterData *> (data); 00932 // Create new resources if any 00933 if (!event->_object_list.empty()) { 00934 _nsdl_interface.create_nsdl_list_structure(event->_object_list); 00935 } 00936 lifetime = event->_lifetime; 00937 } else { 00938 clear_queue = true; 00939 } 00940 00941 bool success = _nsdl_interface.send_update_registration(lifetime, clear_queue); 00942 if(!success) { 00943 if(_reconnection_state == M2MInterfaceImpl::WithUpdate) { 00944 if (_reconnection_state != M2MInterfaceImpl::Unregistration) { 00945 _reconnection_state = M2MInterfaceImpl::FullRegistration; 00946 if(!_nsdl_interface.send_register_message()) { 00947 tr_error("M2MInterfaceImpl::state_update_registration : M2MInterface::MemoryFail"); 00948 internal_event(STATE_IDLE); 00949 set_error_description(ERROR_REASON_25); 00950 _observer.error(M2MInterface::MemoryFail); 00951 } 00952 } 00953 } 00954 } 00955 } 00956 00957 void M2MInterfaceImpl::state_unregister(EventData */*data*/) 00958 { 00959 tr_debug("M2MInterfaceImpl::state_unregister"); 00960 internal_event(STATE_SENDING_COAP_DATA); 00961 if(!_nsdl_interface.send_unregister_message()) { 00962 tr_error("M2MInterfaceImpl::state_unregister : M2MInterface::NotRegistered"); 00963 internal_event(STATE_IDLE); 00964 set_error_description(ERROR_REASON_16); 00965 _observer.error(M2MInterface::NotRegistered); 00966 } 00967 } 00968 00969 void M2MInterfaceImpl::state_unregistered( EventData */*data*/) 00970 { 00971 tr_info("M2MInterfaceImpl::state_unregistered"); 00972 _reconnection_time = _initial_reconnection_time; 00973 _connection_handler.stop_listening(); 00974 internal_event(STATE_IDLE); 00975 } 00976 00977 void M2MInterfaceImpl::state_sending_coap_data( EventData */*data*/) 00978 { 00979 tr_debug("M2MInterfaceImpl::state_sending_coap_data"); 00980 _nsdl_interface.start_nsdl_execution_timer(); 00981 internal_event(STATE_WAITING); 00982 } 00983 00984 void M2MInterfaceImpl::state_coap_data_sent( EventData */*data*/) 00985 { 00986 tr_debug("M2MInterfaceImpl::state_coap_data_sent"); 00987 internal_event(STATE_WAITING); 00988 } 00989 00990 void M2MInterfaceImpl::state_coap_data_received( EventData *data) 00991 { 00992 tr_debug("M2MInterfaceImpl::state_coap_data_received"); 00993 if(data) { 00994 ReceivedData *event = static_cast<ReceivedData*> (data); 00995 sn_nsdl_addr_s address; 00996 00997 M2MInterface::NetworkStack stack = event->_address->_stack; 00998 00999 if(M2MInterface::LwIP_IPv4 == stack) { 01000 address.type = SN_NSDL_ADDRESS_TYPE_IPV4; 01001 address.addr_len = 4; 01002 } else if((M2MInterface::LwIP_IPv6 == stack) || 01003 (M2MInterface::Nanostack_IPv6 == stack)) { 01004 address.type = SN_NSDL_ADDRESS_TYPE_IPV6; 01005 address.addr_len = 16; 01006 } 01007 address.port = event->_address->_port; 01008 address.addr_ptr = (uint8_t*)event->_address->_address; 01009 address.addr_len = event->_address->_length; 01010 01011 // Process received data 01012 internal_event(STATE_PROCESSING_COAP_DATA); 01013 if(!_nsdl_interface.process_received_data(event->_data, 01014 event->_size, 01015 &address)) { 01016 tr_error("M2MInterfaceImpl::state_coap_data_received : M2MInterface::ResponseParseFailed"); 01017 set_error_description(ERROR_REASON_17); 01018 _observer.error(M2MInterface::ResponseParseFailed); 01019 } 01020 } 01021 } 01022 01023 void M2MInterfaceImpl::state_processing_coap_data( EventData */*data*/) 01024 { 01025 tr_debug("M2MInterfaceImpl::state_processing_coap_data"); 01026 internal_event(STATE_WAITING); 01027 } 01028 01029 void M2MInterfaceImpl::state_coap_data_processed( EventData */*data*/) 01030 { 01031 tr_debug("M2MInterfaceImpl::state_coap_data_processed"); 01032 internal_event(STATE_WAITING); 01033 } 01034 01035 void M2MInterfaceImpl::state_waiting( EventData */*data*/) 01036 { 01037 tr_debug("M2MInterfaceImpl::state_waiting"); 01038 } 01039 01040 // generates an external event. called once per external event 01041 // to start the state machine executing 01042 void M2MInterfaceImpl::external_event(uint8_t new_state, 01043 EventData* p_data) 01044 { 01045 tr_debug("M2MInterfaceImpl::external_event : new state %d", new_state); 01046 // if we are supposed to ignore this event 01047 if (new_state == EVENT_IGNORED) { 01048 tr_debug("M2MInterfaceImpl::external_event : new state is EVENT_IGNORED"); 01049 _event_ignored = true; 01050 } 01051 else { 01052 tr_debug("M2MInterfaceImpl::external_event : handle new state"); 01053 // generate the event and execute the state engine 01054 internal_event(new_state, p_data); 01055 } 01056 } 01057 01058 // generates an internal event. called from within a state 01059 // function to transition to a new state 01060 void M2MInterfaceImpl::internal_event(uint8_t new_state, 01061 EventData* p_data) 01062 { 01063 tr_debug("M2MInterfaceImpl::internal_event : new state %d", new_state); 01064 _event_data = p_data; 01065 _event_generated = true; 01066 _current_state = new_state; 01067 state_engine(); 01068 } 01069 01070 // the state engine executes the state machine states 01071 void M2MInterfaceImpl::state_engine (void) 01072 { 01073 tr_debug("M2MInterfaceImpl::state_engine"); 01074 EventData* p_data_temp = NULL; 01075 01076 // while events are being generated keep executing states 01077 while (_event_generated) { 01078 p_data_temp = _event_data; // copy of event data pointer 01079 _event_data = NULL; // event data used up, reset ptr 01080 _event_generated = false; // event used up, reset flag 01081 01082 assert(_current_state < _max_states); 01083 01084 state_function( _current_state, p_data_temp ); 01085 } 01086 } 01087 01088 void M2MInterfaceImpl::state_function( uint8_t current_state, EventData* data ) 01089 { 01090 switch( current_state ) { 01091 case STATE_IDLE: 01092 M2MInterfaceImpl::state_idle(data); 01093 break; 01094 case STATE_BOOTSTRAP: 01095 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01096 M2MInterfaceImpl::state_bootstrap(data); 01097 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01098 break; 01099 case STATE_BOOTSTRAP_ADDRESS_RESOLVED: 01100 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01101 M2MInterfaceImpl::state_bootstrap_address_resolved(data); 01102 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01103 break; 01104 case STATE_BOOTSTRAP_RESOURCE_CREATED: 01105 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01106 M2MInterfaceImpl::state_bootstrap_resource_created(data); 01107 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01108 break; 01109 case STATE_BOOTSTRAP_WAIT: 01110 case STATE_BOOTSTRAP_ERROR_WAIT: 01111 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01112 // Do nothing, we're just waiting for data_sent callback 01113 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01114 break; 01115 case STATE_BOOTSTRAPPED: 01116 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01117 M2MInterfaceImpl::state_bootstrapped(data); 01118 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 01119 break; 01120 case STATE_REGISTER: 01121 M2MInterfaceImpl::state_register(data); 01122 break; 01123 case STATE_REGISTER_ADDRESS_RESOLVED: 01124 M2MInterfaceImpl::state_register_address_resolved(data); 01125 break; 01126 case STATE_REGISTERED: 01127 M2MInterfaceImpl::state_registered(data); 01128 break; 01129 case STATE_UPDATE_REGISTRATION: 01130 M2MInterfaceImpl::state_update_registration(data); 01131 break; 01132 case STATE_UNREGISTER: 01133 M2MInterfaceImpl::state_unregister(data); 01134 break; 01135 case STATE_UNREGISTERED: 01136 M2MInterfaceImpl::state_unregistered(data); 01137 break; 01138 case STATE_SENDING_COAP_DATA: 01139 M2MInterfaceImpl::state_sending_coap_data(data); 01140 break; 01141 case STATE_COAP_DATA_SENT: 01142 M2MInterfaceImpl::state_coap_data_sent(data); 01143 break; 01144 case STATE_COAP_DATA_RECEIVED: 01145 M2MInterfaceImpl::state_coap_data_received(data); 01146 break; 01147 case STATE_PROCESSING_COAP_DATA: 01148 M2MInterfaceImpl::state_processing_coap_data(data); 01149 break; 01150 case STATE_COAP_DATA_PROCESSED: 01151 M2MInterfaceImpl::state_coap_data_processed(data); 01152 break; 01153 case STATE_WAITING: 01154 M2MInterfaceImpl::state_waiting(data); 01155 break; 01156 } 01157 } 01158 01159 void M2MInterfaceImpl::start_register_update(M2MUpdateRegisterData *data) { 01160 tr_debug("M2MInterfaceImpl::start_register_update()"); 01161 if(!data || (data->_lifetime != 0 && (data->_lifetime < MINIMUM_REGISTRATION_TIME))) { 01162 set_error_description(ERROR_REASON_18); 01163 _observer.error(M2MInterface::InvalidParameters); 01164 } 01165 01166 if (_reconnecting) { 01167 //If client is in reconnection mode, ignore this call, state machine will reconnect on its own. 01168 return; 01169 } 01170 01171 _reconnection_state = M2MInterfaceImpl::WithUpdate; 01172 BEGIN_TRANSITION_MAP // - Current State - 01173 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_idle 01174 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap 01175 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state__bootstrap_address_resolved 01176 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_resource_created 01177 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_wait 01178 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_error_wait 01179 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrapped 01180 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register 01181 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_address_resolved 01182 TRANSITION_MAP_ENTRY (STATE_UPDATE_REGISTRATION) // state_registered 01183 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_update_registration 01184 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregister 01185 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregistered 01186 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_sending_coap_data 01187 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_sent 01188 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_received 01189 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_processing_coap_data 01190 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_processed 01191 TRANSITION_MAP_ENTRY (STATE_UPDATE_REGISTRATION) // state_waiting 01192 END_TRANSITION_MAP(data) 01193 if(_event_ignored) { 01194 _event_ignored = false; 01195 if (!_reconnecting) { 01196 set_error_description(ERROR_REASON_19); 01197 _observer.error(M2MInterface::NotAllowed); 01198 } 01199 } 01200 } 01201 01202 void M2MInterfaceImpl::update_endpoint(String &name) { 01203 _nsdl_interface.update_endpoint(name); 01204 } 01205 01206 void M2MInterfaceImpl::update_domain(String &domain) 01207 { 01208 _nsdl_interface.update_domain(domain); 01209 } 01210 01211 const String M2MInterfaceImpl::internal_endpoint_name() const 01212 { 01213 return _nsdl_interface.internal_endpoint_name(); 01214 } 01215 01216 const char *M2MInterfaceImpl::error_description() const 01217 { 01218 #ifndef DISABLE_ERROR_DESCRIPTION 01219 return _error_description; 01220 #else 01221 return ""; 01222 #endif 01223 } 01224 01225 void M2MInterfaceImpl::set_error_description(const char *description) 01226 { 01227 #ifndef DISABLE_ERROR_DESCRIPTION 01228 if (strncmp(_error_description, description, sizeof(_error_description)) != 0) { 01229 strncpy(_error_description, description, MAX_ALLOWED_ERROR_STRING_LENGTH - 1); 01230 } 01231 #endif 01232 } 01233 01234 bool M2MInterfaceImpl::queue_mode() const 01235 { 01236 return (_binding_mode == M2MInterface::UDP_QUEUE || 01237 _binding_mode == M2MInterface::TCP_QUEUE || 01238 _binding_mode == M2MInterface::SMS_QUEUE || 01239 _binding_mode == M2MInterface::UDP_SMS_QUEUE); 01240 } 01241 01242 void M2MInterfaceImpl::get_data_request(const char *uri, 01243 const size_t offset, 01244 const bool async, 01245 get_data_cb data_cb, 01246 get_data_error_cb error_cb, 01247 void *context) 01248 { 01249 get_data_req_error_e error = FAILED_TO_SEND_MSG; 01250 if(_current_state != STATE_IDLE && uri) { 01251 if (!_nsdl_interface.send_get_data_request(uri, offset, async, data_cb, error_cb, context)) { 01252 error_cb(error, context); 01253 } 01254 } 01255 else { 01256 error_cb(error, context); 01257 } 01258 } 01259
Generated on Tue Jul 12 2022 16:22:06 by 1.7.2