Ram Gandikota / Mbed OS ABCD
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers m2minterfaceimpl.cpp Source File

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