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 #include <assert.h> 00017 #include "include/m2minterfaceimpl.h" 00018 #include "include/eventdata.h" 00019 #include "mbed-client/m2minterfaceobserver.h" 00020 #include "mbed-client/m2mconnectionhandler.h" 00021 #include "mbed-client/m2mconnectionsecurity.h" 00022 #include "include/m2mnsdlinterface.h" 00023 #include "include/nsdlaccesshelper.h" 00024 #include "mbed-client/m2msecurity.h" 00025 #include "mbed-client/m2mconstants.h" 00026 #include "mbed-client/m2mtimer.h" 00027 #include "mbed-trace/mbed_trace.h" 00028 00029 #define TRACE_GROUP "mClt" 00030 00031 M2MInterfaceImpl::M2MInterfaceImpl(M2MInterfaceObserver& observer, 00032 const String &ep_name, 00033 const String &ep_type, 00034 const int32_t l_time, 00035 const uint16_t listen_port, 00036 const String &dmn, 00037 M2MInterface::BindingMode mode, 00038 M2MInterface::NetworkStack stack, 00039 const String &con_addr) 00040 : _observer(observer), 00041 _nsdl_interface(new M2MNsdlInterface(*this)), 00042 _current_state(0), 00043 _max_states( STATE_MAX_STATES ), 00044 _event_generated(false), 00045 _event_data(NULL), 00046 _endpoint_type(ep_type), 00047 _domain( dmn), 00048 _life_time(l_time), 00049 _binding_mode(mode), 00050 _context_address(con_addr), 00051 _listen_port(listen_port), 00052 _server_port(0), 00053 _register_server(NULL), 00054 _event_ignored(false), 00055 _register_ongoing(false), 00056 _update_register_ongoing(false), 00057 _queue_sleep_timer(new M2MTimer(*this)), 00058 _retry_timer(new M2MTimer(*this)), 00059 _bootstrap_timer(NULL), 00060 _callback_handler(NULL), 00061 _security(NULL), 00062 _retry_count(0), 00063 _reconnecting(false), 00064 _retry_timer_expired(false) 00065 { 00066 M2MConnectionSecurity::SecurityMode sec_mode = M2MConnectionSecurity::DTLS; 00067 //Hack for now 00068 if( _binding_mode == M2MInterface::TCP ){ 00069 _binding_mode = M2MInterface::UDP; 00070 sec_mode = M2MConnectionSecurity::TLS; 00071 }else if( _binding_mode == M2MInterface::TCP_QUEUE ){ 00072 _binding_mode = M2MInterface::UDP_QUEUE; 00073 sec_mode = M2MConnectionSecurity::TLS; 00074 } 00075 tr_debug("M2MInterfaceImpl::M2MInterfaceImpl() -IN"); 00076 _nsdl_interface->create_endpoint(ep_name, 00077 _endpoint_type, 00078 _life_time, 00079 _domain, 00080 (uint8_t)_binding_mode, 00081 _context_address); 00082 00083 //Doesn't own, ownership is passed to ConnectionHandler class 00084 _security_connection = new M2MConnectionSecurity(sec_mode); 00085 //Here we must use TCP still 00086 _connection_handler = new M2MConnectionHandler(*this, _security_connection, mode, stack); 00087 __connection_handler = _connection_handler; 00088 _connection_handler->bind_connection(_listen_port); 00089 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00090 _bootstrap_timer = new M2MTimer(*this); 00091 #endif 00092 tr_debug("M2MInterfaceImpl::M2MInterfaceImpl() -OUT"); 00093 } 00094 00095 00096 M2MInterfaceImpl::~M2MInterfaceImpl() 00097 { 00098 tr_debug("M2MInterfaceImpl::~M2MInterfaceImpl() - IN"); 00099 delete _queue_sleep_timer; 00100 delete _nsdl_interface; 00101 _connection_handler->stop_listening(); 00102 __connection_handler = NULL; 00103 delete _connection_handler; 00104 delete _retry_timer; 00105 delete _bootstrap_timer; 00106 _security_connection = NULL; 00107 tr_debug("M2MInterfaceImpl::~M2MInterfaceImpl() - OUT"); 00108 } 00109 00110 void M2MInterfaceImpl::bootstrap(M2MSecurity *security) 00111 { 00112 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00113 tr_debug("M2MInterfaceImpl::bootstrap(M2MSecurity *security) - IN"); 00114 // Transition to a new state based upon 00115 // the current state of the state machine 00116 M2MSecurityData* data = new M2MSecurityData(); 00117 data->_object = security; 00118 BEGIN_TRANSITION_MAP // - Current State - 00119 TRANSITION_MAP_ENTRY (STATE_BOOTSTRAP) // state_idle 00120 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap 00121 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state__bootstrap_address_resolved 00122 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_resource_created 00123 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrapped 00124 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register 00125 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_address_resolved 00126 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_resource_created 00127 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_registered 00128 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_update_registration 00129 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregister 00130 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregistered 00131 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_sending_coap_data 00132 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_sent 00133 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_received 00134 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_processing_coap_data 00135 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_processed 00136 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_waiting 00137 END_TRANSITION_MAP(data) 00138 if(_event_ignored) { 00139 _event_ignored = false; 00140 _observer.error(M2MInterface::NotAllowed); 00141 } 00142 tr_debug("M2MInterfaceImpl::bootstrap(M2MSecurity *security) - OUT"); 00143 #else 00144 _observer.error(M2MInterface::NotAllowed); 00145 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00146 } 00147 00148 void M2MInterfaceImpl::cancel_bootstrap() 00149 { 00150 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00151 //TODO: Do we need this ? 00152 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00153 } 00154 00155 void M2MInterfaceImpl::register_object(M2MSecurity *security, const M2MObjectList &object_list) 00156 { 00157 tr_debug("M2MInterfaceImpl::register_object - IN"); 00158 // Transition to a new state based upon 00159 // the current state of the state machine 00160 //TODO: manage register object in a list. 00161 if(!_register_ongoing) { 00162 _register_ongoing = true; 00163 _register_server = security; 00164 M2MRegisterData *data = new M2MRegisterData(); 00165 data->_object = security; 00166 data->_object_list = object_list; 00167 BEGIN_TRANSITION_MAP // - Current State - 00168 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_idle 00169 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap 00170 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state__bootstrap_address_resolved 00171 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_resource_created 00172 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_bootstrapped 00173 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register 00174 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_address_resolved 00175 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_resource_created 00176 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_registered 00177 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_update_registration 00178 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregister 00179 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregistered 00180 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_sending_coap_data 00181 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_sent 00182 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_received 00183 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_processing_coap_data 00184 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_processed 00185 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_waiting 00186 END_TRANSITION_MAP(data) 00187 if(_event_ignored) { 00188 _event_ignored = false; 00189 _observer.error(M2MInterface::NotAllowed); 00190 } 00191 } else { 00192 tr_debug("M2MInterfaceImpl::register_object - NOT ALLOWED"); 00193 _observer.error(M2MInterface::NotAllowed); 00194 } 00195 tr_debug("M2MInterfaceImpl::register_object - OUT"); 00196 } 00197 00198 void M2MInterfaceImpl::update_registration(M2MSecurity *security_object, const uint32_t lifetime) 00199 { 00200 tr_debug("M2MInterfaceImpl::update_registration - IN"); 00201 // Transition to a new state based upon 00202 // the current state of the state machine 00203 if(lifetime != 0 && (lifetime < MINIMUM_REGISTRATION_TIME)) { 00204 _observer.error(M2MInterface::InvalidParameters); 00205 } else if(!_update_register_ongoing){ 00206 tr_debug("M2MInterfaceImpl::update_registration - already ongoing"); 00207 _update_register_ongoing = true; 00208 M2MUpdateRegisterData *data = new M2MUpdateRegisterData(); 00209 data->_object = security_object; 00210 data->_lifetime = lifetime; 00211 BEGIN_TRANSITION_MAP // - Current State - 00212 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_idle 00213 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap 00214 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state__bootstrap_address_resolved 00215 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_resource_created 00216 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrapped 00217 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register 00218 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_address_resolved 00219 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_resource_created 00220 TRANSITION_MAP_ENTRY (STATE_UPDATE_REGISTRATION) // state_registered 00221 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_update_registration 00222 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregister 00223 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregistered 00224 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_sending_coap_data 00225 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_sent 00226 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_received 00227 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_processing_coap_data 00228 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_processed 00229 TRANSITION_MAP_ENTRY (STATE_UPDATE_REGISTRATION) // state_waiting 00230 END_TRANSITION_MAP(data) 00231 if(_event_ignored) { 00232 _event_ignored = false; 00233 if (!_reconnecting) 00234 _observer.error(M2MInterface::NotAllowed); 00235 } 00236 } else if(!_reconnecting) { 00237 tr_debug("M2MInterfaceImpl::update_registration - NOT ALLOWED"); 00238 _observer.error(M2MInterface::NotAllowed); 00239 } else { 00240 tr_debug("M2MInterfaceImpl::update_registration - reconnecting"); 00241 } 00242 tr_debug("M2MInterfaceImpl::update_registration - OUT"); 00243 } 00244 00245 void M2MInterfaceImpl::unregister_object(M2MSecurity* /*security*/) 00246 { 00247 tr_debug("M2MInterfaceImpl::unregister_object - IN"); 00248 // Transition to a new state based upon 00249 // the current state of the state machine 00250 BEGIN_TRANSITION_MAP // - Current State - 00251 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_idle 00252 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap 00253 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state__bootstrap_address_resolved 00254 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_resource_created 00255 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrapped 00256 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register 00257 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_address_resolved 00258 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_resource_created 00259 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_registered 00260 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_update_registration 00261 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregister 00262 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregistered 00263 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_sending_coap_data 00264 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_sent 00265 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_received 00266 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_processing_coap_data 00267 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_processed 00268 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_waiting 00269 END_TRANSITION_MAP(NULL) 00270 if(_event_ignored) { 00271 _event_ignored = false; 00272 _observer.error(M2MInterface::NotAllowed); 00273 } 00274 tr_debug("M2MInterfaceImpl::unregister_object - OUT"); 00275 } 00276 00277 void M2MInterfaceImpl::set_queue_sleep_handler(callback_handler handler) 00278 { 00279 tr_debug("M2MInterfaceImpl::set_queue_sleep_handler()"); 00280 _callback_handler = handler; 00281 } 00282 00283 void M2MInterfaceImpl::set_random_number_callback(random_number_cb callback) 00284 { 00285 if(_security_connection) { 00286 _security_connection->set_random_number_callback(callback); 00287 } 00288 } 00289 00290 void M2MInterfaceImpl::set_entropy_callback(entropy_cb callback) 00291 { 00292 if(_security_connection) { 00293 _security_connection->set_entropy_callback(callback); 00294 } 00295 } 00296 00297 void M2MInterfaceImpl::set_platform_network_handler(void *handler) 00298 { 00299 tr_debug("M2MInterfaceImpl::set_platform_network_handler()"); 00300 if(_connection_handler) { 00301 _connection_handler->set_platform_network_handler(handler); 00302 } 00303 } 00304 00305 void M2MInterfaceImpl::coap_message_ready(uint8_t *data_ptr, 00306 uint16_t data_len, 00307 sn_nsdl_addr_s *address_ptr) 00308 { 00309 tr_debug("M2MInterfaceImpl::coap_message_ready"); 00310 internal_event(STATE_SENDING_COAP_DATA); 00311 if(!_connection_handler->send_data(data_ptr,data_len,address_ptr)) { 00312 internal_event( STATE_IDLE); 00313 tr_error("M2MInterfaceImpl::coap_message_ready() - M2MInterface::NetworkError"); 00314 if (!_reconnecting) { 00315 _observer.error(M2MInterface::NetworkError); 00316 } 00317 } 00318 } 00319 00320 void M2MInterfaceImpl::client_registered(M2MServer *server_object) 00321 { 00322 tr_debug("M2MInterfaceImpl::client_registered"); 00323 _retry_count = 0; 00324 internal_event(STATE_REGISTERED); 00325 //Inform client is registered. 00326 //TODO: manage register object in a list. 00327 _observer.object_registered(_register_server,*server_object); 00328 } 00329 00330 void M2MInterfaceImpl::registration_updated(const M2MServer &server_object) 00331 { 00332 tr_debug("M2MInterfaceImpl::registration_updated"); 00333 internal_event(STATE_REGISTERED); 00334 _observer.registration_updated(_register_server,server_object); 00335 } 00336 00337 void M2MInterfaceImpl::registration_error(uint8_t error_code, bool retry) 00338 { 00339 tr_debug("M2MInterfaceImpl::registration_error code [%d]", error_code); 00340 // Try to register again 00341 if (retry) { 00342 socket_error(M2MConnectionHandler::SOCKET_SEND_ERROR); 00343 } else { 00344 internal_event(STATE_IDLE); 00345 _observer.error((M2MInterface::Error)error_code); 00346 } 00347 } 00348 00349 void M2MInterfaceImpl::client_unregistered() 00350 { 00351 tr_debug("M2MInterfaceImpl::client_unregistered()"); 00352 internal_event(STATE_UNREGISTERED); 00353 //TODO: manage register object in a list. 00354 _observer.object_unregistered(_register_server); 00355 } 00356 00357 void M2MInterfaceImpl::bootstrap_done(M2MSecurity *security_object) 00358 { 00359 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00360 tr_debug("M2MInterfaceImpl::bootstrap_done"); 00361 _bootstrap_timer->stop_timer(); 00362 internal_event(STATE_BOOTSTRAPPED); 00363 _observer.bootstrap_done(security_object); 00364 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00365 } 00366 00367 void M2MInterfaceImpl::bootstrap_error() 00368 { 00369 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00370 tr_debug("M2MInterfaceImpl::bootstrap_error()"); 00371 _bootstrap_timer->stop_timer(); 00372 internal_event(STATE_IDLE); 00373 _observer.error(M2MInterface::BootstrapFailed); 00374 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00375 } 00376 00377 void M2MInterfaceImpl::coap_data_processed() 00378 { 00379 tr_debug("M2MInterfaceImpl::coap_data_processed()"); 00380 internal_event(STATE_COAP_DATA_PROCESSED); 00381 } 00382 00383 void M2MInterfaceImpl::value_updated(M2MBase *base) 00384 { 00385 tr_debug("M2MInterfaceImpl::value_updated(M2MBase *base)"); 00386 if(base) { 00387 M2MBase::BaseType type = base->base_type(); 00388 _observer.value_updated(base, type); 00389 } 00390 } 00391 00392 void M2MInterfaceImpl::data_available(uint8_t* data, 00393 uint16_t data_size, 00394 const M2MConnectionObserver::SocketAddress &address) 00395 { 00396 tr_debug("M2MInterfaceImpl::data_available"); 00397 ReceivedData *event = new ReceivedData(); 00398 event->_data = data; 00399 event->_size = data_size; 00400 event->_address = &address; 00401 internal_event(STATE_COAP_DATA_RECEIVED, event); 00402 } 00403 00404 void M2MInterfaceImpl::socket_error(uint8_t error_code, bool retry) 00405 { 00406 tr_debug("M2MInterfaceImpl::socket_error: (%d), retry (%d), reconnecting (%d)", error_code, retry, _reconnecting); 00407 if (!_retry_timer_expired && _reconnecting) { 00408 tr_debug("M2MInterfaceImpl::socket_error - retry timer running - return"); 00409 return; 00410 } 00411 M2MInterface::Error error = M2MInterface::ErrorNone; 00412 switch (error_code) { 00413 case M2MConnectionHandler::SSL_CONNECTION_ERROR: 00414 error = M2MInterface::SecureConnectionFailed; 00415 break; 00416 case M2MConnectionHandler::DNS_RESOLVING_ERROR: 00417 error = M2MInterface::DnsResolvingFailed; 00418 break; 00419 case M2MConnectionHandler::SOCKET_READ_ERROR: 00420 error = M2MInterface::NetworkError; 00421 break; 00422 case M2MConnectionHandler::SOCKET_SEND_ERROR: 00423 error = M2MInterface::NetworkError; 00424 break; 00425 case M2MConnectionHandler::SSL_HANDSHAKE_ERROR: 00426 error = M2MInterface::SecureConnectionFailed; 00427 break; 00428 case M2MConnectionHandler::SOCKET_ABORT: 00429 error = M2MInterface::NetworkError; 00430 break; 00431 default: 00432 break; 00433 } 00434 00435 // Try to do reconnecting 00436 if (retry) { 00437 if (_retry_count < MBED_CLIENT_RECONNECTION_COUNT) { 00438 internal_event(STATE_IDLE); 00439 _reconnecting = true; 00440 _retry_count++; 00441 _connection_handler->stop_listening(); 00442 int retry_time = MBED_CLIENT_RECONNECTION_INTERVAL * 00443 MBED_CLIENT_RECONNECTION_COUNT * _retry_count * 1000; 00444 _retry_timer_expired = false; 00445 _retry_timer->start_timer(retry_time, 00446 M2MTimerObserver::RetryTimer); 00447 tr_debug("M2MInterfaceImpl::socket_error - reconnecting in %d(s), count %d/%d", retry_time / 1000, 00448 _retry_count, MBED_CLIENT_RECONNECTION_COUNT); 00449 } else { 00450 tr_debug("M2MInterfaceImpl::socket_error - no more retries"); 00451 _connection_handler->stop_listening(); 00452 _retry_timer->stop_timer(); 00453 retry = false; 00454 } 00455 } 00456 // Inform application 00457 if (!retry && M2MInterface::ErrorNone != error) { 00458 tr_debug("M2MInterfaceImpl::socket_error - send error to application"); 00459 _connection_handler->stop_listening(); 00460 _retry_timer->stop_timer(); 00461 _retry_count = 0; 00462 _reconnecting = false; 00463 _observer.error(error); 00464 internal_event(STATE_IDLE); 00465 } 00466 } 00467 00468 void M2MInterfaceImpl::address_ready(const M2MConnectionObserver::SocketAddress &address, 00469 M2MConnectionObserver::ServerType server_type, 00470 const uint16_t server_port) 00471 { 00472 tr_debug("M2MInterfaceImpl::address_ready"); 00473 ResolvedAddressData *data = new ResolvedAddressData(); 00474 data->_address = &address; 00475 data->_port = server_port; 00476 if( M2MConnectionObserver::Bootstrap == server_type) { 00477 tr_debug("M2MInterfaceImpl::address_ready() Server Type Bootstrap"); 00478 internal_event(STATE_BOOTSTRAP_ADDRESS_RESOLVED, data); 00479 } else { 00480 tr_debug("M2MInterfaceImpl::address_ready() Server Type LWM2M"); 00481 internal_event(STATE_REGISTER_ADDRESS_RESOLVED, data); 00482 } 00483 } 00484 00485 void M2MInterfaceImpl::data_sent() 00486 { 00487 tr_debug("M2MInterfaceImpl::data_sent()"); 00488 if(_binding_mode == M2MInterface::UDP_QUEUE || 00489 _binding_mode == M2MInterface::TCP_QUEUE || 00490 _binding_mode == M2MInterface::SMS_QUEUE || 00491 _binding_mode == M2MInterface::UDP_SMS_QUEUE) { 00492 if(_callback_handler) { 00493 _queue_sleep_timer->stop_timer(); 00494 _queue_sleep_timer->start_timer(MBED_CLIENT_RECONNECTION_COUNT*MBED_CLIENT_RECONNECTION_INTERVAL*1000, 00495 M2MTimerObserver::QueueSleep); 00496 } 00497 } 00498 internal_event(STATE_COAP_DATA_SENT); 00499 } 00500 00501 void M2MInterfaceImpl::timer_expired(M2MTimerObserver::Type type) 00502 { 00503 tr_debug("M2MInterfaceImpl::timer_expired()"); 00504 if(M2MTimerObserver::QueueSleep == type) { 00505 if(_callback_handler) { 00506 _callback_handler(); 00507 } 00508 } 00509 else if (M2MTimerObserver::RetryTimer == type) { 00510 _retry_timer_expired = true; 00511 _listen_port = rand() % 64511 + 1024; 00512 tr_debug("M2MInterfaceImpl::timer_expired() - new port: %d", _listen_port); 00513 _connection_handler->bind_connection(_listen_port); 00514 internal_event(STATE_REGISTER); 00515 } 00516 else if (M2MTimerObserver::BootstrapTimer == type) { 00517 bootstrap_error(); 00518 } 00519 } 00520 00521 // state machine sits here. 00522 void M2MInterfaceImpl::state_idle(EventData* /*data*/) 00523 { 00524 tr_debug("M2MInterfaceImpl::state_idle"); 00525 _nsdl_interface->stop_timers(); 00526 _register_ongoing = false; 00527 _update_register_ongoing = false; 00528 } 00529 00530 void M2MInterfaceImpl::state_bootstrap( EventData *data) 00531 { 00532 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00533 tr_debug("M2MInterfaceImpl::state_bootstrap"); 00534 // Start with bootstrapping preparation 00535 bool success = false; 00536 if(data) { 00537 M2MSecurityData *event = static_cast<M2MSecurityData *> (data); 00538 M2MSecurity *security = event->_object; 00539 if(security) { 00540 if(M2MSecurity::Bootstrap == security->server_type()) { 00541 tr_debug("M2MInterfaceImpl::state_bootstrap - server_type : M2MSecurity::Bootstrap"); 00542 String server_address = security->resource_value_string(M2MSecurity::M2MServerUri); 00543 tr_debug("M2MInterfaceImpl::state_bootstrap - server_address %s", server_address.c_str()); 00544 _bootstrap_timer->start_timer(MBED_CLIENT_RECONNECTION_COUNT * MBED_CLIENT_RECONNECTION_INTERVAL * 8 * 1000, 00545 M2MTimerObserver::BootstrapTimer); 00546 String ip_address; 00547 String coap; 00548 if(server_address.compare(0,sizeof(COAP)-1,COAP) == 0) { 00549 coap = COAP; 00550 } 00551 else if(server_address.compare(0,sizeof(COAPS)-1,COAPS) == 0) { 00552 security->resource_value_int(M2MSecurity::SecurityMode) != M2MSecurity::NoSecurity ? coap = COAPS: coap = ""; 00553 } 00554 if(!coap.empty()) { 00555 server_address = server_address.substr(coap.size(), 00556 server_address.size()-coap.size()); 00557 00558 process_address(server_address, ip_address, _server_port); 00559 00560 tr_debug("M2MInterfaceImpl::state_bootstrap - IP address %s , Port %d", ip_address.c_str(), _server_port); 00561 // If bind and resolving server address succeed then proceed else 00562 // return error to the application and go to Idle state. 00563 if(ip_address.empty()) { 00564 tr_error("M2MInterfaceImpl::state_bootstrap - set error as M2MInterface::InvalidParameters"); 00565 success = false; 00566 } else if(_connection_handler->resolve_server_address(ip_address, 00567 _server_port, 00568 M2MConnectionObserver::Bootstrap, 00569 security)) { 00570 tr_debug("M2MInterfaceImpl::state_bootstrap - resolve_server_address - success"); 00571 success = true; 00572 } 00573 } 00574 } 00575 } 00576 } 00577 if(!success) { 00578 tr_error("M2MInterfaceImpl::state_bootstrap - M2MInterface::InvalidParameters"); 00579 _observer.error(M2MInterface::InvalidParameters); 00580 internal_event(STATE_IDLE); 00581 } 00582 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00583 } 00584 00585 void M2MInterfaceImpl::state_bootstrap_address_resolved( EventData *data) 00586 { 00587 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00588 tr_debug("M2MInterfaceImpl::state_bootstrap_address_resolved"); 00589 ResolvedAddressData *event = static_cast<ResolvedAddressData *> (data); 00590 sn_nsdl_addr_s address; 00591 00592 M2MInterface::NetworkStack stack = event->_address->_stack; 00593 00594 if(M2MInterface::LwIP_IPv4 == stack) { 00595 tr_debug("M2MInterfaceImpl::state_bootstrap_address_resolved : IPv4 address"); 00596 address.type = SN_NSDL_ADDRESS_TYPE_IPV4; 00597 address.addr_len = 4; 00598 } else if((M2MInterface::LwIP_IPv6 == stack) || 00599 (M2MInterface::Nanostack_IPv6 == stack)) { 00600 tr_debug("M2MInterfaceImpl::state_bootstrap_address_resolved : IPv6 address"); 00601 address.type = SN_NSDL_ADDRESS_TYPE_IPV6; 00602 address.addr_len = 16; 00603 } 00604 address.port = event->_port; 00605 address.addr_ptr = (uint8_t*)event->_address->_address; 00606 address.addr_len = event->_address->_length; 00607 _connection_handler->start_listening_for_data(); 00608 00609 // Include domain id to be part of endpoint name 00610 String new_ep_name; 00611 new_ep_name += _nsdl_interface->endpoint_name(); 00612 if (!_domain.empty()) { 00613 new_ep_name += '@'; 00614 new_ep_name += _domain; 00615 } 00616 if(_nsdl_interface->create_bootstrap_resource(&address, new_ep_name)) { 00617 tr_debug("M2MInterfaceImpl::state_bootstrap_address_resolved : create_bootstrap_resource - success"); 00618 internal_event(STATE_BOOTSTRAP_RESOURCE_CREATED); 00619 } else{ 00620 // If resource creation fails then inform error to application 00621 tr_error("M2MInterfaceImpl::state_bootstrap_address_resolved : M2MInterface::InvalidParameters"); 00622 internal_event(STATE_IDLE); 00623 _observer.error(M2MInterface::InvalidParameters); 00624 } 00625 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00626 } 00627 00628 void M2MInterfaceImpl::state_bootstrap_resource_created( EventData */*data*/) 00629 { 00630 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00631 tr_debug("M2MInterfaceImpl::state_bootstrap_resource_created"); 00632 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00633 } 00634 00635 void M2MInterfaceImpl::state_bootstrapped( EventData */*data*/) 00636 { 00637 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00638 tr_debug("M2MInterfaceImpl::state_bootstrapped"); 00639 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00640 } 00641 00642 void M2MInterfaceImpl::state_register( EventData *data) 00643 { 00644 tr_debug("M2MInterfaceImpl::state_register"); 00645 if (!_security) { 00646 M2MInterface::Error error = M2MInterface::InvalidParameters; 00647 // Start with registration preparation 00648 if(data) { 00649 M2MRegisterData *event = static_cast<M2MRegisterData *> (data); 00650 _security = event->_object; 00651 if(_security) { 00652 if(M2MSecurity::M2MServer == _security->server_type()) { 00653 tr_debug("M2MInterfaceImpl::state_register - server_type : M2MSecurity::M2MServer"); 00654 if(_nsdl_interface->create_nsdl_list_structure(event->_object_list)) { 00655 tr_debug("M2MInterfaceImpl::state_register - create_nsdl_list_structure - success"); 00656 // If the nsdl resource structure is created successfully 00657 String server_address = _security->resource_value_string(M2MSecurity::M2MServerUri); 00658 tr_debug("M2MInterfaceImpl::state_register - server_address %s", server_address.c_str()); 00659 String coap; 00660 if(server_address.compare(0,sizeof(COAP)-1,COAP) == 0) { 00661 coap = COAP; 00662 } 00663 else if(server_address.compare(0,sizeof(COAPS)-1,COAPS) == 0) { 00664 _security->resource_value_int(M2MSecurity::SecurityMode) != M2MSecurity::NoSecurity ? coap = COAPS: coap = ""; 00665 } 00666 if(!coap.empty()) { 00667 server_address = server_address.substr(coap.size(), 00668 server_address.size() - coap.size()); 00669 process_address(server_address, _server_ip_address, _server_port); 00670 00671 tr_debug("M2MInterfaceImpl::state_register - IP address %s , Port %d", _server_ip_address.c_str(), _server_port); 00672 if(!_server_ip_address.empty()) { 00673 // Connection related errors are coming through callback 00674 error = M2MInterface::ErrorNone; 00675 _connection_handler->resolve_server_address(_server_ip_address,_server_port, 00676 M2MConnectionObserver::LWM2MServer, 00677 _security); 00678 } 00679 } 00680 } 00681 } 00682 } 00683 } 00684 if (error != M2MInterface::ErrorNone) { 00685 tr_error("M2MInterfaceImpl::state_register - set error as M2MInterface::InvalidParameters"); 00686 internal_event(STATE_IDLE); 00687 _observer.error(error); 00688 } 00689 } else { 00690 _connection_handler->resolve_server_address(_server_ip_address,_server_port, 00691 M2MConnectionObserver::LWM2MServer, 00692 _security); 00693 } 00694 } 00695 00696 void M2MInterfaceImpl::process_address(const String& server_address, String& ip_address, uint16_t& port) { 00697 00698 int colonFound = server_address.find_last_of(':'); //10 00699 if(colonFound != -1) { 00700 ip_address = server_address.substr(0,colonFound); 00701 port = atoi(server_address.substr(colonFound+1, 00702 server_address.size()-ip_address.size()).c_str()); 00703 colonFound = ip_address.find_last_of(']'); 00704 if(ip_address.compare(0,1,"[") == 0) { 00705 if(colonFound == -1) { 00706 ip_address.clear(); 00707 } else { 00708 ip_address = ip_address.substr(1,colonFound-1); 00709 } 00710 } else if(colonFound != -1) { 00711 ip_address.clear(); 00712 } 00713 } 00714 } 00715 00716 void M2MInterfaceImpl::state_register_address_resolved( EventData *data) 00717 { 00718 tr_debug("M2MInterfaceImpl::state_register_address_resolved"); 00719 if(data) { 00720 ResolvedAddressData *event = static_cast<ResolvedAddressData *> (data); 00721 00722 sn_nsdl_addr_type_e address_type = SN_NSDL_ADDRESS_TYPE_IPV6; 00723 00724 M2MInterface::NetworkStack stack = event->_address->_stack; 00725 00726 if(M2MInterface::LwIP_IPv4 == stack) { 00727 tr_debug("M2MInterfaceImpl::state_register_address_resolved : IPv4 address"); 00728 address_type = SN_NSDL_ADDRESS_TYPE_IPV4; 00729 } else if((M2MInterface::LwIP_IPv6 == stack) || 00730 (M2MInterface::Nanostack_IPv6 == stack)) { 00731 tr_debug("M2MInterfaceImpl::state_register_address_resolved : IPv6 address"); 00732 address_type = SN_NSDL_ADDRESS_TYPE_IPV6; 00733 } 00734 _connection_handler->start_listening_for_data(); 00735 if(_nsdl_interface->send_register_message((uint8_t*)event->_address->_address,event->_port, address_type)) { 00736 internal_event(STATE_REGISTER_RESOURCE_CREATED); 00737 } else { 00738 // If resource creation fails then inform error to application 00739 tr_error("M2MInterfaceImpl::state_register_address_resolved : M2MInterface::InvalidParameters"); 00740 internal_event(STATE_IDLE); 00741 _observer.error(M2MInterface::InvalidParameters); 00742 } 00743 } 00744 } 00745 00746 void M2MInterfaceImpl::state_register_resource_created( EventData */*data*/) 00747 { 00748 tr_debug("M2MInterfaceImpl::state_register_resource_created"); 00749 } 00750 00751 void M2MInterfaceImpl::state_registered( EventData */*data*/) 00752 { 00753 tr_debug("M2MInterfaceImpl::state_registered"); 00754 _retry_count = 0; 00755 _register_ongoing = false; 00756 _update_register_ongoing = false; 00757 _reconnecting = false; 00758 } 00759 00760 void M2MInterfaceImpl::state_update_registration( EventData *data) 00761 { 00762 tr_debug("M2MInterfaceImpl::state_update_registration"); 00763 // Start with registration preparation 00764 if(data) { 00765 M2MUpdateRegisterData *event = static_cast<M2MUpdateRegisterData *> (data); 00766 _nsdl_interface->send_update_registration(event->_lifetime); 00767 } 00768 } 00769 00770 void M2MInterfaceImpl::state_unregister( EventData */*data*/) 00771 { 00772 tr_debug("M2MInterfaceImpl::state_unregister"); 00773 internal_event(STATE_SENDING_COAP_DATA); 00774 if(!_nsdl_interface->send_unregister_message()) { 00775 tr_error("M2MInterfaceImpl::state_unregister : M2MInterface::NotRegistered"); 00776 internal_event(STATE_IDLE); 00777 _observer.error(M2MInterface::NotRegistered); 00778 } 00779 } 00780 00781 void M2MInterfaceImpl::state_unregistered( EventData */*data*/) 00782 { 00783 tr_debug("M2MInterfaceImpl::state_unregistered"); 00784 internal_event(STATE_IDLE); 00785 } 00786 00787 void M2MInterfaceImpl::state_sending_coap_data( EventData */*data*/) 00788 { 00789 tr_debug("M2MInterfaceImpl::state_sending_coap_data"); 00790 internal_event(STATE_WAITING); 00791 } 00792 00793 void M2MInterfaceImpl::state_coap_data_sent( EventData */*data*/) 00794 { 00795 tr_debug("M2MInterfaceImpl::state_coap_data_sent"); 00796 internal_event(STATE_WAITING); 00797 } 00798 00799 void M2MInterfaceImpl::state_coap_data_received( EventData *data) 00800 { 00801 tr_debug("M2MInterfaceImpl::state_coap_data_received"); 00802 if(data) { 00803 ReceivedData *event = static_cast<ReceivedData*> (data); 00804 sn_nsdl_addr_s address; 00805 00806 M2MInterface::NetworkStack stack = event->_address->_stack; 00807 00808 if(M2MInterface::LwIP_IPv4 == stack) { 00809 tr_debug("M2MInterfaceImpl::state_coap_data_received : IPv4 address"); 00810 address.type = SN_NSDL_ADDRESS_TYPE_IPV4; 00811 address.addr_len = 4; 00812 } else if((M2MInterface::LwIP_IPv6 == stack) || 00813 (M2MInterface::Nanostack_IPv6 == stack)) { 00814 tr_debug("M2MInterfaceImpl::state_coap_data_received : IPv6 address"); 00815 address.type = SN_NSDL_ADDRESS_TYPE_IPV6; 00816 address.addr_len = 16; 00817 } 00818 address.port = event->_address->_port; 00819 address.addr_ptr = (uint8_t*)event->_address->_address; 00820 address.addr_len = event->_address->_length; 00821 00822 // Process received data 00823 internal_event(STATE_PROCESSING_COAP_DATA); 00824 if(!_nsdl_interface->process_received_data(event->_data, 00825 event->_size, 00826 &address)) { 00827 tr_error("M2MInterfaceImpl::state_coap_data_received : M2MInterface::ResponseParseFailed"); 00828 _observer.error(M2MInterface::ResponseParseFailed); 00829 } 00830 } 00831 } 00832 00833 void M2MInterfaceImpl::state_processing_coap_data( EventData */*data*/) 00834 { 00835 tr_debug("M2MInterfaceImpl::state_processing_coap_data"); 00836 internal_event(STATE_WAITING); 00837 } 00838 00839 void M2MInterfaceImpl::state_coap_data_processed( EventData */*data*/) 00840 { 00841 tr_debug("M2MInterfaceImpl::state_coap_data_processed"); 00842 internal_event(STATE_WAITING); 00843 } 00844 00845 void M2MInterfaceImpl::state_waiting( EventData */*data*/) 00846 { 00847 tr_debug("M2MInterfaceImpl::state_waiting"); 00848 } 00849 00850 // generates an external event. called once per external event 00851 // to start the state machine executing 00852 void M2MInterfaceImpl::external_event(uint8_t new_state, 00853 EventData* p_data) 00854 { 00855 tr_debug("M2MInterfaceImpl::external_event : new state %d", new_state); 00856 // if we are supposed to ignore this event 00857 if (new_state == EVENT_IGNORED) { 00858 tr_debug("M2MInterfaceImpl::external_event : new state is EVENT_IGNORED"); 00859 // just delete the event data, if any 00860 if (p_data) { 00861 delete p_data; 00862 p_data = NULL; 00863 } 00864 _event_ignored = true; 00865 } 00866 else { 00867 tr_debug("M2MInterfaceImpl::external_event : handle new state"); 00868 // generate the event and execute the state engine 00869 internal_event(new_state, p_data); 00870 } 00871 } 00872 00873 // generates an internal event. called from within a state 00874 // function to transition to a new state 00875 void M2MInterfaceImpl::internal_event(uint8_t new_state, 00876 EventData* p_data) 00877 { 00878 tr_debug("M2MInterfaceImpl::internal_event : new state %d", new_state); 00879 _event_data = p_data; 00880 _event_generated = true; 00881 _current_state = new_state; 00882 state_engine(); 00883 } 00884 00885 // the state engine executes the state machine states 00886 void M2MInterfaceImpl::state_engine (void) 00887 { 00888 tr_debug("M2MInterfaceImpl::state_engine"); 00889 EventData* p_data_temp = NULL; 00890 00891 // while events are being generated keep executing states 00892 while (_event_generated) { 00893 p_data_temp = _event_data; // copy of event data pointer 00894 _event_data = NULL; // event data used up, reset ptr 00895 _event_generated = false; // event used up, reset flag 00896 00897 assert(_current_state < _max_states); 00898 00899 state_function( _current_state, p_data_temp ); 00900 00901 // if event data was used, then delete it 00902 if (p_data_temp) { 00903 delete p_data_temp; 00904 p_data_temp = NULL; 00905 } 00906 } 00907 } 00908 00909 void M2MInterfaceImpl::state_function( uint8_t current_state, EventData* data ) 00910 { 00911 switch( current_state ) { 00912 case STATE_IDLE: 00913 M2MInterfaceImpl::state_idle(data); 00914 break; 00915 case STATE_BOOTSTRAP: 00916 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00917 M2MInterfaceImpl::state_bootstrap(data); 00918 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00919 break; 00920 case STATE_BOOTSTRAP_ADDRESS_RESOLVED: 00921 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00922 M2MInterfaceImpl::state_bootstrap_address_resolved(data); 00923 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00924 break; 00925 case STATE_BOOTSTRAP_RESOURCE_CREATED: 00926 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00927 M2MInterfaceImpl::state_bootstrap_resource_created(data); 00928 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00929 break; 00930 case STATE_BOOTSTRAPPED: 00931 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00932 M2MInterfaceImpl::state_bootstrapped(data); 00933 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00934 break; 00935 case STATE_REGISTER: 00936 M2MInterfaceImpl::state_register(data); 00937 break; 00938 case STATE_REGISTER_ADDRESS_RESOLVED: 00939 M2MInterfaceImpl::state_register_address_resolved(data); 00940 break; 00941 case STATE_REGISTER_RESOURCE_CREATED: 00942 M2MInterfaceImpl::state_register_resource_created(data); 00943 break; 00944 case STATE_REGISTERED: 00945 M2MInterfaceImpl::state_registered(data); 00946 break; 00947 case STATE_UPDATE_REGISTRATION: 00948 M2MInterfaceImpl::state_update_registration(data); 00949 break; 00950 case STATE_UNREGISTER: 00951 M2MInterfaceImpl::state_unregister(data); 00952 break; 00953 case STATE_UNREGISTERED: 00954 M2MInterfaceImpl::state_unregistered(data); 00955 break; 00956 case STATE_SENDING_COAP_DATA: 00957 M2MInterfaceImpl::state_sending_coap_data(data); 00958 break; 00959 case STATE_COAP_DATA_SENT: 00960 M2MInterfaceImpl::state_coap_data_sent(data); 00961 break; 00962 case STATE_COAP_DATA_RECEIVED: 00963 M2MInterfaceImpl::state_coap_data_received(data); 00964 break; 00965 case STATE_PROCESSING_COAP_DATA: 00966 M2MInterfaceImpl::state_processing_coap_data(data); 00967 break; 00968 case STATE_COAP_DATA_PROCESSED: 00969 M2MInterfaceImpl::state_coap_data_processed(data); 00970 break; 00971 case STATE_WAITING: 00972 M2MInterfaceImpl::state_waiting(data); 00973 break; 00974 } 00975 }
Generated on Tue Jul 12 2022 13:05:09 by
1.7.2