Timothy Beight / Mbed 2 deprecated 6_songs-from-the-cloud

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of 6_songs-from-the-cloud by MakingMusicWorkshop

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 "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 }