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: mbed Socket lwip-eth lwip-sys lwip
Fork of mbed-client-classic-example-lwip 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 "mbed-client/m2msecurity.h" 00024 #include "mbed-client/m2mconstants.h" 00025 #include "mbed-client/m2mtimer.h" 00026 #include "ns_trace.h" 00027 00028 M2MInterfaceImpl::M2MInterfaceImpl(M2MInterfaceObserver& observer, 00029 const String &ep_name, 00030 const String &ep_type, 00031 const int32_t l_time, 00032 const uint16_t listen_port, 00033 const String &dmn, 00034 M2MInterface::BindingMode mode, 00035 M2MInterface::NetworkStack stack, 00036 const String &con_addr) 00037 : _observer(observer), 00038 _nsdl_interface(new M2MNsdlInterface(*this)), 00039 _current_state(0), 00040 _max_states( STATE_MAX_STATES ), 00041 _event_generated(false), 00042 _event_data(NULL), 00043 _endpoint_name(ep_name), 00044 _endpoint_type(ep_type), 00045 _domain( dmn), 00046 _life_time(l_time), 00047 _binding_mode(mode), 00048 _context_address(con_addr), 00049 _listen_port(listen_port), 00050 _register_server(NULL), 00051 _event_ignored(false), 00052 _register_ongoing(false), 00053 _update_register_ongoing(false), 00054 _queue_sleep_timer(new M2MTimer(*this)), 00055 _callback_handler(NULL) 00056 { 00057 M2MConnectionSecurity::SecurityMode sec_mode = M2MConnectionSecurity::DTLS; 00058 //Hack for now 00059 if( _binding_mode == M2MInterface::TCP ){ 00060 _binding_mode = M2MInterface::UDP; 00061 sec_mode = M2MConnectionSecurity::TLS; 00062 }else if( _binding_mode == M2MInterface::TCP_QUEUE ){ 00063 _binding_mode = M2MInterface::UDP_QUEUE; 00064 sec_mode = M2MConnectionSecurity::TLS; 00065 } 00066 tr_debug("M2MInterfaceImpl::M2MInterfaceImpl() -IN"); 00067 _nsdl_interface->create_endpoint(_endpoint_name, 00068 _endpoint_type, 00069 _life_time, 00070 _domain, 00071 (uint8_t)_binding_mode, 00072 _context_address); 00073 00074 //Here we must use TCP still 00075 _connection_handler = new M2MConnectionHandler(*this, new M2MConnectionSecurity(sec_mode), mode, stack); 00076 00077 _connection_handler->bind_connection(_listen_port); 00078 tr_debug("M2MInterfaceImpl::M2MInterfaceImpl() -OUT"); 00079 } 00080 00081 00082 M2MInterfaceImpl::~M2MInterfaceImpl() 00083 { 00084 tr_debug("M2MInterfaceImpl::~M2MInterfaceImpl() - IN"); 00085 delete _queue_sleep_timer; 00086 delete _nsdl_interface; 00087 _connection_handler->stop_listening(); 00088 delete _connection_handler; 00089 tr_debug("M2MInterfaceImpl::~M2MInterfaceImpl() - OUT"); 00090 } 00091 00092 void M2MInterfaceImpl::bootstrap(M2MSecurity *security) 00093 { 00094 tr_debug("M2MInterfaceImpl::bootstrap(M2MSecurity *security) - IN"); 00095 // Transition to a new state based upon 00096 // the current state of the state machine 00097 M2MSecurityData* data = new M2MSecurityData(); 00098 data->_object = security; 00099 BEGIN_TRANSITION_MAP // - Current State - 00100 TRANSITION_MAP_ENTRY (STATE_BOOTSTRAP) // state_idle 00101 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap 00102 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state__bootstrap_address_resolved 00103 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_resource_created 00104 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrapped 00105 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register 00106 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_address_resolved 00107 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_resource_created 00108 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_registered 00109 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_update_registration 00110 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregister 00111 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregistered 00112 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_sending_coap_data 00113 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_sent 00114 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_received 00115 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_processing_coap_data 00116 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_processed 00117 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_waiting 00118 END_TRANSITION_MAP(data) 00119 if(_event_ignored) { 00120 _event_ignored = false; 00121 _observer.error(M2MInterface::NotAllowed); 00122 } 00123 tr_debug("M2MInterfaceImpl::bootstrap(M2MSecurity *security) - OUT"); 00124 } 00125 00126 void M2MInterfaceImpl::cancel_bootstrap() 00127 { 00128 //TODO: Do we need this ? 00129 } 00130 00131 void M2MInterfaceImpl::register_object(M2MSecurity *security, const M2MObjectList &object_list) 00132 { 00133 tr_debug("M2MInterfaceImpl::register_object(M2MSecurity *security,const M2MObjectList &object_list) - IN"); 00134 // Transition to a new state based upon 00135 // the current state of the state machine 00136 //TODO: manage register object in a list. 00137 if(!_register_ongoing) { 00138 _register_ongoing = true; 00139 _register_server = security; 00140 M2MRegisterData *data = new M2MRegisterData(); 00141 data->_object = security; 00142 data->_object_list = object_list; 00143 BEGIN_TRANSITION_MAP // - Current State - 00144 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_idle 00145 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap 00146 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state__bootstrap_address_resolved 00147 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_resource_created 00148 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_bootstrapped 00149 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register 00150 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_address_resolved 00151 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_resource_created 00152 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_registered 00153 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_update_registration 00154 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregister 00155 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregistered 00156 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_sending_coap_data 00157 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_sent 00158 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_received 00159 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_processing_coap_data 00160 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_processed 00161 TRANSITION_MAP_ENTRY (STATE_REGISTER) // state_waiting 00162 END_TRANSITION_MAP(data) 00163 if(_event_ignored) { 00164 _event_ignored = false; 00165 _observer.error(M2MInterface::NotAllowed); 00166 } 00167 } else { 00168 tr_debug("M2MInterfaceImpl::register_object(M2MSecurity *security,const M2MObjectList &object_list) - NOT ALLOWED"); 00169 _observer.error(M2MInterface::NotAllowed); 00170 } 00171 tr_debug("M2MInterfaceImpl::register_object(M2MSecurity *security,const M2MObjectList &object_list) - OUT"); 00172 } 00173 00174 void M2MInterfaceImpl::update_registration(M2MSecurity *security_object, const uint32_t lifetime) 00175 { 00176 tr_debug("M2MInterfaceImpl::update_registration(M2MSecurity *security,const uint32_t lifetime) - IN"); 00177 // Transition to a new state based upon 00178 // the current state of the state machine 00179 if(lifetime != 0 && (lifetime < MINIMUM_REGISTRATION_TIME)) { 00180 _observer.error(M2MInterface::InvalidParameters); 00181 } else if(!_update_register_ongoing){ 00182 _update_register_ongoing = true; 00183 M2MUpdateRegisterData *data = new M2MUpdateRegisterData(); 00184 data->_object = security_object; 00185 data->_lifetime = lifetime; 00186 BEGIN_TRANSITION_MAP // - Current State - 00187 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_idle 00188 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap 00189 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state__bootstrap_address_resolved 00190 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_resource_created 00191 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrapped 00192 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register 00193 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_address_resolved 00194 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_resource_created 00195 TRANSITION_MAP_ENTRY (STATE_UPDATE_REGISTRATION) // state_registered 00196 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_update_registration 00197 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregister 00198 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregistered 00199 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_sending_coap_data 00200 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_sent 00201 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_received 00202 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_processing_coap_data 00203 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_processed 00204 TRANSITION_MAP_ENTRY (STATE_UPDATE_REGISTRATION) // state_waiting 00205 END_TRANSITION_MAP(data) 00206 if(_event_ignored) { 00207 _event_ignored = false; 00208 _observer.error(M2MInterface::NotAllowed); 00209 } 00210 } else { 00211 tr_debug("M2MInterfaceImpl::update_registration(M2MSecurity *security,const M2MObjectList &object_list) - NOT ALLOWED"); 00212 _observer.error(M2MInterface::NotAllowed); 00213 } 00214 tr_debug("M2MInterfaceImpl::update_registration(M2MSecurity *security,const uint32_t lifetime) - OUT"); 00215 } 00216 00217 void M2MInterfaceImpl::unregister_object(M2MSecurity* /*security*/) 00218 { 00219 tr_debug("M2MInterfaceImpl::unregister_object(M2MSecurity *security) - IN"); 00220 // Transition to a new state based upon 00221 // the current state of the state machine 00222 BEGIN_TRANSITION_MAP // - Current State - 00223 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_idle 00224 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap 00225 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state__bootstrap_address_resolved 00226 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrap_resource_created 00227 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_bootstrapped 00228 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register 00229 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_address_resolved 00230 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_register_resource_created 00231 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_registered 00232 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_update_registration 00233 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregister 00234 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_unregistered 00235 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_sending_coap_data 00236 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_sent 00237 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_received 00238 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_processing_coap_data 00239 TRANSITION_MAP_ENTRY (EVENT_IGNORED) // state_coap_data_processed 00240 TRANSITION_MAP_ENTRY (STATE_UNREGISTER) // state_waiting 00241 END_TRANSITION_MAP(NULL) 00242 if(_event_ignored) { 00243 _event_ignored = false; 00244 _observer.error(M2MInterface::NotAllowed); 00245 } 00246 tr_debug("M2MInterfaceImpl::unregister_object(M2MSecurity *security) - OUT"); 00247 } 00248 00249 void M2MInterfaceImpl::set_queue_sleep_handler(callback_handler handler) 00250 { 00251 tr_debug("M2MInterfaceImpl::set_queue_sleep_handler()"); 00252 _callback_handler = handler; 00253 } 00254 00255 void M2MInterfaceImpl::coap_message_ready(uint8_t *data_ptr, 00256 uint16_t data_len, 00257 sn_nsdl_addr_s *address_ptr) 00258 { 00259 tr_debug("M2MInterfaceImpl::coap_message_ready(uint8_t *data_ptr,uint16_t data_len,sn_nsdl_addr_s *address_ptr)"); 00260 internal_event(STATE_SENDING_COAP_DATA); 00261 if(!_connection_handler->send_data(data_ptr,data_len,address_ptr)) { 00262 internal_event( STATE_IDLE); 00263 tr_error("M2MInterfaceImpl::coap_message_ready() - M2MInterface::NetworkError"); 00264 _observer.error(M2MInterface::NetworkError); 00265 } 00266 } 00267 00268 void M2MInterfaceImpl::client_registered(M2MServer *server_object) 00269 { 00270 tr_debug("M2MInterfaceImpl::client_registered(M2MServer *server_object)"); 00271 internal_event(STATE_REGISTERED); 00272 //Inform client is registered. 00273 //TODO: manage register object in a list. 00274 _observer.object_registered(_register_server,*server_object); 00275 } 00276 00277 void M2MInterfaceImpl::registration_updated(const M2MServer &server_object) 00278 { 00279 tr_debug("M2MInterfaceImpl::registration_updated(const M2MServer &server_object)"); 00280 internal_event(STATE_REGISTERED); 00281 _observer.registration_updated(_register_server,server_object); 00282 } 00283 00284 00285 void M2MInterfaceImpl::registration_error(uint8_t error_code) 00286 { 00287 tr_debug("M2MInterfaceImpl::registration_error(uint8_t error_code) %d", error_code); 00288 internal_event(STATE_IDLE); 00289 _observer.error((M2MInterface::Error)error_code); 00290 } 00291 00292 void M2MInterfaceImpl::client_unregistered() 00293 { 00294 tr_debug("M2MInterfaceImpl::client_unregistered()"); 00295 internal_event(STATE_UNREGISTERED); 00296 //TODO: manage register object in a list. 00297 _observer.object_unregistered(_register_server); 00298 } 00299 00300 void M2MInterfaceImpl::bootstrap_done(M2MSecurity *security_object) 00301 { 00302 tr_debug("M2MInterfaceImpl::bootstrap_done(M2MSecurity *security_object)"); 00303 internal_event(STATE_BOOTSTRAPPED); 00304 _observer.bootstrap_done(security_object); 00305 } 00306 00307 void M2MInterfaceImpl::bootstrap_error() 00308 { 00309 tr_debug("M2MInterfaceImpl::bootstrap_error()"); 00310 internal_event(STATE_IDLE); 00311 _observer.error(M2MInterface::BootstrapFailed); 00312 } 00313 00314 void M2MInterfaceImpl::coap_data_processed() 00315 { 00316 tr_debug("M2MInterfaceImpl::coap_data_processed()"); 00317 internal_event(STATE_COAP_DATA_PROCESSED); 00318 } 00319 00320 void M2MInterfaceImpl::value_updated(M2MBase *base) 00321 { 00322 tr_debug("M2MInterfaceImpl::value_updated(M2MBase *base)"); 00323 if(base) { 00324 M2MBase::BaseType type = base->base_type(); 00325 _observer.value_updated(base, type); 00326 } 00327 } 00328 00329 void M2MInterfaceImpl::data_available(uint8_t* data, 00330 uint16_t data_size, 00331 const M2MConnectionObserver::SocketAddress &address) 00332 { 00333 tr_debug("M2MInterfaceImpl::data_available(uint8_t* data,uint16_t data_size,const M2MConnectionObserver::SocketAddress &address)"); 00334 ReceivedData *event = new ReceivedData(); 00335 event->_data = data; 00336 event->_size = data_size; 00337 event->_address = &address; 00338 internal_event(STATE_COAP_DATA_RECEIVED, event); 00339 } 00340 00341 void M2MInterfaceImpl::socket_error(uint8_t /*error_code*/) 00342 { 00343 tr_debug("M2MInterfaceImpl::socket_error(uint8_t error_code)"); 00344 internal_event(STATE_IDLE); 00345 M2MInterface::Error error = M2MInterface::NetworkError; 00346 _observer.error(error); 00347 } 00348 00349 void M2MInterfaceImpl::address_ready(const M2MConnectionObserver::SocketAddress &address, 00350 M2MConnectionObserver::ServerType server_type, 00351 const uint16_t server_port) 00352 { 00353 tr_debug("M2MInterfaceImpl::address_ready(const M2MConnectionObserver::SocketAddress ,M2MConnectionObserver::ServerType,const uint16_t)"); 00354 ResolvedAddressData *data = new ResolvedAddressData(); 00355 data->_address = &address; 00356 data->_port = server_port; 00357 if( M2MConnectionObserver::Bootstrap == server_type) { 00358 tr_debug("M2MInterfaceImpl::address_ready() Server Type Bootstrap"); 00359 internal_event(STATE_BOOTSTRAP_ADDRESS_RESOLVED, data); 00360 } else { 00361 tr_debug("M2MInterfaceImpl::address_ready() Server Type LWM2M"); 00362 internal_event(STATE_REGISTER_ADDRESS_RESOLVED, data); 00363 } 00364 } 00365 00366 void M2MInterfaceImpl::data_sent() 00367 { 00368 tr_debug("M2MInterfaceImpl::data_sent()"); 00369 if(_binding_mode == M2MInterface::UDP_QUEUE || 00370 _binding_mode == M2MInterface::TCP_QUEUE || 00371 _binding_mode == M2MInterface::SMS_QUEUE || 00372 _binding_mode == M2MInterface::UDP_SMS_QUEUE) { 00373 if(_callback_handler) { 00374 _queue_sleep_timer->stop_timer(); 00375 _queue_sleep_timer->start_timer(RETRY_COUNT*RETRY_INTERVAL*1000, M2MTimerObserver::QueueSleep); 00376 } 00377 } 00378 internal_event(STATE_COAP_DATA_SENT); 00379 } 00380 00381 void M2MInterfaceImpl::timer_expired(M2MTimerObserver::Type type) 00382 { 00383 tr_debug("M2MInterfaceImpl::timer_expired()"); 00384 if(M2MTimerObserver::QueueSleep == type) { 00385 if(_callback_handler) { 00386 _callback_handler(); 00387 } 00388 _queue_sleep_timer->stop_timer(); 00389 } 00390 } 00391 00392 // state machine sits here. 00393 void M2MInterfaceImpl::state_idle(EventData* /*data*/) 00394 { 00395 // Handle Idle state here 00396 // Cleanup all resources, if necessary 00397 _connection_handler->stop_listening(); 00398 _nsdl_interface->stop_timers(); 00399 _register_ongoing = false; 00400 _update_register_ongoing = false; 00401 tr_debug("M2MInterfaceImpl::state_idle"); 00402 } 00403 00404 void M2MInterfaceImpl::state_bootstrap( EventData *data) 00405 { 00406 tr_debug("M2MInterfaceImpl::state_bootstrap"); 00407 // Start with bootstrapping preparation 00408 bool success = false; 00409 if(data) { 00410 M2MSecurityData *event = (M2MSecurityData *)data; 00411 M2MSecurity *security = event->_object; 00412 if(security) { 00413 if(M2MSecurity::Bootstrap == security->server_type()) { 00414 tr_debug("M2MInterfaceImpl::state_bootstrap - server_type : M2MSecurity::Bootstrap"); 00415 String server_address = security->resource_value_string(M2MSecurity::M2MServerUri); 00416 tr_debug("M2MInterfaceImpl::state_bootstrap - server_address %s", server_address.c_str()); 00417 String ip_address; 00418 uint16_t port; 00419 if(server_address.compare(0,COAP.size(),COAP) == 0) { 00420 server_address = server_address.substr(COAP.size(), 00421 server_address.size()-COAP.size()); 00422 int colonFound = server_address.find_last_of(':'); 00423 if(colonFound != -1) { 00424 ip_address = server_address.substr(0,colonFound); 00425 port = atoi(server_address.substr(colonFound+1, 00426 server_address.size()-ip_address.size()).c_str()); 00427 00428 tr_debug("M2MInterfaceImpl::state_bootstrap - IP address %s , Port %d", ip_address.c_str(), port); 00429 // If bind and resolving server address succeed then proceed else 00430 // return error to the application and go to Idle state. 00431 if(_connection_handler->resolve_server_address(ip_address, 00432 port, 00433 M2MConnectionObserver::Bootstrap, 00434 security)) { 00435 tr_debug("M2MInterfaceImpl::state_bootstrap - resolve_server_address - success"); 00436 success = true; 00437 } 00438 } 00439 } 00440 } 00441 } 00442 } 00443 if(!success) { 00444 tr_error("M2MInterfaceImpl::state_bootstrap - M2MInterface::InvalidParameters"); 00445 _observer.error(M2MInterface::InvalidParameters); 00446 internal_event(STATE_IDLE); 00447 } 00448 } 00449 00450 void M2MInterfaceImpl::state_bootstrap_address_resolved( EventData *data) 00451 { 00452 tr_debug("M2MInterfaceImpl::state_bootstrap_address_resolved"); 00453 ResolvedAddressData *event = (ResolvedAddressData *)data; 00454 sn_nsdl_addr_s address; 00455 00456 M2MInterface::NetworkStack stack = event->_address->_stack; 00457 00458 if(M2MInterface::LwIP_IPv4 == stack) { 00459 tr_debug("M2MInterfaceImpl::state_bootstrap_address_resolved : IPv4 address"); 00460 address.type = SN_NSDL_ADDRESS_TYPE_IPV4; 00461 address.addr_len = 4; 00462 } else if((M2MInterface::LwIP_IPv6 == stack) || 00463 (M2MInterface::Nanostack_IPv6 == stack)) { 00464 tr_debug("M2MInterfaceImpl::state_bootstrap_address_resolved : IPv6 address"); 00465 address.type = SN_NSDL_ADDRESS_TYPE_IPV6; 00466 address.addr_len = 16; 00467 } 00468 address.port = event->_port; 00469 address.addr_ptr = (uint8_t*)event->_address->_address; 00470 _connection_handler->start_listening_for_data(); 00471 if(_nsdl_interface->create_bootstrap_resource(&address)) { 00472 tr_debug("M2MInterfaceImpl::state_bootstrap_address_resolved : create_bootstrap_resource - success"); 00473 internal_event(STATE_BOOTSTRAP_RESOURCE_CREATED); 00474 } else{ 00475 // If resource creation fails then inform error to application 00476 tr_error("M2MInterfaceImpl::state_bootstrap_address_resolved : M2MInterface::InvalidParameters"); 00477 internal_event(STATE_IDLE); 00478 _observer.error(M2MInterface::InvalidParameters); 00479 } 00480 } 00481 00482 void M2MInterfaceImpl::state_bootstrap_resource_created( EventData */*data*/) 00483 { 00484 tr_debug("M2MInterfaceImpl::state_bootstrap_resource_created"); 00485 } 00486 00487 void M2MInterfaceImpl::state_bootstrapped( EventData */*data*/) 00488 { 00489 tr_debug("M2MInterfaceImpl::state_bootstrapped"); 00490 } 00491 00492 void M2MInterfaceImpl::state_register( EventData *data) 00493 { 00494 tr_debug("M2MInterfaceImpl::state_register"); 00495 // Start with registration preparation 00496 bool success = false; 00497 M2MInterface::Error error = M2MInterface::InvalidParameters; 00498 if(data) { 00499 M2MRegisterData *event = (M2MRegisterData *)data; 00500 M2MSecurity *security = event->_object; 00501 if(security) { 00502 if(M2MSecurity::M2MServer == security->server_type()) { 00503 tr_debug("M2MInterfaceImpl::state_register - server_type : M2MSecurity::M2MServer"); 00504 if(_nsdl_interface->create_nsdl_list_structure(event->_object_list)) { 00505 tr_debug("M2MInterfaceImpl::state_register - create_nsdl_list_structure - success"); 00506 // If the nsdl resource structure is created successfully 00507 String server_address = security->resource_value_string(M2MSecurity::M2MServerUri); 00508 tr_debug("M2MInterfaceImpl::state_register - server_address %s", server_address.c_str()); 00509 String ip_address; 00510 uint16_t port; 00511 if(server_address.compare(0,COAP.size(),COAP) == 0) { 00512 server_address = server_address.substr(COAP.size(), 00513 server_address.size()-COAP.size()); 00514 int colonFound = server_address.find_last_of(':'); //10 00515 if(colonFound != -1) { 00516 ip_address = server_address.substr(0,colonFound); 00517 port = atoi(server_address.substr(colonFound+1, 00518 server_address.size()-ip_address.size()).c_str()); 00519 00520 tr_debug("M2MInterfaceImpl::state_register - IP address %s , Port %d", ip_address.c_str(), port); 00521 // If bind and resolving server address succeed then proceed else 00522 // return error to the application and go to Idle state. 00523 if(_connection_handler->resolve_server_address(ip_address, 00524 port, 00525 M2MConnectionObserver::LWM2MServer, 00526 security)) { 00527 tr_debug("M2MInterfaceImpl::state_register - resolve_server_address - success"); 00528 success = true; 00529 } else { 00530 tr_error("M2MInterfaceImpl::state_register - set error as M2MInterface::NetworkError"); 00531 error = M2MInterface::NetworkError; 00532 } 00533 } 00534 } 00535 } 00536 } 00537 } 00538 } 00539 if(!success) { 00540 tr_error("M2MInterfaceImpl::state_register - Error Occured %d", (int)error); 00541 internal_event(STATE_IDLE); 00542 _observer.error(error); 00543 } 00544 } 00545 00546 void M2MInterfaceImpl::state_register_address_resolved( EventData *data) 00547 { 00548 tr_debug("M2MInterfaceImpl::state_register_address_resolved"); 00549 if(data) { 00550 ResolvedAddressData *event = (ResolvedAddressData *)data; 00551 00552 sn_nsdl_addr_type_e address_type = SN_NSDL_ADDRESS_TYPE_IPV6; 00553 00554 M2MInterface::NetworkStack stack = event->_address->_stack; 00555 00556 if(M2MInterface::LwIP_IPv4 == stack) { 00557 tr_debug("M2MInterfaceImpl::state_register_address_resolved : IPv4 address"); 00558 address_type = SN_NSDL_ADDRESS_TYPE_IPV4; 00559 } else if((M2MInterface::LwIP_IPv6 == stack) || 00560 (M2MInterface::Nanostack_IPv6 == stack)) { 00561 tr_debug("M2MInterfaceImpl::state_register_address_resolved : IPv6 address"); 00562 address_type = SN_NSDL_ADDRESS_TYPE_IPV6; 00563 } 00564 internal_event(STATE_REGISTER_RESOURCE_CREATED); 00565 _connection_handler->start_listening_for_data(); 00566 if(!_nsdl_interface->send_register_message((uint8_t*)event->_address->_address,event->_port, address_type)) { 00567 // If resource creation fails then inform error to application 00568 tr_error("M2MInterfaceImpl::state_register_address_resolved : M2MInterface::InvalidParameters"); 00569 internal_event(STATE_IDLE); 00570 _observer.error(M2MInterface::InvalidParameters); 00571 } 00572 } 00573 } 00574 00575 void M2MInterfaceImpl::state_register_resource_created( EventData */*data*/) 00576 { 00577 tr_debug("M2MInterfaceImpl::state_register_resource_created"); 00578 } 00579 00580 void M2MInterfaceImpl::state_registered( EventData */*data*/) 00581 { 00582 tr_debug("M2MInterfaceImpl::state_registered"); 00583 _register_ongoing = false; 00584 _update_register_ongoing = false; 00585 } 00586 00587 void M2MInterfaceImpl::state_update_registration( EventData *data) 00588 { 00589 tr_debug("M2MInterfaceImpl::state_update_registration"); 00590 // Start with registration preparation 00591 bool success = false; 00592 if(data) { 00593 M2MUpdateRegisterData *event = (M2MUpdateRegisterData *)data; 00594 success = _nsdl_interface->send_update_registration(event->_lifetime); 00595 00596 } 00597 if(!success) { 00598 tr_error("M2MInterfaceImpl::state_register_address_resolved : M2MInterface::InvalidParameters"); 00599 internal_event(STATE_IDLE); 00600 _observer.error(M2MInterface::InvalidParameters); 00601 } 00602 } 00603 00604 void M2MInterfaceImpl::state_unregister( EventData */*data*/) 00605 { 00606 tr_debug("M2MInterfaceImpl::state_unregister"); 00607 internal_event(STATE_SENDING_COAP_DATA); 00608 if(!_nsdl_interface->send_unregister_message()) { 00609 tr_error("M2MInterfaceImpl::state_unregister : M2MInterface::NotRegistered"); 00610 internal_event(STATE_IDLE); 00611 _observer.error(M2MInterface::NotRegistered); 00612 } 00613 } 00614 00615 void M2MInterfaceImpl::state_unregistered( EventData */*data*/) 00616 { 00617 tr_debug("M2MInterfaceImpl::state_unregistered"); 00618 internal_event(STATE_IDLE); 00619 } 00620 00621 void M2MInterfaceImpl::state_sending_coap_data( EventData */*data*/) 00622 { 00623 tr_debug("M2MInterfaceImpl::state_sending_coap_data"); 00624 internal_event(STATE_WAITING); 00625 } 00626 00627 void M2MInterfaceImpl::state_coap_data_sent( EventData */*data*/) 00628 { 00629 tr_debug("M2MInterfaceImpl::state_coap_data_sent"); 00630 internal_event(STATE_WAITING); 00631 } 00632 00633 void M2MInterfaceImpl::state_coap_data_received( EventData *data) 00634 { 00635 tr_debug("M2MInterfaceImpl::state_coap_data_received"); 00636 if(data) { 00637 ReceivedData *event = (ReceivedData*)data; 00638 sn_nsdl_addr_s address; 00639 00640 M2MInterface::NetworkStack stack = event->_address->_stack; 00641 00642 if(M2MInterface::LwIP_IPv4 == stack) { 00643 tr_debug("M2MInterfaceImpl::state_coap_data_received : IPv4 address"); 00644 address.type = SN_NSDL_ADDRESS_TYPE_IPV4; 00645 address.addr_len = 4; 00646 } else if((M2MInterface::LwIP_IPv6 == stack) || 00647 (M2MInterface::Nanostack_IPv6 == stack)) { 00648 tr_debug("M2MInterfaceImpl::state_coap_data_received : IPv6 address"); 00649 address.type = SN_NSDL_ADDRESS_TYPE_IPV6; 00650 address.addr_len = 16; 00651 } 00652 address.port = event->_address->_port; 00653 address.addr_ptr = (uint8_t*)event->_address->_address; 00654 00655 // Process received data 00656 internal_event(STATE_PROCESSING_COAP_DATA); 00657 if(!_nsdl_interface->process_received_data(event->_data, 00658 event->_size, 00659 &address)) { 00660 tr_error("M2MInterfaceImpl::state_coap_data_received : M2MInterface::ResponseParseFailed"); 00661 _observer.error(M2MInterface::ResponseParseFailed); 00662 } 00663 } 00664 } 00665 00666 void M2MInterfaceImpl::state_processing_coap_data( EventData */*data*/) 00667 { 00668 tr_debug("M2MInterfaceImpl::state_processing_coap_data"); 00669 internal_event(STATE_WAITING); 00670 } 00671 00672 void M2MInterfaceImpl::state_coap_data_processed( EventData */*data*/) 00673 { 00674 tr_debug("M2MInterfaceImpl::state_coap_data_processed"); 00675 internal_event(STATE_WAITING); 00676 } 00677 00678 void M2MInterfaceImpl::state_waiting( EventData */*data*/) 00679 { 00680 tr_debug("M2MInterfaceImpl::state_waiting"); 00681 } 00682 00683 // generates an external event. called once per external event 00684 // to start the state machine executing 00685 void M2MInterfaceImpl::external_event(uint8_t new_state, 00686 EventData* p_data) 00687 { 00688 tr_debug("M2MInterfaceImpl::external_event : new state %d", new_state); 00689 // if we are supposed to ignore this event 00690 if (new_state == EVENT_IGNORED) { 00691 tr_debug("M2MInterfaceImpl::external_event : new state is EVENT_IGNORED"); 00692 // just delete the event data, if any 00693 if (p_data) { 00694 delete p_data; 00695 p_data = NULL; 00696 } 00697 _event_ignored = true; 00698 } 00699 else { 00700 tr_debug("M2MInterfaceImpl::external_event : handle new state"); 00701 // generate the event and execute the state engine 00702 internal_event(new_state, p_data); 00703 } 00704 } 00705 00706 // generates an internal event. called from within a state 00707 // function to transition to a new state 00708 void M2MInterfaceImpl::internal_event(uint8_t new_state, 00709 EventData* p_data) 00710 { 00711 tr_debug("M2MInterfaceImpl::internal_event : new state %d", new_state); 00712 _event_data = p_data; 00713 _event_generated = true; 00714 _current_state = new_state; 00715 state_engine(); 00716 } 00717 00718 // the state engine executes the state machine states 00719 void M2MInterfaceImpl::state_engine (void ) 00720 { 00721 tr_debug("M2MInterfaceImpl::state_engine"); 00722 EventData* p_data_temp = NULL; 00723 00724 // while events are being generated keep executing states 00725 while (_event_generated) { 00726 p_data_temp = _event_data; // copy of event data pointer 00727 _event_data = NULL; // event data used up, reset ptr 00728 _event_generated = false; // event used up, reset flag 00729 00730 assert(_current_state < _max_states); 00731 00732 state_function( _current_state, p_data_temp ); 00733 00734 // if event data was used, then delete it 00735 if (p_data_temp) { 00736 delete p_data_temp; 00737 p_data_temp = NULL; 00738 } 00739 } 00740 } 00741 00742 void M2MInterfaceImpl::state_function( uint8_t current_state, EventData* data ) 00743 { 00744 switch( current_state ) { 00745 case STATE_IDLE: 00746 M2MInterfaceImpl::state_idle(data); 00747 break; 00748 case STATE_BOOTSTRAP: 00749 M2MInterfaceImpl::state_bootstrap(data); 00750 break; 00751 case STATE_BOOTSTRAP_ADDRESS_RESOLVED: 00752 M2MInterfaceImpl::state_bootstrap_address_resolved(data); 00753 break; 00754 case STATE_BOOTSTRAP_RESOURCE_CREATED: 00755 M2MInterfaceImpl::state_bootstrap_resource_created(data); 00756 break; 00757 case STATE_BOOTSTRAPPED: 00758 M2MInterfaceImpl::state_bootstrapped(data); 00759 break; 00760 case STATE_REGISTER: 00761 M2MInterfaceImpl::state_register(data); 00762 break; 00763 case STATE_REGISTER_ADDRESS_RESOLVED: 00764 M2MInterfaceImpl::state_register_address_resolved(data); 00765 break; 00766 case STATE_REGISTER_RESOURCE_CREATED: 00767 M2MInterfaceImpl::state_register_resource_created(data); 00768 break; 00769 case STATE_REGISTERED: 00770 M2MInterfaceImpl::state_registered(data); 00771 break; 00772 case STATE_UPDATE_REGISTRATION: 00773 M2MInterfaceImpl::state_update_registration(data); 00774 break; 00775 case STATE_UNREGISTER: 00776 M2MInterfaceImpl::state_unregister(data); 00777 break; 00778 case STATE_UNREGISTERED: 00779 M2MInterfaceImpl::state_unregistered(data); 00780 break; 00781 case STATE_SENDING_COAP_DATA: 00782 M2MInterfaceImpl::state_sending_coap_data(data); 00783 break; 00784 case STATE_COAP_DATA_SENT: 00785 M2MInterfaceImpl::state_coap_data_sent(data); 00786 break; 00787 case STATE_COAP_DATA_RECEIVED: 00788 M2MInterfaceImpl::state_coap_data_received(data); 00789 break; 00790 case STATE_PROCESSING_COAP_DATA: 00791 M2MInterfaceImpl::state_processing_coap_data(data); 00792 break; 00793 case STATE_COAP_DATA_PROCESSED: 00794 M2MInterfaceImpl::state_coap_data_processed(data); 00795 break; 00796 case STATE_WAITING: 00797 M2MInterfaceImpl::state_waiting(data); 00798 break; 00799 } 00800 }
Generated on Tue Jul 12 2022 13:53:46 by
