Simple interface for Mbed Cloud Client

Dependents:  

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