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.
Dependencies: MAX44000 PWM_Tone_Library nexpaq_mdk
Fork of LED_Demo by
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 12:28:37 by
1.7.2
