Mayank Gupta / Mbed OS pelion-example-frdm

Dependencies:   FXAS21002 FXOS8700Q

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers m2minterfaceimpl.h Source File

m2minterfaceimpl.h

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 #ifndef M2M_INTERFACE_IMPL_H
00017 #define M2M_INTERFACE_IMPL_H
00018 
00019 #include "mbed-client/m2minterface.h"
00020 #include "mbed-client/m2mserver.h"
00021 #include "mbed-client/m2mconnectionobserver.h"
00022 #include "mbed-client/m2mconnectionsecurity.h"
00023 #include "include/m2mnsdlobserver.h"
00024 #include "include/m2mnsdlinterface.h"
00025 #include "mbed-client/m2mtimerobserver.h"
00026 #include "mbed-client/m2mtimer.h"
00027 #include "mbed-client/m2mconnectionhandler.h"
00028 #include "mbed-client/m2mconstants.h"
00029 
00030 //FORWARD DECLARATION
00031 class M2MConnectionSecurity;
00032 class EventData;
00033 class M2MUpdateRegisterData;
00034 /**
00035  *  @brief M2MInterfaceImpl.
00036  *  This class implements handling of all mbed Client Interface operations
00037  *  defined in OMA LWM2M specifications.
00038  *  This includes Bootstrapping, Client Registration, Device Management &
00039  *  Service Enablement and Information Reporting.
00040  */
00041 
00042 class  M2MInterfaceImpl : public M2MInterface,
00043                           public M2MNsdlObserver,
00044                           public M2MConnectionObserver,
00045                           public M2MTimerObserver
00046 {
00047 private:
00048     // Prevents the use of assignment operator by accident.
00049     M2MInterfaceImpl& operator=( const M2MInterfaceImpl& /*other*/ );
00050 
00051     // Prevents the use of copy constructor by accident
00052     M2MInterfaceImpl( const M2MInterfaceImpl& /*other*/ );
00053 
00054 friend class M2MInterfaceFactory;
00055 
00056 private:
00057 
00058     /**
00059      * @brief Constructor
00060      * @param observer, Observer to pass the event callbacks for various
00061      * interface operations.
00062      * @param endpoint_name Endpoint name of the client.
00063      * @param endpoint_type Endpoint type of the client.
00064      * @param life_time Life time of the client in seconds
00065      * @param listen_port Listening port for the endpoint, default is 8000.
00066      * @param domain Domain of the client.
00067      * @param mode Binding mode of the client, default is UDP
00068      * @param stack Network stack to be used for connection, default is LwIP_IPv4.
00069      * @param context_address Context address, default is empty.
00070      */
00071     M2MInterfaceImpl(M2MInterfaceObserver& observer,
00072                      const String &endpoint_name,
00073                      const String &endpoint_type,
00074                      const int32_t life_time,
00075                      const uint16_t listen_port,
00076                      const String &domain = "",
00077                      BindingMode mode = M2MInterface::NOT_SET,
00078                      M2MInterface::NetworkStack stack = M2MInterface::LwIP_IPv4,
00079                      const String &context_address = "");
00080 
00081 public:
00082 
00083     /**
00084      * @brief Destructor
00085      */
00086     virtual ~M2MInterfaceImpl();
00087 
00088     /**
00089      * @brief Initiates bootstrapping of the client with the provided Bootstrap
00090      * server information.
00091      * @param security_object Security object which contains information
00092      * required for successful bootstrapping of the client.
00093      */
00094     virtual void bootstrap(M2MSecurity *security);
00095 
00096     /**
00097      * @brief Cancels on going bootstrapping operation of the client. If the client has
00098      * already successfully bootstrapped then this function deletes existing
00099      * bootstrap information from the client.
00100      */
00101     virtual void cancel_bootstrap();
00102 
00103     /**
00104      * @brief Finishes on going bootstrap in cases where client is the one to finish it.
00105      */
00106     virtual void finish_bootstrap();
00107 
00108     /**
00109      * @brief Initiates registration of the provided Security object to the
00110      * corresponding LWM2M server.
00111      * @param security_object Security object which contains information
00112      * required for registering to the LWM2M server.
00113      * If client wants to register to multiple LWM2M servers then it has call
00114      * this function once for each of LWM2M server object separately.
00115      * @param object_list Objects which contains information
00116      * which the client want to register to the LWM2M server.
00117      */
00118     virtual void register_object(M2MSecurity *security_object, const M2MBaseList &list);
00119 
00120     /**
00121      * @brief Initiates registration of the provided Security object to the
00122      * corresponding LWM2M server.
00123      * @param security_object Security object which contains information
00124      * required for registering to the LWM2M server.
00125      * If client wants to register to multiple LWM2M servers then it has call
00126      * this function once for each of LWM2M server object separately.
00127      * @param object_list Objects which contains information
00128      * which the client want to register to the LWM2M server.
00129      */
00130     virtual void register_object(M2MSecurity *security_object, const M2MObjectList &object_list);
00131 
00132     /**
00133      * @brief Updates or refreshes the client's registration on the LWM2M
00134      * server.
00135      * @param security_object Security object from which the device object
00136      * needs to update registration, if there is only one LWM2M server registered
00137      * then this parameter can be NULL.
00138      * @param lifetime Lifetime for the endpoint client in seconds.
00139      */
00140     virtual void update_registration(M2MSecurity *security_object, const uint32_t lifetime = 0);
00141 
00142     /**
00143      * @brief Updates or refreshes the client's registration on the LWM2M
00144      * server. Use this function to publish new objects to LWM2M server.
00145      * @param security_object The security object from which the device object
00146      * needs to update the registration. If there is only one LWM2M server registered,
00147      * this parameter can be NULL.
00148      * @param object_list Objects that contain information about the
00149      * client attempting to register to the LWM2M server.
00150      * @param lifetime The lifetime of the endpoint client in seconds. If the same value
00151      * has to be passed, set the default value to 0.
00152      */
00153     virtual void update_registration(M2MSecurity *security_object, const M2MBaseList &list,
00154                                      const uint32_t lifetime = 0);
00155 
00156     /**
00157      * @brief Updates or refreshes the client's registration on the LWM2M
00158      * server. Use this function to publish new objects to LWM2M server.
00159      * @param security_object The security object from which the device object
00160      * needs to update the registration. If there is only one LWM2M server registered,
00161      * this parameter can be NULL.
00162      * @param object_list Objects that contain information about the
00163      * client attempting to register to the LWM2M server.
00164      * @param lifetime The lifetime of the endpoint client in seconds. If the same value
00165      * has to be passed, set the default value to 0.
00166      */
00167     virtual void update_registration(M2MSecurity *security_object, const M2MObjectList &object_list,
00168                                      const uint32_t lifetime = 0);
00169 
00170     /**
00171      * @brief Unregisters the registered object from the LWM2M server
00172      * @param security_object Security object from which the device object
00173      * needs to be unregistered. If there is only one LWM2M server registered
00174      * this parameter can be NULL.
00175      */
00176     virtual void unregister_object(M2MSecurity* security = NULL);
00177 
00178     /**
00179      * @brief Sets the function which will be called indicating client
00180      * is going to sleep when the Binding mode is selected with Queue mode.
00181      * @param callback A function pointer that will be called when client
00182      * goes to sleep.
00183      */
00184     virtual void set_queue_sleep_handler(callback_handler handler);
00185 
00186     /**
00187      * @brief Sets the network interface handler that is used by client to connect
00188      * to a network over IP.
00189      * @param handler A network interface handler that is used by client to connect.
00190      *  This API is optional but provides a mechanism for different platforms to
00191      * manage usage of underlying network interface by client.
00192      */
00193     virtual void set_platform_network_handler(void *handler = NULL);
00194 
00195     /**
00196      * \brief Sets the function callback that will be called by mbed-client for
00197      * fetching random number from application for ensuring strong entropy.
00198      * \param random_callback A function pointer that will be called by mbed-client
00199      * while performing secure handshake.
00200      * Function signature should be uint32_t (*random_number_callback)(void);
00201      */
00202     virtual void set_random_number_callback(random_number_cb callback);
00203 
00204     /**
00205      * \brief Sets the function callback that will be called by mbed-client for
00206      * providing entropy source from application for ensuring strong entropy.
00207      * \param entropy_callback A function pointer that will be called by mbed-client
00208      * while performing secure handshake.
00209      * Function signature , if using mbed-client-mbedtls should be
00210      * int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output,
00211      *                                     size_t len, size_t *olen);
00212      */
00213     virtual void set_entropy_callback(entropy_cb callback);
00214 
00215     /**
00216       * \brief Removes an object from M2MInterfaceImpl.
00217       * Does not call delete on the object though.
00218       * \return true if the object was found and false if the object was not found.
00219       */
00220     virtual bool remove_object(M2MBase *object);
00221 
00222     /**
00223      * @brief Updates the endpoint name.
00224      * @param name New endpoint name
00225      */
00226     virtual void update_endpoint(const String &name);
00227 
00228     /**
00229      * @brief Updates the domain name.
00230      * @param domain New domain name
00231      */
00232     virtual void update_domain(const String &domain);
00233 
00234     /**
00235      * @brief Return internal endpoint name
00236      * @return internal endpoint name
00237      */
00238     virtual const String internal_endpoint_name() const;
00239 
00240     /**
00241      * @brief Return error description for the latest error code
00242      * @return Error description string
00243      */
00244     virtual const char *error_description() const;
00245 
00246     /**
00247      * @brief Sends the CoAP GET request to the server.
00248      * @type Download type.
00249      * @uri Uri path to the data.
00250      * @offset Data offset.
00251      * @async In async mode application must call this API again with the updated offset.
00252      *        If set to false then client will automatically download the whole package.
00253      * @get_data_cb Callback which is triggered once there is data available.
00254      * @get_data_error_cb Callback which is trigged in case of any error.
00255     */
00256     virtual void get_data_request(DownloadType type,
00257                                   const char *uri,
00258                                   const size_t offset,
00259                                   const bool async,
00260                                   get_data_cb data_cb,
00261                                   get_data_error_cb error_cb,
00262                                   void *context);
00263 
00264     /**
00265      * @brief Sends the CoAP POST request to the server.
00266      * @uri Uri path to the data.
00267      * @async In async mode application must call this API again with the updated offset.
00268      *        If set to false then client will automatically download the whole package.
00269      * @payload_len Length of payload.
00270      * @payload_ptr, Pointer to payload buffer.
00271      * @get_data_cb Callback which is triggered once there is data available.
00272      * @get_data_error_cb Callback which is trigged in case of any error.
00273      */
00274     virtual void post_data_request(const char *uri,
00275                                    const bool async,
00276                                    const uint16_t payload_len,
00277                                    uint8_t *payload_ptr,
00278                                    get_data_cb data_cb,
00279                                    get_data_error_cb error_cb,
00280                                    void *context);
00281 
00282     /**
00283      * @brief Set custom uri query paramaters used in LWM2M registration.
00284      * @uri_query_params Uri query params. Parameters must be in key-value format:
00285      * "a=100&b=200". Maximum length can be up to 64 bytes.
00286      * @return False if maximum length exceeded otherwise True.
00287     */
00288     virtual bool set_uri_query_parameters(const char *uri_query_params);
00289 
00290     /**
00291      * \brief Pauses client's timed functionality and closes network connection
00292      * to the Cloud. After successful call the operation is continued
00293      * by calling resume().
00294      *
00295      * \note This operation does not unregister client from the Cloud.
00296      * Closes the socket and removes interface from the interface list.
00297      */
00298     virtual void pause();
00299 
00300     /**
00301      * \brief Resumes client's timed functionality and network connection
00302      * to the Cloud. Updates registration. Can be only called after
00303      * a successful call to pause().
00304      *
00305      * \param iface A handler to the network interface.
00306      */
00307     virtual void resume(void *iface, const M2MBaseList &list);
00308 
00309 protected: // From M2MNsdlObserver
00310 
00311     virtual void coap_message_ready(uint8_t *data_ptr,
00312                                     uint16_t data_len,
00313                                     sn_nsdl_addr_s *address_ptr);
00314 
00315     virtual void client_registered(M2MServer *server_object);
00316 
00317     virtual void registration_updated(const M2MServer &server_object);
00318 
00319     virtual void registration_error(uint8_t error_code, bool retry = false, bool full_registration = false);
00320 
00321     virtual void client_unregistered();
00322 
00323     virtual void bootstrap_done();
00324 
00325     virtual void bootstrap_finish();
00326 
00327     virtual void bootstrap_wait();
00328 
00329     virtual void bootstrap_error_wait(const char *reason);
00330 
00331     virtual void bootstrap_error(const char *reason);
00332 
00333     virtual void coap_data_processed();
00334 
00335     virtual void value_updated(M2MBase *base);
00336 
00337 protected: // From M2MConnectionObserver
00338 
00339     virtual void data_available(uint8_t* data,
00340                                 uint16_t data_size,
00341                                 const M2MConnectionObserver::SocketAddress &address);
00342 
00343     virtual void socket_error(int error_code, bool retry = true);
00344 
00345     virtual void address_ready(const M2MConnectionObserver::SocketAddress &address,
00346                                M2MConnectionObserver::ServerType server_type,
00347                                const uint16_t server_port);
00348 
00349     virtual void data_sent();
00350 
00351 protected: // from M2MTimerObserver
00352 
00353     virtual void timer_expired(M2MTimerObserver::Type type);
00354 
00355 
00356 private: // state machine state functions
00357 
00358     /**
00359     * When the state is Idle.
00360     */
00361     void state_idle(EventData* data);
00362 
00363     /**
00364     * When the client starts bootstrap.
00365     */
00366     void state_bootstrap( EventData *data);
00367 
00368     /**
00369     * When the bootstrap server address is resolved.
00370     */
00371     void state_bootstrap_address_resolved( EventData *data);
00372 
00373     /**
00374     * When the bootstrap resource is created.
00375     */
00376     void state_bootstrap_resource_created( EventData *data);
00377 
00378     /**
00379     * When the server has sent response and bootstrapping is done.
00380     */
00381     void state_bootstrapped( EventData *data);
00382 
00383     /**
00384     * When the client starts register.
00385     */
00386     void state_register( EventData *data);
00387 
00388     /**
00389     * When the server address for register is resolved.
00390     */
00391     void state_register_address_resolved( EventData *data);
00392 
00393     /**
00394     * When the client is registered.
00395     */
00396     void state_registered( EventData *data);
00397 
00398     /**
00399     * When the client is updating registration.
00400     */
00401     void state_update_registration( EventData *data);
00402 
00403     /**
00404     * When the client starts unregister.
00405     */
00406     void state_unregister( EventData *data);
00407 
00408     /**
00409     * When the client has been unregistered.
00410     */
00411     void state_unregistered( EventData *data);
00412 
00413     /**
00414     * When the coap data is been sent through socket.
00415     */
00416     void state_sending_coap_data( EventData *data);
00417 
00418     /**
00419     * When the coap data is sent successfully.
00420     */
00421     void state_coap_data_sent( EventData *data);
00422 
00423     /**
00424     * When the socket is receiving coap data.
00425     */
00426     void state_receiving_coap_data( EventData *data);
00427 
00428     /**
00429     * When the socket has received coap data.
00430     */
00431     void state_coap_data_received( EventData *data);
00432 
00433     /**
00434     * When the coap message is being processed.
00435     */
00436     void state_processing_coap_data( EventData *data);
00437 
00438     /**
00439     * When the coap message has been processed.
00440     */
00441     void state_coap_data_processed( EventData *data);
00442 
00443     /**
00444     * When the client is waiting to receive or send data.
00445     */
00446     void state_waiting( EventData *data);
00447 
00448     /**
00449      * Start registration update.
00450      */
00451     void start_register_update(M2MUpdateRegisterData *data);
00452 
00453     /**
00454     * State enumeration order must match the order of state
00455     * method entries in the state map
00456     */
00457     enum E_States {
00458         STATE_IDLE = 0,
00459         STATE_BOOTSTRAP,
00460         STATE_BOOTSTRAP_ADDRESS_RESOLVED,
00461         STATE_BOOTSTRAP_RESOURCE_CREATED,
00462         STATE_BOOTSTRAP_WAIT,
00463         STATE_BOOTSTRAP_ERROR_WAIT, // 5
00464         STATE_BOOTSTRAPPED,
00465         STATE_REGISTER,
00466         STATE_REGISTER_ADDRESS_RESOLVED,
00467         STATE_REGISTERED,
00468         STATE_UPDATE_REGISTRATION, // 10
00469         STATE_UNREGISTER,
00470         STATE_UNREGISTERED,
00471         STATE_SENDING_COAP_DATA,
00472         STATE_COAP_DATA_SENT,
00473         STATE_COAP_DATA_RECEIVED, // 15
00474         STATE_PROCESSING_COAP_DATA,
00475         STATE_COAP_DATA_PROCESSED,
00476         STATE_WAITING,
00477         STATE_MAX_STATES
00478     };
00479 
00480     /**
00481      * @brief Redirects the state machine to right function.
00482      * @param current_state Current state to be set.
00483      * @param data Data to be passed to the state function.
00484      */
00485     void state_function( uint8_t current_state, EventData* data  );
00486 
00487     /**
00488      * @brief State Engine maintaining state machine logic.
00489      */
00490     void state_engine(void);
00491 
00492     /**
00493     * External event which can trigger the state machine.
00494     * @param New The state to which the state machine should go.
00495     * @param data The data to be passed to the state machine.
00496     */
00497     void external_event(uint8_t, EventData* = NULL);
00498 
00499     /**
00500     * Internal event generated by state machine.
00501     * @param New State which the state machine should go to.
00502     * @param data The data to be passed to the state machine.
00503     */
00504     void internal_event(uint8_t, EventData* = NULL);
00505 
00506     /**
00507     * Queue mode enabled or not.
00508     * @return True if queue mode otherwise false.
00509     */
00510     bool queue_mode() const;
00511 
00512     enum
00513     {
00514         EVENT_IGNORED = 0xFE,
00515         CANNOT_HAPPEN
00516     };
00517 
00518     /**
00519      * Helper method for extracting the IP address part and port from the
00520      * given server address.
00521      * @param server_address Source URL (without "coap" or "coaps" prefix).
00522      * @param ip_address The extracted IP.
00523      * @param port The extracted port.
00524      */
00525     static void process_address(const String& server_address, String& ip_address, uint16_t& port);
00526 
00527     /**
00528      * Helper method for storing the error description to _error_description if the feature
00529      * has not been turned off.
00530      * @param error description
00531      */
00532     void set_error_description(const char *description);
00533 
00534     enum ReconnectionState{
00535         None,
00536         WithUpdate,
00537         Unregistration
00538     };
00539 
00540 private:
00541 
00542     EventData                   *_event_data;
00543     M2MTimer                    *_registration_flow_timer;
00544     uint16_t                    _server_port;
00545     uint16_t                    _listen_port;
00546     int32_t                     _life_time;
00547     String                      _server_ip_address;
00548     M2MSecurity                 *_register_server; //TODO: to be the list not owned
00549     M2MTimer                    _queue_sleep_timer;
00550     M2MTimer                    _retry_timer;
00551     callback_handler            _callback_handler;
00552     const uint8_t               _max_states;
00553     bool                        _event_ignored;
00554     bool                        _event_generated;
00555     bool                        _reconnecting;
00556     bool                        _retry_timer_expired;
00557     bool                        _bootstrapped;
00558     bool                        _bootstrap_finished;
00559     bool                        _queue_mode_timer_ongoing;
00560     uint8_t                     _current_state;
00561     BindingMode                 _binding_mode;
00562     ReconnectionState           _reconnection_state;
00563     M2MInterfaceObserver        &_observer;
00564     M2MConnectionSecurity       *_security_connection; // Doesn't own
00565     M2MConnectionHandler        _connection_handler;
00566     M2MNsdlInterface            _nsdl_interface;
00567     M2MSecurity                 *_security;
00568 
00569 #ifndef DISABLE_ERROR_DESCRIPTION
00570     // The DISABLE_ERROR_DESCRIPTION macro will reduce the flash usage by ~1800 bytes.
00571     char                        _error_description[MAX_ALLOWED_ERROR_STRING_LENGTH];
00572 #endif
00573 
00574     uint8_t                     _initial_reconnection_time;
00575     uint64_t                    _reconnection_time;
00576 
00577     friend class Test_M2MInterfaceImpl;
00578 
00579 };
00580 
00581 #define BEGIN_TRANSITION_MAP \
00582     static const uint8_t TRANSITIONS[] = {\
00583 
00584 #define TRANSITION_MAP_ENTRY(entry)\
00585     entry,
00586 
00587 #define END_TRANSITION_MAP(data) \
00588     0 };\
00589     external_event(TRANSITIONS[_current_state], data);
00590 
00591 #endif //M2M_INTERFACE_IMPL_H
00592 
00593