TI's mqtt.

Dependencies:   client server

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sl_mqtt_client.h Source File

sl_mqtt_client.h

00001 /*******************************************************************************
00002 Copyright (c) (2014) Texas Instruments Incorporated
00003 All rights reserved not granted herein.
00004 
00005 Limited License.  
00006 
00007 Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive 
00008 license under copyrights and patents it now or hereafter owns or controls to make, 
00009 have made, use, import, offer to sell and sell ("Utilize") this software subject 
00010 to the terms herein.  With respect to the foregoing patent license, such license 
00011 is granted  solely to the extent that any such patent is necessary to Utilize the 
00012 software alone.  The patent license shall not apply to any combinations which 
00013 include this software, other than combinations with devices manufactured by or 
00014 for TI (�TI Devices�).  No hardware patent is licensed hereunder.
00015 
00016 Redistributions must preserve existing copyright notices and reproduce this license 
00017 (including the above copyright notice and the disclaimer and (if applicable) source 
00018 code license limitations below) in the documentation and/or other materials provided 
00019 with the distribution
00020 
00021 Redistribution and use in binary form, without modification, are permitted provided 
00022 that the following conditions are met:
00023 * No reverse engineering, decompilation, or disassembly of this software is 
00024   permitted with respect to any software provided in binary form.
00025 * any redistribution and use are licensed by TI for use only with TI Devices.
00026 * Nothing shall obligate TI to provide you with source code for the software 
00027   licensed and provided to you in object code.
00028 
00029 If software source code is provided to you, modification and redistribution of the 
00030 source code are permitted provided that the following conditions are met;
00031 * any redistribution and use of the source code, including any resulting derivative 
00032   works, are licensed by TI for use only with TI Devices.
00033 * any redistribution and use of any object code compiled from the source code and 
00034   any resulting derivative works, are licensed by TI for use only with TI Devices.
00035 
00036 Neither the name of Texas Instruments Incorporated nor the names of its suppliers 
00037 may be used to endorse or promote products derived from this software without 
00038 specific prior written permission.
00039 
00040 DISCLAIMER.
00041 
00042 THIS SOFTWARE IS PROVIDED BY TI AND TI�S LICENSORS "AS IS" AND ANY EXPRESS OR IMPLIED 
00043 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
00044 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TI AND TI�S 
00045 LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00046 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
00047 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00048 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
00049 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
00050 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00051 
00052 ******************************************************************************/
00053 
00054 #include <stdio.h>
00055 #include <string.h>
00056 #include <stdbool.h>
00057 #include "cc3100_simplelink.h"
00058 
00059 #ifndef __SL_MQTT_H__
00060 #define __SL_MQTT_H__
00061 
00062 #ifdef __cplusplus
00063 extern "C"
00064 {
00065 #endif
00066 
00067 namespace mbed_mqtt {
00068 
00069         /**
00070           \mainpage SimpleLink MQTT Client Layer
00071           
00072           * \section intro_sec Introduction
00073 
00074           The SimpleLink MQTT Client Layer provides an easy-to-use API(s) to enable
00075           constrained and deeply embedded microcontroller based products to interact
00076           with cloud or network based server for telemetery. The users of SL MQTT
00077           Client services, while benefiting from the abstraction of the MQTT protocol
00078           would find them suitable for varied deployments of MQTT subscribers and / or
00079           publishers.
00080 
00081           The following figure outlines the composition of the SL MQTT Client Layer.
00082 
00083           * \image html ./sl_mqtt_client_view.png
00084           
00085           * \section descrypt_sec Description
00086 
00087           The SL MQTT Client Layer, in addition to providing services to the application,
00088           encompasses a RTOS task to handle the incoming messages from the server. Such
00089           a dedicated context to process the messages from the server facilitates the
00090           apps to receive data (i.e. PUBLISH messages) even when they are blocked, whilst
00091           awaiting ACK for a previous transaction with the server. The receive task in
00092           the SL MQTT Layer can not be disabled anytime, however its system wide priority
00093           is configurable and can be set.
00094 
00095           Some of the salient features of the SL MQTT Layer are 
00096           
00097           - Easy-to-use, intuitive and small set of MQTT API
00098           - App can indicate its choice to await ACK for a message transaction
00099           - Supports MQTT 3.1 protocol
00100 
00101           * \section config_sec Configuration
00102           The SL implementation enables the application developers to configure the
00103           following parameters using the compile line flags (-D option)
00104           * - <b> CFG_SL_CL_MAX_MQP: </b> the count of TX + RX resources in the buffer pool
00105       for the library to use. \n\n
00106           * - <b> CFG_SL_CL_BUF_LEN: </b> the length of the TX and RX buffers in the pool. \n\n
00107           * - <b> CFG_SL_CL_STACK: </b> Max stack (bytes) for RX Task executed by SL-MQTT. \n\n
00108           * - <b> CFG_CL_MQTT_CTXS: </b> the max number of simultaneous network connections
00109           to one or more servers. \n\n
00110 
00111           * \section seq_sec Sequence Diagram
00112           The following sequence diagram outlines one of the possible usecases
00113       (Blocking APIs with QOS1) using the SL MQTT Client Layer
00114           * \image html ./sl_mqtt_client_seq.jpg
00115 
00116           * \note An app that has chosen not to await an ACK from the server for an
00117           scheduled transaction can benefit from the availability of control to
00118           pursue other activities to make overall progress in the system. However,
00119           an attempt to schedule another transaction with the server, while the
00120           previous one is still active, will depend on the availability of buffers for transaction.
00121           
00122 
00123           \subsection seq_subsec Typical Sequences:
00124           
00125           - Publishers:  INIT --> CONTEXT_CREATE --> CONNECT --> PUBLISH (TX) --> DISCONNECT --> CONTEXT_DELETE --> EXIT
00126           - Subscribers: INIT --> CONTEXT_CREATE --> CONNECT --> SUBSCRIBE --> PUBLISH (RX) --> UNSUBSCRIBE --> DISCONNECT --> CONTEXT_DELETE --> EXIT
00127           
00128         */
00129 
00130         /** @defgroup sl_mqtt_cl_api SL MQTT Client API
00131             @{
00132         */
00133   
00134         /** @defgroup sl_mqtt_cl_evt SL MQTT Client Events
00135             @{ 
00136         */
00137 #define SL_MQTT_CL_EVT_PUBACK   0x04  /**< PUBACK has been received from the server */
00138 #define SL_MQTT_CL_EVT_PUBCOMP  0x07  /**< PUBCOMP has been received from the server */
00139 #define SL_MQTT_CL_EVT_SUBACK   0x09  /**< SUBACK has been received from the server */
00140 #define SL_MQTT_CL_EVT_UNSUBACK 0x0B  /**< UNSUBACK has been received from the server */
00141         /** @} */ /* End Client events */
00142 
00143 
00144       /* Define server structure which holds , server address and port number.
00145       These values are set by the sl_MqttSet API and retrieved by sl_MqttGet API*/
00146 
00147         /** Callbacks Routines
00148             The routines are invoked by SL Implementation onto Client application
00149 
00150             * \note The user applications implement the callbacks that are registered 
00151                     with the libraries. While using the MQTT library, invoking the 
00152                     core library APIs from a callback should be avoided and 
00153                     can lead to lockup scenarios. It is recommended to signal another 
00154                     task from the callback routines invoked from the library 
00155                     and invoke the core library API calls from that task.
00156          */
00157         typedef struct {
00158                 
00159                 /** Callback routine to receive a PUBLISH from the server.
00160                     The client app must provide this routine for the instances where it has
00161                     subscribed to certain set of topics from the server. The callback is
00162                     invoked in the context of the internal SL Receive Task.
00163                     
00164                     \param[in] app_hndl application handle returned
00165                     \param[in] topstr name of topic published by the server. Not NUL terminated.
00166                     \param[in] toplen length of the topic name published by the server.
00167                     \param[in] payload refers to payload published by the server.
00168                     \param[in] pay_len length of the payload.
00169                     \param[in] dup assert to indicate that it is re-send by the server
00170                     \param[in] qoS quality of service of the published message
00171                     \param[in] retain asserted to indicate that a retained message has been published
00172                     \return none.
00173                 */
00174                 void (*sl_ExtLib_MqttRecv)(void *app_hndl, const char *topstr, int32_t toplen,
00175                                             const void *payload, int32_t pay_len,
00176                                             bool dup, unsigned char qos,
00177                                             bool retain);
00178                 
00179                 /** Indication of event either from the server or implementation generated.
00180                     These events are notified as part of the processing carried out by the
00181                     internal recv task of the SL implementation. The application must populate
00182                     the callback to receive events about the progress made by the SL Mqtt layer.
00183                     
00184                     This handler is used by the SL Mqtt Layer to report acknowledgements from the
00185                     server, in case, the application has chosen not to block the service invokes
00186                     till the arrival of the corresponding ACK.
00187                     
00188                     \param[in] app_hndl application handle returned
00189                     \param[in] evt identifier to the reported event. Refer to @ref sl_mqtt_cl_evt
00190                     \param[in] buf points to buffer
00191                     \param[in] len length of buffer
00192                     
00193                     \note
00194                 */
00195                 void (*sl_ExtLib_MqttEvent)(void *app_hndl, int32_t evt, const void *buf, 
00196                                              uint32_t len);
00197 
00198                 /** Notifies the client app about the termination of MQTT connection.
00199                     After servicing this callback, the client-app can destroy associated
00200                     context if it no longer required
00201 
00202                     \param[in] app_hndl application handle returned
00203                 */
00204                 void (*sl_ExtLib_MqttDisconn)(void *app_hndl);
00205 
00206                 
00207         } SlMqttClientCbs_t;
00208         
00209         typedef struct {
00210 
00211                 const char        *will_topic;   /**< Will Topic    */
00212                 const char        *will_msg;     /**< Will message  */
00213                 char      will_qos;     /**< Will Qos      */
00214                 bool               retain;       /**< Retain Flag   */
00215                          
00216         } SlMqttWill_t;
00217         
00218          
00219         /** Secure Socket Parameters to open a secure connection */
00220         /*
00221         Note: value of n_files can vary from 1 to 4, with corresponding pointers to
00222         the files in files field. Value of 1(n_files) will assume the corresponding
00223         pointer is for CA File Name. Any other value of n_files expects the files to
00224         be in following order:
00225         1.  Private Key File
00226         2.  Certificate File Name
00227         3.  CA File Name
00228         4.  DH Key File Name
00229 
00230         example: 
00231         If you want to provide only CA File Name, following are the two way of doing it:
00232         for n_files = 1
00233         char *security_file_list[] = {"/cert/testcacert.der"};
00234         for n_files = 4
00235         char *security_file_list[] = {NULL, NULL, "/cert/testcacert.der", NULL};
00236 
00237         where secure_files = security_file_list
00238         */
00239         typedef struct {
00240 
00241 #define SL_MQTT_NETCONN_IP6  0x04  /**< Assert for IPv6 connection, otherwise  IPv4 */
00242 #define SL_MQTT_NETCONN_URL  0x08  /**< Server address is an URL and not IP address */
00243 #define SL_MQTT_NETCONN_SEC  0x10  /**< Connection to server  must  be secure (TLS) */
00244 
00245                 uint32_t         netconn_flags; /**< Enumerate connection type  */
00246                 const char          *server_addr;   /**< Server Address: URL or IP  */
00247                 uint16_t       port_number;   /**< Port number of MQTT server */
00248                 char        method;        /**< Method to tcp secured socket */
00249                 uint32_t         cipher;        /**< Cipher to tcp secured socket */
00250                 uint32_t         n_files;       /**< Number of files for secure transfer */
00251                 char * const        *secure_files;  /* SL needs 4 files*/
00252 
00253         } SlMqttServer_t;
00254 
00255     
00256         /** MQTT Lib structure which holds Initialization Data */
00257         typedef struct
00258         {
00259                 /**< Loopback port is used to manage lib internal functioning in case of connections to 
00260                      multiple servers simultaneously is desired. */
00261                 uint16_t  loopback_port;  /**< Loopback port = 0, implies connection to only single server */
00262                                                 /**< Loopback port != 0, implies connection to multiple servers */
00263                 uint32_t   rx_tsk_priority;  /**< Priority of the receive task */
00264                 uint32_t    resp_time;        /**< Reasonable response time (seconds) from server */
00265                 bool  aux_debug_en;               /**< Assert to indicate additional debug info */
00266                 int32_t (*dbg_print)(const char *pcFormat, ...); /**< Print debug information */
00267 
00268         } SlMqttClientLibCfg_t;
00269 
00270 
00271         /** MQTT client context configuration structure */
00272         typedef struct
00273         {
00274                 SlMqttServer_t  server_info;      /**< Server information */
00275                 bool            mqtt_mode31;      /**< Operate LIB in MQTT 3.1 mode; default is 3.1.1. false - default( 3.1.1) & true - 3.1) */
00276                 bool            blocking_send;    /**< Select the mode of operation for send APIs (PUB, SUB, UNSUB). false - callback, true - blocking */
00277 
00278         } SlMqttClientCtxCfg_t;
00279 
00280         /** Initialize the SL MQTT Implementation.
00281             A caller must initialize the MQTT implementation prior to using its services.
00282             
00283             \param[in] cfg refers to client lib configuration parameters
00284             \return Success (0) or Failure (-1)
00285         */
00286         int32_t sl_ExtLib_MqttClientInit(const SlMqttClientLibCfg_t  *cfg);
00287 
00288         /** Exit the SL MQTT Implementation.
00289             
00290             \return Success (0) or Failure (-1)
00291         */
00292         int32_t sl_ExtLib_MqttClientExit();
00293 
00294         /** Create a new client context to connect to a server.
00295             A context has to be created prior to invoking the client services.
00296 
00297             \param[in] ctx_cfg refers to client context configuration parameters
00298             \param[in] msg_cbs refers to callbacks into application
00299             \param[in] app refers to the application callback to be returned on callback
00300         */
00301         void *sl_ExtLib_MqttClientCtxCreate(const SlMqttClientCtxCfg_t *ctx_cfg,
00302                                               const SlMqttClientCbs_t *msg_cbs,
00303                                               void *app_hndl);
00304 
00305         /** Deletes the specified client context.
00306 
00307             \param[in] cli_ctx refers to client context to be deleted
00308             \return Success (0) or Failure (< 0)
00309         */
00310         int32_t sl_ExtLib_MqttClientCtxDelete(void *cli_ctx);
00311 
00312         /** @defgroup sl_mqtt_cl_params SL MQTT Oper Paramters
00313             @{
00314         */
00315 #define SL_MQTT_PARAM_CLIENT_ID  0x01   /**< Refers to Client ID */
00316 #define SL_MQTT_PARAM_USER_NAME  0x02   /**< User name of client */
00317 #define SL_MQTT_PARAM_PASS_WORD  0x03   /**< Pass-word of client */
00318 #define SL_MQTT_PARAM_TOPIC_QOS1 0x04   /**< Set a QoS1 SUB topic */
00319 #define SL_MQTT_PARAM_WILL_PARAM 0x05   /**< Set a WILL topic,Will Message, Will QOS,Will Retain */
00320           
00321           /** @} */
00322         
00323         /** Set parameters in SL MQTT implementation.
00324             The caller must configure these paramters prior to invoking any MQTT
00325             transaction.
00326             
00327             \note The implementation does not copy the contents referred. Therefore,
00328             the caller must ensure that contents are persistent in the memory.
00329             
00330             \param[in] cli_ctx refers to the handle to the client context
00331             \param[in] param identifies parameter to set. Refer to @ref sl_mqtt_cl_params
00332             \param[in] value refers to the place-holder of value to be set
00333             \param[in] len length of the value of the parameter
00334             \return Success (0) or Failure (-1)          
00335         */
00336         int32_t sl_ExtLib_MqttClientSet(void *cli_ctx, int32_t param, const void *value, uint32_t len);
00337         
00338         /*\brief None defined at the moment
00339         */
00340         int32_t sl_ExtLib_MqttClientGet(void *cli_ctx, int32_t param, void *value, uint32_t len);
00341   
00342   
00343         /** CONNECT to the server. 
00344             This routine establishes a connection with the server for MQTT transactions.
00345             The caller should specify a time-period with-in which the implementation
00346             should send a message to the server to keep-alive the connection.
00347             
00348             \param[in] cli_ctx refers to the handle to the client context
00349             \param[in] clean assert to make a clean start and purge the previous session
00350             \param[in] keep_alive_time the maximum time within which client should send
00351             a message to server. The unit of the interval is in seconds.
00352             \return on success, variable header of CONNACK message in network byte
00353             order. Lowest Byte[Byte0] contains CONNACK Return Code. Byte1 Contains 
00354             Session Present Bit.  
00355             on failure  returns(-1)
00356         */
00357         int32_t sl_ExtLib_MqttClientConnect(void *cli_ctx, bool clean, uint16_t keep_alive_time);
00358         
00359         /** DISCONNECT from the server.
00360             The caller must use this service to close the connection with the 
00361             server.
00362 
00363             \param[in] cli_ctx refers to the handle to the client context
00364          
00365             \return Success (0) or Failure (< 0)
00366         */
00367         int32_t sl_ExtLib_MqttClientDisconnect(void *cli_ctx);
00368         
00369 
00370         /** SUBSCRIBE a set of topics.
00371             To receive data about a set of topics from the server, the app through
00372             this routine must subscribe to those topic names with the server. The
00373             caller can indicate whether the routine should block until a time, the
00374             message has been acknowledged by the server.
00375 
00376             In case, the app has chosen not to await for the ACK from the server, 
00377             the SL MQTT implementation will notify the app about the subscription
00378             through the callback routine.
00379             
00380             \param[in] cli_ctx refers to the handle to the client context
00381             \param[in] topics set of topic names to subscribe. It is an array of
00382             pointers to NUL terminated strings.
00383             \param[in,out] qos array of qos values for each topic in the same order
00384             of the topic array. If configured to await for SUB-ACK from server, the
00385             array will contain qos responses for topics from the server.
00386             \param[in] count number of such topics
00387   
00388             \return Success(transaction Message ID) or Failure(< 0)
00389         */
00390         int32_t sl_ExtLib_MqttClientSub(void *cli_ctx, char* const *topics,
00391                                     uint8_t *qos, int32_t count);
00392 
00393         
00394         /** UNSUBSCRIBE a set of topics.
00395             The app should use this service to stop receiving data for the named
00396             topics from the server. The caller can indicate whether the routine
00397             should block until a time, the message has been acknowleged by the
00398             server.
00399 
00400             In case, the app has chosen not to await for the ACK from the server, 
00401             the SL MQTT implementation will notify the app about the subscription
00402             through the callback routine.
00403             
00404             \param[in] cli_ctx refers to the handle to the client context
00405             \param[in] topics set of topics to be unsubscribed. It is an array of
00406             pointers to NUL terminated strings.
00407             \param[in] count number of topics to be unsubscribed
00408 
00409             \return Success(transaction Message ID) or Failure(< 0) 
00410         */
00411         int32_t sl_ExtLib_MqttClientUnsub(void *cli_ctx, char* const *topics, int32_t count);
00412         
00413         
00414         /** PUBLISH a named message to the server.
00415             In addition to the PUBLISH specific parameters, the caller can indicate
00416             whether the routine should block until the time, the message has been
00417             acknowleged by the server. This is applicable only for non-QoS0 messages.
00418             
00419             In case, the app has chosen not to await for the ACK from the server, 
00420             the SL MQTT implementation will notify the app about the subscription
00421             through the callback routine.
00422 
00423             \param[in] cli_ctx refers to the handle to the client context
00424             \param[in] topic  topic of the data to be published. It is NULL terminated.
00425             \param[in] data   binary data to be published
00426             \param[in] len    length of the data
00427             \param[in] qos    QoS for the publish message 
00428             \param[in] retain assert if server should retain the message
00429             \param[in] flags Command flag. Refer to @ref sl_mqtt_cl_cmdflags
00430             \return Success(transaction Message ID) or Failure(< 0)
00431         */
00432         int32_t sl_ExtLib_MqttClientSend(void *cli_ctx, const char *topic,
00433                                       const void *data, int32_t len, 
00434                                       char qos, bool retain);
00435         
00436         /** PUBLISH a named message to the server - wrapper function.
00437         */
00438         static inline int32_t sl_ExtLib_MqttClientPub(void *cli_ctx, const char *topic,
00439                                       const void *data, int32_t len,
00440                                       char qos, bool retain)
00441         {
00442                 return sl_ExtLib_MqttClientSend(cli_ctx, topic, data, len,
00443                                           qos, retain);
00444         }
00445 
00446         /** @} */ /* End Client API */
00447         
00448 }//namespace mbed_mqtt        
00449 
00450 #ifdef __cplusplus  
00451 }
00452 #endif  
00453 
00454 
00455 
00456 #endif // __SL_MQTT_H__
00457