Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 #include "eventOS_event.h" 00030 00031 //FORWARD DECLARARTION 00032 class M2MSecurity; 00033 class M2MObject; 00034 class M2MObjectInstance; 00035 class M2MResource; 00036 class M2MResourceInstance; 00037 class M2MNsdlObserver; 00038 class M2MServer; 00039 class M2MConnectionHandler; 00040 class M2MNotificationHandler; 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 request_context_s { 00059 request_data_cb on_request_data_cb; 00060 request_error_cb on_request_error_cb; 00061 size_t received_size; 00062 uint32_t msg_token; 00063 char *uri_path; 00064 void *context; 00065 bool async_req; 00066 sn_coap_msg_code_e msg_code; 00067 bool resend; 00068 ns_list_link_t link; 00069 }; 00070 00071 struct nsdl_coap_data_s { 00072 nsdl_s *nsdl_handle; 00073 sn_coap_hdr_s *received_coap_header; 00074 sn_nsdl_addr_s address; 00075 }; 00076 00077 typedef NS_LIST_HEAD(request_context_s, link) request_context_list_t; 00078 00079 /** 00080 * @brief Constructor 00081 * @param observer, Observer to pass the event callbacks from nsdl library. 00082 */ 00083 M2MNsdlInterface(M2MNsdlObserver &observer, M2MConnectionHandler &connection_handler); 00084 00085 /** 00086 * @brief Destructor 00087 */ 00088 virtual ~M2MNsdlInterface(); 00089 00090 /** 00091 * @brief Creates endpoint object for the nsdl stack. 00092 * @param endpoint_name, Endpoint name of the client. 00093 * @param endpoint_type, Endpoint type of the client. 00094 * @param life_time, Life time of the client in seconds 00095 * @param domain, Domain of the client. 00096 * @param mode, Binding mode of the client, default is UDP 00097 * @param context_address, Context address default is empty. 00098 */ 00099 void create_endpoint(const String &endpoint_name, 00100 const String &endpoint_type, 00101 const int32_t life_time, 00102 const String &domain, 00103 const uint8_t mode, 00104 const String &context_address); 00105 00106 /** 00107 * @brief Deletes the endpoint. 00108 */ 00109 void delete_endpoint(); 00110 00111 /** 00112 * @brief Updates endpoint name. 00113 */ 00114 void update_endpoint(const String &name); 00115 00116 /** 00117 * @brief Updates domain. 00118 */ 00119 void update_domain(const String &domain); 00120 00121 /** 00122 * @brief Creates the NSDL structure for the registered objectlist. 00123 * @param list, List of objects implementing the M2MBase interface to be registered. 00124 * @return true if structure created successfully else false. 00125 */ 00126 bool create_nsdl_list_structure(const M2MBaseList &list); 00127 00128 /** 00129 * @brief Removed the NSDL resource for the given resource. 00130 * @param base, Resource to be removed. 00131 * @return true if removed successfully else false. 00132 */ 00133 bool remove_nsdl_resource(M2MBase *base); 00134 00135 /** 00136 * @brief Creates the bootstrap object. 00137 * @param address Bootstrap address. 00138 * @return true if created and sent successfully else false. 00139 */ 00140 bool create_bootstrap_resource(sn_nsdl_addr_s *address); 00141 00142 /** 00143 * @brief Sets the register message to the server. 00144 * @param address M2MServer address. 00145 * @param address_length M2MServer address length. 00146 * @param port M2MServer port. 00147 * @param address_type IP Address type. 00148 */ 00149 void set_server_address(uint8_t* address, 00150 uint8_t address_length, 00151 const uint16_t port, 00152 sn_nsdl_addr_type_e address_type); 00153 /** 00154 * @brief Sends the register message to the server. 00155 * @return true if register sent successfully else false. 00156 */ 00157 bool send_register_message(); 00158 00159 /** 00160 * @brief Sends the CoAP request to the server. 00161 * @uri Uri path to the data. 00162 * @msg_code CoAP message code of request to send. 00163 * @offset Data offset. 00164 * @async In async mode application must call this API again with the updated offset. 00165 * If set to false then client will automatically download the whole package. 00166 * @payload_len Length of payload buffer. 00167 * @payload_ptr Pointer to payload buffer. 00168 * @request_data_cb Callback which is triggered once there is data available. 00169 * @request_error_cb Callback which is trigged in case of any error. 00170 * @context Application context. 00171 */ 00172 void send_request(const char *uri, 00173 const sn_coap_msg_code_e msg_code, 00174 const size_t offset, 00175 const bool async, 00176 const uint16_t payload_len, 00177 uint8_t *payload_ptr, 00178 request_data_cb data_cb, 00179 request_error_cb error_cb, 00180 void *context); 00181 00182 /** 00183 * @brief Sends the update registration message to the server. 00184 * @param lifetime, Updated lifetime value in seconds. 00185 * @return true if sent successfully else false. 00186 * 00187 */ 00188 bool send_update_registration(const uint32_t lifetime = 0); 00189 00190 /** 00191 * @brief Sends unregister message to the server. 00192 * @return true if unregister sent successfully else false. 00193 */ 00194 bool send_unregister_message(); 00195 00196 /** 00197 * @brief Memory Allocation required for libCoap. 00198 * @param size, Size of memory to be reserved. 00199 */ 00200 static void* memory_alloc(uint32_t size); 00201 00202 /** 00203 * @brief Memory free functions required for libCoap 00204 * @param ptr, Object whose memory needs to be freed. 00205 */ 00206 static void memory_free(void *ptr); 00207 00208 /** 00209 * @brief Callback from nsdl library to inform the data is ready 00210 * to be sent to server. 00211 * @param nsdl_handle, Handler for the nsdl structure for this endpoint 00212 * @param protocol, Protocol format of the data 00213 * @param data, Data to be sent. 00214 * @param data_len, Size of the data to be sent 00215 * @param address, server address where data has to be sent. 00216 * @return 1 if successful else 0. 00217 */ 00218 uint8_t send_to_server_callback(struct nsdl_s * nsdl_handle, 00219 sn_nsdl_capab_e protocol, 00220 uint8_t *data, 00221 uint16_t data_len, 00222 sn_nsdl_addr_s *address); 00223 00224 /** 00225 * @brief Callback from nsdl library to inform the data which is 00226 * received from server for the client has been converted to coap message. 00227 * @param nsdl_handle, Handler for the nsdl structure for this endpoint 00228 * @param coap_header, Coap message formed from data. 00229 * @param address, Server address from where the data is received. 00230 * @return 1 if successful else 0. 00231 */ 00232 uint8_t received_from_server_callback(struct nsdl_s * nsdl_handle, 00233 sn_coap_hdr_s *coap_header, 00234 sn_nsdl_addr_s *address); 00235 00236 /** 00237 * @brief Callback from nsdl library to inform the data which is 00238 * received from server for the resources has been converted to coap message. 00239 * @param nsdl_handle, Handler for the nsdl resource structure for this endpoint.. 00240 * @param coap_header, Coap message formed from data. 00241 * @param address, Server address from where the data is received. 00242 * @param nsdl_capab, Protocol for the message, currently only coap is supported. 00243 * @return 1 if successful else 0. 00244 */ 00245 uint8_t resource_callback(struct nsdl_s *nsdl_handle, sn_coap_hdr_s *coap, 00246 sn_nsdl_addr_s *address, 00247 sn_nsdl_capab_e nsdl_capab); 00248 00249 /** 00250 * @brief Callback from event loop for handling CoAP messages received from server for the resources 00251 * that has been converted to coap message. 00252 * @param coap_header, Coap message formed from data. 00253 * @param address, Server address from where the data is received. 00254 * @return 1 if successful else 0. 00255 */ 00256 uint8_t resource_callback_handle_event(sn_coap_hdr_s *coap, 00257 sn_nsdl_addr_s *address); 00258 00259 00260 /** 00261 * @brief Callback when there is data received from server and needs to be processed. 00262 * @param data, data received from server. 00263 * @param data_size, data size received from server. 00264 * @param addres, address structure of the server. 00265 * @return true if successfully processed else false. 00266 */ 00267 bool process_received_data(uint8_t *data, 00268 uint16_t data_size, 00269 sn_nsdl_addr_s *address); 00270 00271 /** 00272 * @brief Stops all the timers in case there is any errors. 00273 */ 00274 void stop_timers(); 00275 00276 /** 00277 * @brief Returns nsdl handle. 00278 * @return ndsl handle 00279 */ 00280 nsdl_s* get_nsdl_handle() const; 00281 00282 /** 00283 * @brief Get endpoint name 00284 * @return endpoint name 00285 */ 00286 const String& endpoint_name() const; 00287 00288 /** 00289 * @brief Get internal endpoint name 00290 * @return internal endpoint name 00291 */ 00292 const String internal_endpoint_name() const; 00293 00294 /** 00295 * @brief Set server address 00296 * @param server_address, Bootstrap or M2M server address. 00297 */ 00298 void set_server_address(const char *server_address); 00299 00300 /** 00301 * @brief Remove an object from the list kept by the NSDLInteface. 00302 * Does not call delete on the object. 00303 */ 00304 bool remove_object_from_list(M2MBase *base); 00305 00306 /* 00307 * @brief Get NSDL timer. 00308 * @return NSDL execution timer. 00309 */ 00310 M2MTimer &get_nsdl_execution_timer(); 00311 00312 /** 00313 * @brief Get unregister state. 00314 * @return Is unregistration ongoing. 00315 */ 00316 bool is_unregister_ongoing() const; 00317 00318 /** 00319 * @brief Get update register state. 00320 * @return Is updare registration ongoing. 00321 */ 00322 bool is_update_register_ongoing() const; 00323 00324 /** 00325 * @brief Starts the NSDL execution timer. 00326 */ 00327 void start_nsdl_execution_timer(); 00328 00329 /** 00330 * @brief Returns security object. 00331 * @return M2MSecurity object, contains lwm2m server information. 00332 */ 00333 M2MSecurity* get_security_object(); 00334 00335 /** 00336 * @brief Returns auto-observation token. 00337 * @param path, Resource path, used for searching the right object. 00338 * @param token[OUT], Token data. 00339 * @return Length of the token if found otherwise 0. 00340 */ 00341 uint8_t find_auto_obs_token(const char *path, uint8_t *token) const; 00342 00343 /** 00344 * @brief Set custom uri query paramaters used in LWM2M registration. 00345 * @uri_query_params Uri query params. Parameters must be in key-value pair format: 00346 * "a=100&b=200". Maximum length can be up to 64 bytes. 00347 * @return False if maximum length exceeded otherwise True. 00348 */ 00349 bool set_uri_query_parameters(const char *uri_query_params); 00350 00351 /** 00352 * @brief Clears the sent blockwise message list in CoAP library. 00353 */ 00354 void clear_sent_blockwise_messages(); 00355 00356 /** 00357 * @brief Send next notification message. 00358 */ 00359 void send_next_notification(bool clear_token); 00360 00361 /** 00362 * @brief Store the "BS finished" response id. 00363 * @param msg_id Response id. 00364 */ 00365 void store_bs_finished_response_id(uint16_t msg_id); 00366 00367 /** 00368 * @brief Store the registration state. 00369 * @param registered Registered to lwm2m server or not. 00370 */ 00371 void set_registration_status(bool registered); 00372 00373 /** 00374 * @brief Handle incoming bootstrap PUT message. 00375 * @param coap_header, Received CoAP message 00376 * @param address, Server address 00377 */ 00378 void handle_bootstrap_put_message(sn_coap_hdr_s *coap_header, sn_nsdl_addr_s *address); 00379 00380 /** 00381 * @brief Handle bootstrap finish acknowledgement. 00382 */ 00383 void handle_bootstrap_finish_ack(uint16_t msg_id); 00384 00385 /** 00386 * @brief Returns total retransmission time 00387 * @resend_count Resend count 00388 * @return Total retransmission time 00389 */ 00390 uint32_t total_retransmission_time(int resend_count); 00391 00392 /** 00393 * @brief Returns CoAP retransmission count 00394 * @return CoAP retransmission count 00395 */ 00396 uint8_t get_resend_count(); 00397 00398 /** 00399 * @brief Mark request to be resend again after network break 00400 */ 00401 void set_request_context_to_be_resend(); 00402 00403 protected: // from M2MTimerObserver 00404 00405 virtual void timer_expired(M2MTimerObserver::Type type); 00406 00407 protected: // from M2MObservationHandler 00408 00409 virtual bool observation_to_be_sent(M2MBase *object, 00410 uint16_t obs_number, 00411 const m2m::Vector<uint16_t> &changed_instance_ids, 00412 bool send_object = false); 00413 00414 virtual void resource_to_be_deleted(M2MBase* base); 00415 00416 virtual void value_updated(M2MBase *base); 00417 00418 virtual void remove_object(M2MBase *object); 00419 #ifndef DISABLE_DELAYED_RESPONSE 00420 virtual void send_delayed_response(M2MBase *base); 00421 #endif 00422 00423 private: 00424 00425 /** 00426 * Enum defining an LWM2M object type. 00427 */ 00428 typedef enum { 00429 SECURITY = 0x00, 00430 SERVER = 0x01, 00431 DEVICE = 0x02 00432 }ObjectType; 00433 00434 /** 00435 * @brief Initializes all the nsdl library component to be usable. 00436 * @return true if initialization is successful else false. 00437 */ 00438 bool initialize(); 00439 00440 bool add_object_to_list(M2MBase *base); 00441 00442 bool create_nsdl_structure(M2MBase *base); 00443 00444 #ifdef MBED_CLOUD_CLIENT_EDGE_EXTENSION 00445 bool create_nsdl_endpoint_structure(M2MEndpoint *endpoint); 00446 #endif 00447 00448 bool create_nsdl_object_structure(M2MObject *object); 00449 00450 bool create_nsdl_object_instance_structure(M2MObjectInstance *object_instance); 00451 00452 bool create_nsdl_resource_structure(M2MResource *resource, 00453 bool multiple_instances = false); 00454 00455 bool create_nsdl_resource(M2MBase *base); 00456 00457 static String coap_to_string(const uint8_t *coap_data_ptr, 00458 int coap_data_ptr_length); 00459 00460 void execute_nsdl_process_loop(); 00461 00462 uint64_t registration_time() const; 00463 00464 M2MBase* find_resource(const String &object, 00465 const uint16_t msg_id) const; 00466 00467 #ifdef MBED_CLOUD_CLIENT_EDGE_EXTENSION 00468 M2MBase* find_resource(const M2MEndpoint *endpoint, 00469 const String &object_name, 00470 const uint16_t msg_id) const; 00471 #endif 00472 00473 M2MBase* find_resource(const M2MObject *object, 00474 const String &object_instance, 00475 const uint16_t msg_id) const; 00476 00477 M2MBase* find_resource(const M2MObjectInstance *object_instance, 00478 const String &resource_instance, 00479 const uint16_t msg_id) const; 00480 00481 M2MBase* find_resource(const M2MResource *resource, 00482 const String &object_name, 00483 const String &resource_instance) const; 00484 00485 bool object_present(M2MBase *base) const; 00486 00487 int object_index(M2MBase *base) const; 00488 00489 static M2MInterface::Error interface_error(const sn_coap_hdr_s &coap_header); 00490 00491 void send_object_observation(M2MObject *object, 00492 uint16_t obs_number, 00493 const m2m::Vector<uint16_t> &changed_instance_ids, 00494 bool send_object); 00495 00496 void send_object_instance_observation(M2MObjectInstance *object_instance, 00497 uint16_t obs_number); 00498 00499 void send_resource_observation(M2MResource *resource, uint16_t obs_number); 00500 00501 00502 00503 /** 00504 * @brief Allocate (size + 1) amount of memory, copy size bytes into 00505 * it and add zero termination. 00506 * @param source Source string to copy, may not be NULL. 00507 * @param size The size of memory to be reserved. 00508 */ 00509 static uint8_t* alloc_string_copy(const uint8_t* source, uint16_t size); 00510 00511 /** 00512 * @brief Utility method to convert given lifetime int to ascii 00513 * and allocate a buffer for it and set it to _endpoint->lifetime_ptr. 00514 * @param lifetime A new value for lifetime. 00515 */ 00516 void set_endpoint_lifetime_buffer(int lifetime); 00517 00518 /** 00519 * @brief Handle bootstrap finished message. 00520 * @param coap_header, Received CoAP message 00521 * @param address, Server address 00522 */ 00523 void handle_bootstrap_finished(sn_coap_hdr_s *coap_header,sn_nsdl_addr_s *address); 00524 00525 /** 00526 * @brief Handle bootstrap delete message. 00527 * @param coap_header, Received CoAP message 00528 * @param address, Server address 00529 */ 00530 void handle_bootstrap_delete(sn_coap_hdr_s *coap_header,sn_nsdl_addr_s *address); 00531 00532 /** 00533 * @brief Parse bootstrap TLV message. 00534 * @param coap_header, Received CoAP message 00535 * @return True if parsing was succesful else false 00536 */ 00537 bool parse_bootstrap_message(sn_coap_hdr_s *coap_header, M2MNsdlInterface::ObjectType lwm2m_object_type); 00538 00539 /** 00540 * @brief Parse bootstrap TLV message. 00541 * @param coap_header, Received CoAP message 00542 * @return True if parsing was succesful else false 00543 */ 00544 bool validate_security_object(); 00545 00546 /** 00547 * @brief Handle bootstrap errors. 00548 * @param reason, Reason for Bootstrap failure. 00549 * @param wait, True if need to wait that ACK has been sent. 00550 * False if reconnection can start immediately. 00551 */ 00552 void handle_bootstrap_error(const char *reason, bool wait); 00553 00554 /** 00555 * @brief Handle different coap errors. 00556 * @param coap_header, CoAP structure. 00557 * @return Error reason. 00558 */ 00559 static const char *coap_error(const sn_coap_hdr_s &coap_header); 00560 00561 /** 00562 * @brief Claim 00563 */ 00564 void claim_mutex(); 00565 00566 /** 00567 * @brief Release 00568 */ 00569 void release_mutex(); 00570 00571 /** 00572 * @brief Change operation mode of every resource. 00573 * @param object, Object to be updated. 00574 * @return operation, New operation mode. 00575 */ 00576 void change_operation_mode(M2MObject *object, M2MBase::Operation operation); 00577 00578 /** 00579 * @brief Parse URI query parameters and pass those to nsdl-c. 00580 * @return True if parsing success otherwise False 00581 */ 00582 bool parse_and_send_uri_query_parameters(); 00583 00584 /** 00585 * @brief Callback function that triggers the registration update call. 00586 * @param argument, Arguments part of the POST request. 00587 */ 00588 void update_trigger_callback(void *argument); 00589 00590 bool lifetime_value_changed() const; 00591 00592 void execute_notification_delivery_status_cb(M2MBase* object, int32_t msgid); 00593 00594 bool is_response_to_request(const sn_coap_hdr_s *coap_header, 00595 struct request_context_s &get_data); 00596 00597 void free_request_context_list(const sn_coap_hdr_s *coap_header = NULL); 00598 00599 /** 00600 * @brief Send next notification for object, return true if notification sent, false 00601 * if no notification to send or send already in progress. 00602 * @param object, M2MObject whose next notification should be sent 00603 * @param clear_token, Flag to indicate whether observation token should be cleared. 00604 * @return True if notification sent, false otherwise or if send already in progress 00605 */ 00606 bool send_next_notification_for_object(M2MObject& object, bool clear_token); 00607 00608 static char* parse_uri_query_parameters(char* uri); 00609 00610 void calculate_new_coap_ping_send_time(); 00611 00612 void send_coap_ping(); 00613 00614 void send_empty_ack(const sn_coap_hdr_s *header, sn_nsdl_addr_s *address); 00615 00616 struct M2MNsdlInterface::nsdl_coap_data_s* create_coap_event_data(sn_coap_hdr_s *received_coap_header, 00617 sn_nsdl_addr_s *address, 00618 struct nsdl_s *nsdl_handle, 00619 uint8_t coap_msg_code = COAP_MSG_CODE_EMPTY); 00620 00621 void handle_register_response(const sn_coap_hdr_s *coap_header); 00622 00623 void handle_unregister_response(const sn_coap_hdr_s *coap_header); 00624 00625 void handle_register_update_response(const sn_coap_hdr_s *coap_header); 00626 00627 void handle_request_response(const sn_coap_hdr_s *coap_header, struct request_context_s *request_context); 00628 00629 void handle_bootstrap_response(const sn_coap_hdr_s *coap_header); 00630 00631 void handle_notification_delivered(M2MBase *base); 00632 00633 void handle_empty_ack(const sn_coap_hdr_s *coap_header, bool is_bootstrap_msg); 00634 00635 bool handle_post_response(sn_coap_hdr_s *coap_header, 00636 sn_nsdl_addr_s *address, 00637 sn_coap_hdr_s *&coap_response, 00638 M2MObjectInstance *&obj_instance, 00639 bool is_bootstrap_msg); 00640 00641 bool is_blockwise_needed(uint32_t length) const; 00642 00643 void set_retransmission_parameters(); 00644 00645 void send_pending_request(); 00646 00647 private: 00648 00649 M2MNsdlObserver &_observer; 00650 M2MBaseList _base_list; 00651 sn_nsdl_ep_parameters_s *_endpoint; 00652 nsdl_s *_nsdl_handle; 00653 M2MSecurity *_security; // Not owned 00654 M2MServer *_server; 00655 M2MTimer _nsdl_execution_timer; 00656 M2MTimer _registration_timer; 00657 M2MConnectionHandler &_connection_handler; 00658 String _endpoint_name; 00659 String _internal_endpoint_name; 00660 uint32_t _counter_for_nsdl; 00661 uint32_t _next_coap_ping_send_time; 00662 char *_server_address; // BS or M2M address 00663 request_context_list_t _request_context_list; 00664 char *_custom_uri_query_params; 00665 M2MNotificationHandler *_notification_handler; 00666 arm_event_storage_t _event; 00667 uint16_t _auto_obs_token; 00668 uint16_t _bootstrap_id; 00669 static int8_t _tasklet_id; 00670 uint8_t _binding_mode; 00671 bool _identity_accepted; 00672 bool _nsdl_execution_timer_running; 00673 bool _notification_send_ongoing; 00674 bool _registered; 00675 bool _bootstrap_finish_ack_received; 00676 00677 friend class Test_M2MNsdlInterface; 00678 00679 }; 00680 00681 #endif // M2MNSDLINTERFACE_H 00682
Generated on Tue Jul 12 2022 16:24:15 by
1.7.2