This package includes the SharkSSL lite library and header files.

Dependents:   WebSocket-Client-Example SharkMQ-LED-Demo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SharkMQ.h Source File

SharkMQ.h

00001 /*
00002  *     ____             _________                __                _     
00003  *    / __ \___  ____ _/ /_  __(_)___ ___  ___  / /   ____  ____ _(_)____
00004  *   / /_/ / _ \/ __ `/ / / / / / __ `__ \/ _ \/ /   / __ \/ __ `/ / ___/
00005  *  / _, _/  __/ /_/ / / / / / / / / / / /  __/ /___/ /_/ / /_/ / / /__  
00006  * /_/ |_|\___/\__,_/_/ /_/ /_/_/ /_/ /_/\___/_____/\____/\__, /_/\___/  
00007  *                                                       /____/          
00008  *
00009  ****************************************************************************
00010  *            HEADER
00011  *
00012  *   This file is part of SharkMQ:
00013  *            https://realtimelogic.com/products/simplemq/
00014  *
00015  *   $Id: SharkMQ.h 3635 2014-12-31 03:39:41Z wini $
00016  *
00017  *   COPYRIGHT:  Real Time Logic LLC, 2014
00018  *
00019  *   This software is copyrighted by and is the sole property of Real
00020  *   Time Logic LLC.  All rights, title, ownership, or other interests in
00021  *   the software remain the property of Real Time Logic LLC.  This
00022  *   software may only be used in accordance with the terms and
00023  *   conditions stipulated in the corresponding license agreement under
00024  *   which the software has been supplied.  Any unauthorized use,
00025  *   duplication, transmission, distribution, or disclosure of this
00026  *   software is expressly forbidden.
00027  *                                                                        
00028  *   This Copyright notice may not be removed or modified without prior
00029  *   written consent of Real Time Logic LLC.
00030  *                                                                         
00031  *   Real Time Logic LLC. reserves the right to modify this software
00032  *   without notice.
00033  *
00034  *               http://sharkssl.com
00035  ****************************************************************************
00036  *
00037  */
00038 
00039 #ifndef __SharkMQ_h
00040 #define __SharkMQ_h
00041 
00042 #include "selib.h"
00043 
00044 /** @addtogroup SMQLib
00045 @{
00046 */
00047 
00048 /** \defgroup SharkMQErrorCodes Error codes returned by function SharkMQ_getMessage
00049 \ingroup SharkMQ
00050 \anchor SharkMQErrorCodes Error codes returned by function #SharkMQ_getMessage
00051 @{
00052 */
00053 
00054 /** The buffer provided in SharkMQ_constructor is not sufficiently large.
00055  */
00056 #define SMQE_BUF_OVERFLOW    -10000
00057 
00058 /** The URL provided is invalid.
00059  */
00060 #define SMQE_INVALID_URL     -10002 
00061 
00062 /** TCP connection error
00063  */
00064 #define SMQE_PROTOCOL_ERROR  -10003 
00065 
00066 /** Server sent a disconnect message
00067  */
00068 #define SMQE_DISCONNECT      -10004
00069 
00070 
00071 /** No PONG response to PING: timeout
00072  */
00073 #define SMQE_PONGTIMEOUT     -10005
00074 
00075 
00076 /** The SharkMQ_getMessage call timed out.
00077  */
00078 #define SMQE_TIMEOUT         -10100
00079 
00080 
00081 /** @} */ /* end SharkMQErrorCodes */
00082 
00083 
00084 /** \defgroup SharkMQRespCodes Response codes returned by function SharkMQ_getMessage
00085 \ingroup SharkMQ
00086 \anchor SharkMQRespCodes Response codes returned by function #SharkMQ_getMessage
00087 @{
00088 */
00089 
00090 /** Asynchronous #SharkMQ_subscribe response message received via
00091     #SharkMQ_getMessage.
00092 
00093     \li SharkMQ::ptid is set to the subscribed Topic ID.
00094     \li SharkMQ::status is set to zero (0) if the request was accepted and
00095     a negative value if the request was denied.
00096     \li the 'msg' out parameter in #SharkMQ_getMessage is set to the optional
00097     server's authentication response message if the request was
00098     denied.
00099  */
00100 #define SMQ_SUBACK           -20000
00101 
00102 /** Asynchronous #SharkMQ_create response message received via
00103     #SharkMQ_getMessage.
00104 
00105     \li SharkMQ::ptid is set to the created Topic ID.
00106     \li SharkMQ::status is set to zero (0) if the request was accepted and
00107     a negative value if the request was denied.
00108     \li the 'msg' out parameter in #SharkMQ_getMessage is set to the optional
00109     server's authentication response message if the request was
00110     denied.
00111  */
00112 #define SMQ_CREATEACK        -20001
00113 
00114 /** Asynchronous #SharkMQ_createsub response message received via
00115     #SharkMQ_getMessage.
00116 
00117     \li SharkMQ::ptid is set to the created Sub Topic ID.
00118     \li SharkMQ::status is set to zero (0) if the request was accepted and
00119     a negative value if the request was denied.
00120  */
00121 #define SMQ_CREATESUBACK     -20002
00122 
00123 /** Change notification event (from observed tid). Observe events are
00124  * initiated via #SharkMQ_observe.
00125 
00126     \li SharkMQ::ptid is set to the observed Topic ID.
00127     \li SharkMQ::status is set to the number of clients subscribed to the topic.
00128  */
00129 #define SMQ_SUBCHANGE        -20003
00130 
00131 /** @} */ /* end SharkMQRespCodes */
00132 
00133 
00134 #define SMQSTR(str) str, (sizeof(str)-1)
00135 
00136 /** SharkMQ structure.
00137  */
00138 typedef struct
00139 {
00140    SOCKET sock;
00141    SharkSslCon* scon;
00142 
00143    U8* sharkBuf; /* SharkSSL read buffer is set when we have data from Shark */
00144    U16 sharkBufLen; /* Received payload len */
00145    U16 sharkBufIx; /* Current read index in sharkBuf */
00146 
00147    U8* recBuf; /*Buffer provided by the application and set in the constructor*/
00148    /* 'buf' is managed internally and is either the internal Shark
00149       recv-buf or (recBuf).
00150    */
00151    U8* buf; /**< The buffer provides an [out] param for a few methods. */
00152 
00153    /** Timeout in milliseconds to wait in functions waiting for server
00154        data
00155    */
00156    U32 timeout;
00157    S32 pingTmoCounter,pingTmo;
00158    U32 clientTid; /**< Client's unique topic ID */
00159    U32 tid;  /**< Topic: set when receiving MSG_PUBLISH from broker */
00160    U32 ptid; /**< Publisher's tid: Set when receiving MSG_PUBLISH from broker */
00161    U32 subtid; /**< Sub-tid: set when receiving MSG_PUBLISH from broker */
00162    int status; /**< Last known error code */
00163    U16 recBufLen;
00164    U16 sendBufIx;
00165    U16 frameLen; /**< The SimpleMQ frame size for the incomming data */
00166    /** Read frame data using SharkMQ_getMessage until: frameLen-bytesRead = 0 */
00167    U16 bytesRead;
00168 } SharkMQ;
00169 
00170 /** Create a SimpleMQ client instance.
00171     \param o Uninitialized data of size sizeof(SharkMQ).
00172     \param buf is used for internal management and must not be less
00173     than 127 bytes and not smaller than the largest control
00174     frame. Function SharkMQ_getMessage will return #SMQE_BUF_OVERFLOW if
00175     the buffer is not sufficiently large.
00176     \param bufLen buffer length.
00177  */
00178 void SharkMQ_constructor(SharkMQ* o, U8* buf, U16 bufLen);
00179 
00180 /** Bare metal configuration. This macro must be called immediately
00181     after calling the constructor on bare metal systems.
00182     \param o the #SharkMQ instance.
00183     \param ctx an #SeCtx instance.
00184  */
00185 #define SharkMQ_setCtx(o, ctx) SOCKET_constructor(&(o)->sock, ctx)
00186 
00187 /** Initiate the SharkMQ server connection. The connection phase is
00188     divided into two steps: (1) initiating and (2) connecting via
00189     SharkMQ_connect.
00190     \param o the SharkMQ instance.
00191     \param scon SharkSslCon instance created by calling #SharkSsl_createCon.
00192     \param url is a URL that starts with http:// and this URL
00193     must be to a server resource that initiates a SimpleMQ connection.
00194     \param rnd (out param) a random number created by the server. This
00195     number can be used for securing hash based password encryption.
00196     \return
00197 
00198    - The return value is #SharkSslConTrust for any return value
00199      greater than zero.
00200    - A negative return value is one of:  an error code from #se_connect, or
00201     a [SimpleMQ error code](\ref SharkMQErrorCodes).
00202 
00203     A return value greater than zero means that a connection is
00204     established, but the connection is not trusted unless the return
00205     value is #SharkSslConTrust_CertCn.
00206 
00207     On success, SharkMQ::buf is set to the IP address of the client as
00208     seen by the broker.
00209  */
00210 int SharkMQ_init(SharkMQ* o, SharkSslCon* scon, const char* url, U32* rnd);
00211 
00212 /** Connect/establish a persistent SimpleMQ connection. The connection
00213     phase is divided into two steps: (1) initiating via SharkMQ_init and (2)
00214     connecting.
00215     \param o the SharkMQ instance.
00216     \param uid a universally unique client identifier (uid) must be
00217     unique across all clients connecting to the same broker
00218     instance. The uid is preferably a stringified version of the
00219     client's Ethernet MAC address.
00220     \param uidLen the uid length.
00221     \param credentials provide credentials if required by the broker instance.
00222     \param credLen credentials length.
00223     \param info a string that provides information to optional server
00224     code interacting with the broker. This string is also passed into
00225     the optional broker's authentication callback function.
00226     \param infoLen length of info.
00227     \returns 0 on success, error code from TCP/IP stack,
00228     [SimpleMQ error code](\ref SharkMQErrorCodes), or one of the
00229     following error codes from the broker:
00230 
00231     \li 0x01    Connection Refused: unacceptable protocol version
00232     \li 0x02    Connection Refused: server unavailable
00233     \li 0x03    Connection Refused: Incorrect credentials
00234     \li 0x04    Connection Refused: Client certificate required
00235     \li 0x05    Connection Refused: Client certificate not accepted
00236     \li 0x06    Connection Refused: Access denied
00237 
00238     The broker may optionally send a human readable string in addition
00239     to the above broker produced error codes. This string is avaiable
00240     via SharkMQ::buf.
00241  */
00242 int SharkMQ_connect(SharkMQ* o, const char* uid, int uidLen,
00243                     const char* credentials, U8 credLen,
00244                     const char* info, int infoLen);
00245 
00246 
00247 /** Gracefully close the connection. You cannot publish any messages
00248     after calling this method.
00249     \param o the SharkMQ instance.
00250  */
00251 void SharkMQ_disconnect(SharkMQ* o);
00252 
00253 
00254 /** Terminate a SimpleMQ instance.
00255     \param o the SharkMQ instance.
00256  */
00257 void SharkMQ_destructor(SharkMQ* o);
00258 
00259 
00260 /** Create a topic an fetch the topic ID (tid). The SharkMQ protocol is
00261     optimized and does not directly use a string when publishing, but a
00262     number. The server randomly a creates 32 bit number and
00263     persistently stores the topic name and number.
00264 
00265     The response to SharkMQ_create is asynchronous and returned as status
00266     #SMQ_CREATEACK via #SharkMQ_getMessage.
00267 
00268     \param o the SharkMQ instance.
00269     \param topic the topic name where you plan on publishing messages.
00270  */
00271 int SharkMQ_create(SharkMQ* o, const char* topic);
00272 
00273 
00274 /** Create a sub-topic and fetch the subtopic ID.
00275 
00276     The response to SharkMQ_subscribe is asynchronous and returned as status
00277     #SMQ_CREATESUBACK via #SharkMQ_getMessage.
00278 
00279     \param o the SharkMQ instance.
00280     \param subtopic the sub-topic name you want registered.
00281  */
00282 int SharkMQ_createsub(SharkMQ* o, const char* subtopic);
00283 
00284 
00285 /** Subscribe to topic.
00286 
00287     The response to SharkMQ_subscribe is asynchronous and returned as status
00288     #SMQ_SUBACK via #SharkMQ_getMessage.
00289 
00290     \param o the SharkMQ instance.
00291     \param topic the topic name to subscribe to.
00292  */
00293 int SharkMQ_subscribe(SharkMQ* o, const char* topic);
00294 
00295 
00296 /** Requests the broker to unsubscribe the client from a topic.
00297     \param o the SharkMQ instance.
00298     \param tid the topic name's Topic ID.
00299  */
00300 int SharkMQ_unsubscribe(SharkMQ* o, U32 tid);
00301 
00302 
00303 /** Publish messages to a topic and optionally to a sub-topic. Topic
00304     name must have previosly been been resolved by #SharkMQ_create and
00305     sub-topic should preferably have been created by #SharkMQ_createsub.
00306     \param o the SharkMQ instance.
00307     \param data message payload.
00308     \param len payload length.
00309     \param tid the topic ID (created with SharkMQ_create).
00310     \param subtid optional sub-topic ID preferably created with SharkMQ_createsub.
00311  */
00312 int SharkMQ_publish(SharkMQ* o, const void* data, int len, U32 tid, U32 subtid);
00313 
00314 
00315 /** Publish a message in chunks and request the broker to assemble the
00316     message before publishing to the subscriber(s). This method uses
00317     the internal SharkSSL send buffer and sends the message as a chunk
00318     when the internal buffer is full, thus sending the message as an
00319     incomplete message to the broker. The message is assembled by the
00320     broker when you flush the remaining bytes in the buffer by calling
00321     #SharkMQ_pubflush.
00322 
00323     \param o the SharkMQ instance.
00324     \param str a string.
00325  */
00326 int SharkMQ_wrtstr(SharkMQ* o, const char* str);
00327 
00328 /** Publish a message in chunks and request the broker to assemble the
00329     message before publishing to the subscriber(s). This method uses
00330     the internal SharkSSL send buffer and sends the message as a chunk
00331     when the internal buffer is full, thus sending the message as an
00332     incomplete message to the broker. The message is assembled by the
00333     broker when you flush the remaining bytes in the buffer by calling
00334     #SharkMQ_pubflush.
00335 
00336 
00337     \param o the SharkMQ instance.
00338     \param data message payload.
00339     \param len payload length.
00340  */
00341 int SharkMQ_write(SharkMQ* o,  const void* data, int len);
00342 
00343 /** Flush the internal buffer and request the broker to assemble all
00344     stored fragments as one message. This message is then published to
00345     topic 'tid', and sub-topic 'subtid'.
00346 
00347     \param o the SharkMQ instance.
00348     \param tid the topic ID (created with SharkMQ_create).
00349     \param subtid optional sub-topic ID preferably created with SharkMQ_createsub.
00350 
00351     Example:
00352     \code
00353     SharkMQ_wrtstr(smq, "Hello");
00354     SharkMQ_wrtstr(smq, " ");
00355     SharkMQ_wrtstr(smq, "World");
00356     SharkMQ_pubflush(smq,tid,subtid);
00357     \endcode
00358 
00359  */
00360 int SharkMQ_pubflush(SharkMQ* o, U32 tid, U32 subtid);
00361 
00362 
00363 /** Request the broker to provide change notification events when the
00364     number of subscribers to a specific topic changes. Ephemeral topic
00365     IDs can also be observed. The number of connected subscribers for
00366     an ephemeral ID can only be one, which means the client is
00367     connected. Receiving a change notification for an ephemeral ID
00368     means the client has disconnected and that you no longer will get
00369     any change notifications for the observed topic ID.
00370 
00371     Change notification events are received as #SMQ_SUBCHANGE via
00372     #SharkMQ_getMessage.
00373 
00374     \param o the SharkMQ instance.
00375     \param tid the Topic ID you which to observe.
00376  */
00377 int SharkMQ_observe(SharkMQ* o, U32 tid);
00378 
00379 
00380 /** Stop receiving change notifications for a topic ID or ephemeral topic ID.
00381     \param o the SharkMQ instance.
00382     \param tid the Topic ID you no longer want to observe.
00383  */
00384 int SharkMQ_unobserve(SharkMQ* o, U32 tid);
00385 
00386 
00387 /** Wait for messages sent from the broker.
00388     \param o the SharkMQ instance.
00389     \param msg a pointer to the response data (out param)
00390     \returns
00391     \li a negative value signals an
00392     [error code](\ref SharkMQErrorCodes) or an
00393     [asynchronous response code](\ref SharkMQRespCodes).
00394     \li zero signals timeout.
00395     \li a value greater than zero signals the reception of a full
00396     message or a message fragment. See receiving large frames for details.
00397 
00398     <b>Receiving large frames:</b><br>
00399     The SimpleMQ protocol is frame based, but the function can return
00400     a fragment before the complete SimpleMQ frame is received if the
00401     frame sent by the peer is larger than the provided buffer. The
00402     frame length is returned in SharkMQ::frameLen and the data consumed
00403     thus far is returned in SharkMQ::bytesRead. The complete frame is
00404     consumed when frameLen == bytesRead.
00405 
00406     <b>Note:</b> the default timeout value is set to one minute. You
00407     can set the timeout value by setting SharkMQ::timeout to the
00408     number of milliseconds you want to wait for incoming messages
00409     before the timeout triggers. Note: Setting a long timeout may
00410     interfere with the built in PING timer.
00411  */
00412 int SharkMQ_getMessage(SharkMQ* o, U8** msg);
00413 
00414 
00415 /** Returns the message size, which is SharkMQ::frameLen - 15.
00416     \param o the SharkMQ instance.
00417  */
00418 #define SMQ_getMsgSize(o)
00419 
00420 /** @} */ /* end group SMQLib */
00421 
00422 #endif