Mbed Cloud example program for workshop in W27 2018.

Dependencies:   MMA7660 LM75B

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers m2mnsdlinterface.h Source File

m2mnsdlinterface.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 M2MNSDLINTERFACE_H
00017 #define M2MNSDLINTERFACE_H
00018 
00019 #include "ns_list.h"
00020 #include "mbed-client/m2mvector.h"
00021 #include "mbed-client/m2mconfig.h"
00022 #include "mbed-client/m2minterface.h"
00023 #include "mbed-client/m2mtimerobserver.h"
00024 #include "mbed-client/m2mobservationhandler.h"
00025 #include "mbed-client/m2mtimer.h"
00026 #include "mbed-client/m2mbase.h"
00027 #include "mbed-client/m2mserver.h"
00028 #include "include/nsdllinker.h"
00029 
00030 //FORWARD DECLARARTION
00031 class M2MSecurity;
00032 class M2MObject;
00033 class M2MObjectInstance;
00034 class M2MResource;
00035 class M2MResourceInstance;
00036 class M2MNsdlObserver;
00037 class M2MServer;
00038 class M2MConnectionHandler;
00039 
00040 typedef Vector<M2MObject *> M2MObjectList;
00041 
00042 /**
00043  * @brief M2MNsdlInterface
00044  * Class which interacts between mbed Client C++ Library and mbed-client-c library.
00045  */
00046 class M2MNsdlInterface : public M2MTimerObserver,
00047                          public M2MObservationHandler
00048 {
00049 private:
00050     // Prevents the use of assignment operator by accident.
00051     M2MNsdlInterface& operator=( const M2MNsdlInterface& /*other*/ );
00052 
00053     // Prevents the use of copy constructor by accident
00054     M2MNsdlInterface( const M2MNsdlInterface& /*other*/ );
00055 
00056 public:
00057 
00058     struct get_data_request_s {
00059         get_data_cb         on_get_data_cb;
00060         get_data_error_cb   on_get_data_error_cb;
00061         size_t              received_size;
00062         uint32_t            msg_token;
00063         char                *uri_path;
00064         void                *context;
00065         bool                async_req;
00066         ns_list_link_t      link;
00067     };
00068 
00069     typedef NS_LIST_HEAD(get_data_request_s, link) get_data_request_list_t;
00070 
00071     /**
00072     * @brief Constructor
00073     * @param observer, Observer to pass the event callbacks from nsdl library.
00074     */
00075     M2MNsdlInterface(M2MNsdlObserver &observer, M2MConnectionHandler &connection_handler);
00076 
00077     /**
00078      * @brief Destructor
00079      */
00080     virtual ~M2MNsdlInterface();
00081 
00082     /**
00083      * @brief Creates endpoint object for the nsdl stack.
00084      * @param endpoint_name, Endpoint name of the client.
00085      * @param endpoint_type, Endpoint type of the client.
00086      * @param life_time, Life time of the client in seconds
00087      * @param domain, Domain of the client.
00088      * @param mode, Binding mode of the client, default is UDP
00089      * @param context_address, Context address default is empty.
00090     */
00091     void create_endpoint(const String &endpoint_name,
00092                          const String &endpoint_type,
00093                          const int32_t life_time,
00094                          const String &domain,
00095                          const uint8_t mode,
00096                          const String &context_address);
00097 
00098     /**
00099      * @brief Deletes the endpoint.
00100     */
00101     void delete_endpoint();
00102 
00103     /**
00104      * @brief Updates endpoint name.
00105     */
00106     void update_endpoint(const String &name);
00107 
00108     /**
00109      * @brief Updates domain.
00110     */
00111     void update_domain(const String &domain);
00112 
00113     /**
00114      * @brief Creates the NSDL structure for the registered objectlist.
00115      * @param object_list, List of objects to be registered.
00116      * @return true if structure created successfully else false.
00117     */
00118     bool create_nsdl_list_structure(const M2MObjectList &object_list);
00119 
00120     /**
00121      * @brief Removed the NSDL resource for the given resource.
00122      * @param base, Resource to be removed.
00123      * @return true if removed successfully else false.
00124     */
00125     bool remove_nsdl_resource(M2MBase *base);
00126 
00127     /**
00128      * @brief Creates the bootstrap object.
00129      * @param address Bootstrap address.
00130      * @return true if created and sent successfully else false.
00131     */
00132     bool create_bootstrap_resource(sn_nsdl_addr_s *address);
00133 
00134     /**
00135      * @brief Sets the register message to the server.
00136      * @param address M2MServer address.
00137      * @param address_length M2MServer address length.
00138      * @param port M2MServer port.
00139      * @param address_type IP Address type.
00140     */
00141     void set_server_address(uint8_t* address,
00142                             uint8_t address_length,
00143                             const uint16_t port,
00144                             sn_nsdl_addr_type_e address_type);
00145     /**
00146      * @brief Sends the register message to the server.
00147      * @return  true if register sent successfully else false.
00148     */
00149     bool send_register_message();
00150 
00151     /**
00152      * @brief Sends the CoAP GET request to the server.
00153      * @uri Uri path to the data.
00154      * @offset Data offset.
00155      * @async In async mode application must call this API again with the updated offset.
00156      *        If set to false then client will automatically download the whole package.
00157      * @get_data_cb Callback which is triggered once there is data available.
00158      * @get_data_error_cb Callback which is trigged in case of any error.
00159      * @context Application context.
00160     */
00161     bool send_get_data_request(const char *uri,
00162                                const size_t offset,
00163                                const bool async,
00164                                get_data_cb data_cb,
00165                                get_data_error_cb error_cb,
00166                                void *context);
00167 
00168     /**
00169      * @brief Sends the update registration message to the server.
00170      * @param lifetime, Updated lifetime value in seconds.
00171      * @param clear_queue, Empties resending queue, by default it doesn't empties queue.
00172      * @return  true if sent successfully else false.
00173      *
00174     */
00175     bool send_update_registration(const uint32_t lifetime = 0, bool clear_queue = false);
00176 
00177     /**
00178      * @brief Sends unregister message to the server.
00179      * @return  true if unregister sent successfully else false.
00180     */
00181     bool send_unregister_message();
00182 
00183     /**
00184      * @brief Memory Allocation required for libCoap.
00185      * @param size, Size of memory to be reserved.
00186     */
00187     static void* memory_alloc(uint32_t size);
00188 
00189     /**
00190      * @brief Memory free functions required for libCoap
00191      * @param ptr, Object whose memory needs to be freed.
00192     */
00193     static void memory_free(void *ptr);
00194 
00195     /**
00196     * @brief Callback from nsdl library to inform the data is ready
00197     * to be sent to server.
00198     * @param nsdl_handle, Handler for the nsdl structure for this endpoint
00199     * @param protocol, Protocol format of the data
00200     * @param data, Data to be sent.
00201     * @param data_len, Size of the data to be sent
00202     * @param address, server address where data has to be sent.
00203     * @return 1 if successful else 0.
00204     */
00205     uint8_t send_to_server_callback(struct nsdl_s * nsdl_handle,
00206                                     sn_nsdl_capab_e protocol,
00207                                     uint8_t *data,
00208                                     uint16_t data_len,
00209                                     sn_nsdl_addr_s *address);
00210 
00211     /**
00212     * @brief Callback from nsdl library to inform the data which is
00213     * received from server for the client has been converted to coap message.
00214     * @param nsdl_handle, Handler for the nsdl structure for this endpoint
00215     * @param coap_header, Coap message formed from data.
00216     * @param address, Server address from where the data is received.
00217     * @return 1 if successful else 0.
00218     */
00219     uint8_t received_from_server_callback(struct nsdl_s * nsdl_handle,
00220                                           sn_coap_hdr_s *coap_header,
00221                                           sn_nsdl_addr_s *address);
00222 
00223     /**
00224     * @brief Callback from nsdl library to inform the data which is
00225     * received from server for the resources has been converted to coap message.
00226     * @param nsdl_handle, Handler for the nsdl resource structure for this endpoint..
00227     * @param coap_header, Coap message formed from data.
00228     * @param address, Server address from where the data is received.
00229     * @param nsdl_capab, Protocol for the message, currently only coap is supported.
00230     * @return 1 if successful else 0.
00231     */
00232     uint8_t resource_callback(struct nsdl_s *nsdl_handle, sn_coap_hdr_s *coap,
00233                                sn_nsdl_addr_s *address,
00234                                sn_nsdl_capab_e nsdl_capab);
00235 
00236     /**
00237      * @brief Callback when there is data received from server and needs to be processed.
00238      * @param data, data received from server.
00239      * @param data_size, data size received from server.
00240      * @param addres, address structure of the server.
00241      * @return true if successfully processed else false.
00242      */
00243     bool process_received_data(uint8_t *data,
00244                                uint16_t data_size,
00245                                sn_nsdl_addr_s *address);
00246 
00247     /**
00248      * @brief Stops all the timers in case there is any errors.
00249      */
00250     void stop_timers();
00251 
00252     /**
00253      * @brief Returns nsdl handle.
00254      * @return ndsl handle
00255      */
00256     nsdl_s* get_nsdl_handle() const;
00257 
00258     /**
00259      * @brief Get endpoint name
00260      * @return endpoint name
00261      */
00262     const String& endpoint_name() const;
00263 
00264     /**
00265      * @brief Get internal endpoint name
00266      * @return internal endpoint name
00267      */
00268     const String internal_endpoint_name() const;
00269 
00270     /**
00271      * @brief Set server address
00272      * @param server_address, Bootstrap or M2M server address.
00273      */
00274     void set_server_address(const char *server_address);
00275 
00276     /**
00277      * @brief Get NSDL timer.
00278      * @return NSDL execution timer.
00279      */
00280     M2MTimer &get_nsdl_execution_timer();
00281 
00282     /**
00283      * @brief Get unregister state.
00284      * @return Is unregistration ongoing.
00285      */
00286     bool get_unregister_ongoing() const;
00287 
00288     /**
00289      * @brief Starts the NSDL execution timer.
00290      */
00291     void start_nsdl_execution_timer();
00292 
00293     /**
00294      * @brief Returns security object.
00295      * @return M2MSecurity object, contains lwm2m server information.
00296      */
00297     M2MSecurity* get_security_object();
00298 
00299     /**
00300      * @brief Returns auto-observation token.
00301      * @param path, Resource path, used for searching the right object.
00302      * @param token[OUT], Token data.
00303      * @return Length of the token if found otherwise 0.
00304      */
00305     uint8_t find_auto_obs_token(const char *path, uint8_t *token) const;
00306 
00307 protected: // from M2MTimerObserver
00308 
00309     virtual void timer_expired(M2MTimerObserver::Type type);
00310 
00311 protected: // from M2MObservationHandler
00312 
00313     virtual void observation_to_be_sent(M2MBase *object,
00314                                         uint16_t obs_number,
00315                                         const m2m::Vector<uint16_t> &changed_instance_ids,
00316                                         bool send_object = false);
00317 
00318     virtual void resource_to_be_deleted(M2MBase* base);
00319 
00320     virtual void value_updated(M2MBase *base);
00321 
00322     virtual void remove_object(M2MBase *object);
00323 #ifndef DISABLE_DELAYED_RESPONSE
00324     virtual void send_delayed_response(M2MBase *base);
00325 #endif
00326 
00327 private:
00328 
00329     /**
00330      * Enum defining an LWM2M object type.
00331     */
00332     typedef enum {
00333         SECURITY = 0x00,
00334         SERVER   = 0x01,
00335         DEVICE   = 0x02
00336     }ObjectType;
00337 
00338     /**
00339     * @brief Initializes all the nsdl library component to be usable.
00340     * @return true if initialization is successful else false.
00341     */
00342     bool initialize();
00343 
00344     bool add_object_to_list(M2MObject *object);
00345 
00346     bool create_nsdl_object_structure(M2MObject *object);
00347 
00348     bool create_nsdl_object_instance_structure(M2MObjectInstance *object_instance);
00349 
00350     bool create_nsdl_resource_structure(M2MResource *resource,
00351                                         bool multiple_instances = false);
00352 
00353     bool create_nsdl_resource(M2MBase *base);
00354 
00355     static String coap_to_string(const uint8_t *coap_data_ptr,
00356                           int coap_data_ptr_length);
00357 
00358     void execute_nsdl_process_loop();
00359 
00360     uint64_t registration_time() const;
00361 
00362     M2MBase* find_resource(const String &object,
00363                            const uint16_t msg_id) const;
00364 
00365     M2MBase* find_resource(const M2MObject *object,
00366                            const String &object_instance,
00367                            const uint16_t msg_id) const;
00368 
00369     M2MBase* find_resource(const M2MObjectInstance *object_instance,
00370                            const String &resource_instance,
00371                            const uint16_t msg_id) const;
00372 
00373     M2MBase* find_resource(const M2MResource *resource,
00374                            const String &object_name,
00375                            const String &resource_instance) const;
00376 
00377     bool object_present(M2MObject * object) const;
00378 
00379     static M2MInterface::Error interface_error(const sn_coap_hdr_s &coap_header);
00380 
00381     void send_object_observation(M2MObject *object,
00382                                  uint16_t obs_number,
00383                                  const m2m::Vector<uint16_t> &changed_instance_ids,
00384                                  bool send_object, bool resend);
00385 
00386     void send_object_instance_observation(M2MObjectInstance *object_instance,
00387                                           uint16_t obs_number, bool resend);
00388 
00389     void send_resource_observation(M2MResource *resource, uint16_t obs_number, bool resend);
00390 
00391     /**
00392      * @brief Allocate (size + 1) amount of memory, copy size bytes into
00393      * it and add zero termination.
00394      * @param source Source string to copy, may not be NULL.
00395      * @param size The size of memory to be reserved.
00396     */
00397     static uint8_t* alloc_string_copy(const uint8_t* source, uint16_t size);
00398 
00399     /**
00400      * @brief Utility method to convert given lifetime int to ascii
00401      * and allocate a buffer for it and set it to _endpoint->lifetime_ptr.
00402      * @param lifetime A new value for lifetime.
00403     */
00404     void set_endpoint_lifetime_buffer(int lifetime);
00405 
00406     /**
00407      * @brief Handle incoming bootstrap PUT message.
00408      * @param coap_header, Received CoAP message
00409      * @param address, Server address
00410     */
00411     void handle_bootstrap_put_message(sn_coap_hdr_s *coap_header, sn_nsdl_addr_s *address);
00412 
00413     /**
00414      * @brief Handle bootstrap finished message.
00415      * @param coap_header, Received CoAP message
00416      * @param address, Server address
00417     */
00418     void handle_bootstrap_finished(sn_coap_hdr_s *coap_header,sn_nsdl_addr_s *address);
00419 
00420     /**
00421      * @brief Handle bootstrap delete message.
00422      * @param coap_header, Received CoAP message
00423      * @param address, Server address
00424     */
00425     void handle_bootstrap_delete(sn_coap_hdr_s *coap_header,sn_nsdl_addr_s *address);
00426 
00427     /**
00428      * @brief Parse bootstrap TLV message.
00429      * @param coap_header, Received CoAP message
00430      * @return True if parsing was succesful else false
00431     */
00432     bool parse_bootstrap_message(sn_coap_hdr_s *coap_header, M2MNsdlInterface::ObjectType lwm2m_object_type);
00433 
00434     /**
00435      * @brief Parse bootstrap TLV message.
00436      * @param coap_header, Received CoAP message
00437      * @return True if parsing was succesful else false
00438     */
00439     bool validate_security_object();
00440 
00441     /**
00442      * @brief Handle bootstrap errors.
00443      * @param reason, Reason for Bootstrap failure.
00444      * @param wait, True if need to wait that ACK has been sent.
00445      *              False if reconnection can start immediately.
00446     */
00447     void handle_bootstrap_error(const char *reason, bool wait);
00448 
00449     /**
00450      * @brief Handle different coap errors.
00451      * @param coap_header, CoAP structure.
00452      * @return Error reason.
00453     */
00454     static const char *coap_error(const sn_coap_hdr_s &coap_header);
00455 
00456     /**
00457      * @brief Claim
00458      */
00459     void claim_mutex();
00460 
00461     /**
00462      * @brief Release
00463      */
00464     void release_mutex();
00465 
00466     /**
00467      * @brief Change operation mode of every resource.
00468      * @param object, Object to be updated.
00469      * @return operation, New operation mode.
00470     */
00471     void change_operation_mode(M2MObject *object, M2MBase::Operation operation);
00472 
00473     /**
00474      * @brief Parse URI query parameters and pass those to nsdl-c.
00475      * @return True if parsing success otherwise False
00476     */
00477     bool parse_and_send_uri_query_parameters();
00478 
00479     /**
00480      * @brief Handle pending notifications.
00481      * @param clear, If set clears the flag to initial state otherwise sends the notification.
00482     */
00483     void handle_pending_notifications(bool clear);
00484 
00485     /**
00486      * @brief Callback function that triggers the registration update call.
00487      * @param argument, Arguments part of the POST request.
00488     */
00489     void update_trigger_callback(void *argument);
00490 
00491     bool lifetime_value_changed() const;
00492 
00493     static void execute_notification_delivery_status_cb(M2MBase* object, int32_t msgid);
00494 
00495     bool is_response_to_get_req(const sn_coap_hdr_s *coap_header, get_data_request_s &get_data);
00496 
00497     void free_get_request_list(const sn_coap_hdr_s *coap_header = NULL);
00498 
00499 private:
00500 
00501     M2MNsdlObserver                         &_observer;
00502     M2MObjectList                            _object_list;
00503     sn_nsdl_ep_parameters_s                 *_endpoint;
00504     nsdl_s                                  *_nsdl_handle;
00505     M2MSecurity                             *_security; // Not owned
00506     M2MServer                               *_server;
00507     M2MTimer                                _nsdl_exceution_timer;
00508     M2MTimer                                _registration_timer;
00509     M2MConnectionHandler                    &_connection_handler;
00510     sn_nsdl_addr_s                          _sn_nsdl_address;
00511     String                                  _endpoint_name;
00512     uint32_t                                _counter_for_nsdl;
00513     uint16_t                                _bootstrap_id;
00514     char                                    *_server_address; // BS or M2M address
00515     bool                                    _unregister_ongoing;
00516     bool                                    _identity_accepted;
00517     bool                                    _nsdl_exceution_timer_running;
00518     uint8_t                                 _binding_mode;
00519     uint16_t                                _auto_obs_token;
00520     get_data_request_list_t                 _get_request_list;
00521     
00522 
00523 friend class Test_M2MNsdlInterface;
00524 
00525 };
00526 
00527 #endif // M2MNSDLINTERFACE_H
00528