Simulated product dispenser

Dependencies:   HTS221

Fork of mbed-cloud-workshop-connect-HTS221 by Jim Carver

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(String &name);
00227 
00228     /**
00229      * @brief Updates the domain name.
00230      * @param domain New domain name
00231      */
00232     virtual void update_domain(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      * @uri Uri path to the data.
00249      * @offset Data offset.
00250      * @async In async mode application must call this API again with the updated offset.
00251      *        If set to false then client will automatically download the whole package.
00252      * @get_data_cb Callback which is triggered once there is data available.
00253      * @get_data_error_cb Callback which is trigged in case of any error.
00254     */
00255     virtual void get_data_request(const char *uri,
00256                                   const size_t offset,
00257                                   const bool async,
00258                                   get_data_cb data_cb,
00259                                   get_data_error_cb error_cb,
00260                                   void *context);
00261 
00262     /**
00263      * @brief Sends the CoAP POST request to the server.
00264      * @uri Uri path to the data.
00265      * @async In async mode application must call this API again with the updated offset.
00266      *        If set to false then client will automatically download the whole package.
00267      * @payload_len Length of payload.
00268      * @payload_ptr, Pointer to payload buffer.
00269      * @get_data_cb Callback which is triggered once there is data available.
00270      * @get_data_error_cb Callback which is trigged in case of any error.
00271      */
00272     virtual void post_data_request(const char *uri,
00273                                    const bool async,
00274                                    const uint16_t payload_len,
00275                                    uint8_t *payload_ptr,
00276                                    get_data_cb data_cb,
00277                                    get_data_error_cb error_cb,
00278                                    void *context);
00279 
00280     /**
00281      * @brief Set custom uri query paramaters used in LWM2M registration.
00282      * @uri_query_params Uri query params. Parameters must be in key-value format:
00283      * "a=100&b=200". Maximum length can be up to 64 bytes.
00284      * @return False if maximum length exceeded otherwise True.
00285     */
00286     virtual bool set_uri_query_parameters(const char *uri_query_params);
00287 
00288 protected: // From M2MNsdlObserver
00289 
00290     virtual void coap_message_ready(uint8_t *data_ptr,
00291                                     uint16_t data_len,
00292                                     sn_nsdl_addr_s *address_ptr);
00293 
00294     virtual void client_registered(M2MServer *server_object);
00295 
00296     virtual void registration_updated(const M2MServer &server_object);
00297 
00298     virtual void registration_error(uint8_t error_code, bool retry = false);
00299 
00300     virtual void client_unregistered();
00301 
00302     virtual void bootstrap_done();
00303 
00304     virtual void bootstrap_finish();
00305 
00306     virtual void bootstrap_wait();
00307 
00308     virtual void bootstrap_error_wait(const char *reason);
00309 
00310     virtual void bootstrap_error(const char *reason);
00311 
00312     virtual void coap_data_processed();
00313 
00314     virtual void value_updated(M2MBase *base);
00315 
00316 protected: // From M2MConnectionObserver
00317 
00318     virtual void data_available(uint8_t* data,
00319                                 uint16_t data_size,
00320                                 const M2MConnectionObserver::SocketAddress &address);
00321 
00322     virtual void socket_error(uint8_t error_code, bool retry = true);
00323 
00324     virtual void address_ready(const M2MConnectionObserver::SocketAddress &address,
00325                                M2MConnectionObserver::ServerType server_type,
00326                                const uint16_t server_port);
00327 
00328     virtual void data_sent();
00329 
00330 protected: // from M2MTimerObserver
00331 
00332     virtual void timer_expired(M2MTimerObserver::Type type);
00333 
00334 
00335 private: // state machine state functions
00336 
00337     /**
00338     * When the state is Idle.
00339     */
00340     void state_idle(EventData* data);
00341 
00342     /**
00343     * When the client starts bootstrap.
00344     */
00345     void state_bootstrap( EventData *data);
00346 
00347     /**
00348     * When the bootstrap server address is resolved.
00349     */
00350     void state_bootstrap_address_resolved( EventData *data);
00351 
00352     /**
00353     * When the bootstrap resource is created.
00354     */
00355     void state_bootstrap_resource_created( EventData *data);
00356 
00357     /**
00358     * When the server has sent response and bootstrapping is done.
00359     */
00360     void state_bootstrapped( EventData *data);
00361 
00362     /**
00363     * When the client starts register.
00364     */
00365     void state_register( EventData *data);
00366 
00367     /**
00368     * When the server address for register is resolved.
00369     */
00370     void state_register_address_resolved( EventData *data);
00371 
00372     /**
00373     * When the client is registered.
00374     */
00375     void state_registered( EventData *data);
00376 
00377     /**
00378     * When the client is updating registration.
00379     */
00380     void state_update_registration( EventData *data);
00381 
00382     /**
00383     * When the client starts unregister.
00384     */
00385     void state_unregister( EventData *data);
00386 
00387     /**
00388     * When the client has been unregistered.
00389     */
00390     void state_unregistered( EventData *data);
00391 
00392     /**
00393     * When the coap data is been sent through socket.
00394     */
00395     void state_sending_coap_data( EventData *data);
00396 
00397     /**
00398     * When the coap data is sent successfully.
00399     */
00400     void state_coap_data_sent( EventData *data);
00401 
00402     /**
00403     * When the socket is receiving coap data.
00404     */
00405     void state_receiving_coap_data( EventData *data);
00406 
00407     /**
00408     * When the socket has received coap data.
00409     */
00410     void state_coap_data_received( EventData *data);
00411 
00412     /**
00413     * When the coap message is being processed.
00414     */
00415     void state_processing_coap_data( EventData *data);
00416 
00417     /**
00418     * When the coap message has been processed.
00419     */
00420     void state_coap_data_processed( EventData *data);
00421 
00422     /**
00423     * When the client is waiting to receive or send data.
00424     */
00425     void state_waiting( EventData *data);
00426 
00427     /**
00428      * Start registration update.
00429      */
00430     void start_register_update(M2MUpdateRegisterData *data);
00431 
00432     /**
00433     * State enumeration order must match the order of state
00434     * method entries in the state map
00435     */
00436     enum E_States {
00437         STATE_IDLE = 0,
00438         STATE_BOOTSTRAP,
00439         STATE_BOOTSTRAP_ADDRESS_RESOLVED,
00440         STATE_BOOTSTRAP_RESOURCE_CREATED,
00441         STATE_BOOTSTRAP_WAIT,
00442         STATE_BOOTSTRAP_ERROR_WAIT, // 5
00443         STATE_BOOTSTRAPPED,
00444         STATE_REGISTER,
00445         STATE_REGISTER_ADDRESS_RESOLVED,
00446         STATE_REGISTERED,
00447         STATE_UPDATE_REGISTRATION, // 10
00448         STATE_UNREGISTER,
00449         STATE_UNREGISTERED,
00450         STATE_SENDING_COAP_DATA,
00451         STATE_COAP_DATA_SENT,
00452         STATE_COAP_DATA_RECEIVED, // 15
00453         STATE_PROCESSING_COAP_DATA,
00454         STATE_COAP_DATA_PROCESSED,
00455         STATE_WAITING,
00456         STATE_MAX_STATES
00457     };
00458 
00459     /**
00460      * @brief Redirects the state machine to right function.
00461      * @param current_state Current state to be set.
00462      * @param data Data to be passed to the state function.
00463      */
00464     void state_function( uint8_t current_state, EventData* data  );
00465 
00466     /**
00467      * @brief State Engine maintaining state machine logic.
00468      */
00469     void state_engine(void);
00470 
00471     /**
00472     * External event which can trigger the state machine.
00473     * @param New The state to which the state machine should go.
00474     * @param data The data to be passed to the state machine.
00475     */
00476     void external_event(uint8_t, EventData* = NULL);
00477 
00478     /**
00479     * Internal event generated by state machine.
00480     * @param New State which the state machine should go to.
00481     * @param data The data to be passed to the state machine.
00482     */
00483     void internal_event(uint8_t, EventData* = NULL);
00484 
00485     /**
00486     * Queue mode enabled or not.
00487     * @return True if queue mode otherwise false.
00488     */
00489     bool queue_mode() const;
00490 
00491     enum
00492     {
00493         EVENT_IGNORED = 0xFE,
00494         CANNOT_HAPPEN
00495     };
00496 
00497     /**
00498      * Helper method for extracting the IP address part and port from the
00499      * given server address.
00500      * @param server_address Source URL (without "coap" or "coaps" prefix).
00501      * @param ip_address The extracted IP.
00502      * @param port The extracted port.
00503      */
00504     static void process_address(const String& server_address, String& ip_address, uint16_t& port);
00505 
00506     /**
00507      * Helper method for storing the error description to _error_description if the feature
00508      * has not been turned off.
00509      * @param error description
00510      */
00511     void set_error_description(const char *description);
00512 
00513     enum ReconnectionState{
00514         None,
00515         WithUpdate,
00516         Unregistration
00517     };
00518 
00519 private:
00520 
00521     EventData                   *_event_data;
00522     M2MTimer                    *_registration_flow_timer;
00523     uint16_t                    _server_port;
00524     uint16_t                    _listen_port;
00525     int32_t                     _life_time;
00526     String                      _server_ip_address;
00527     M2MSecurity                 *_register_server; //TODO: to be the list not owned
00528     M2MTimer                    _queue_sleep_timer;
00529     M2MTimer                    _retry_timer;
00530     callback_handler            _callback_handler;
00531     const uint8_t               _max_states;
00532     bool                        _event_ignored;
00533     bool                        _event_generated;
00534     bool                        _reconnecting;
00535     bool                        _retry_timer_expired;
00536     bool                        _bootstrapped;
00537     bool                        _bootstrap_finished;
00538     bool                        _queue_mode_timer_ongoing;
00539     uint8_t                     _current_state;
00540     BindingMode                 _binding_mode;
00541     ReconnectionState           _reconnection_state;
00542     M2MInterfaceObserver        &_observer;
00543     M2MConnectionSecurity       *_security_connection; // Doesn't own
00544     M2MConnectionHandler        _connection_handler;
00545     M2MNsdlInterface            _nsdl_interface;
00546     M2MSecurity                 *_security;
00547 
00548 #ifndef DISABLE_ERROR_DESCRIPTION
00549     // The DISABLE_ERROR_DESCRIPTION macro will reduce the flash usage by ~1800 bytes.
00550     char                        _error_description[MAX_ALLOWED_ERROR_STRING_LENGTH];
00551 #endif
00552 
00553     uint8_t                     _initial_reconnection_time;
00554     uint64_t                    _reconnection_time;
00555 
00556     friend class Test_M2MInterfaceImpl;
00557 
00558 };
00559 
00560 #define BEGIN_TRANSITION_MAP \
00561     static const uint8_t TRANSITIONS[] = {\
00562 
00563 #define TRANSITION_MAP_ENTRY(entry)\
00564     entry,
00565 
00566 #define END_TRANSITION_MAP(data) \
00567     0 };\
00568     external_event(TRANSITIONS[_current_state], data);
00569 
00570 #endif //M2M_INTERFACE_IMPL_H
00571 
00572