Modified PubNub library to better utilize low bandwidth connections like a GSM modem. Instead of 10 socket connections sending 3 bytes only one is made and it sends all 30 bytes at the same time.

Fork of PubNub by PubNub

PubNub.h

Committer:
sam_grove
Date:
2014-03-24
Revision:
5:cfcba723d245
Parent:
4:a4759c403023
Child:
7:55eb53c78b47

File content as of revision 5:cfcba723d245:

/* PubNub.h */
/* Copyright (c) 2013 PubNub Inc.
 * http://www.pubnub.com/
 * http://www.pubnub.com/terms
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/** \file
PubNub Client header file 
*/

#ifndef PubNub_h
#define PubNub_h

#include "TCPSocketConnection.h"


/* TODO: UUID */
/* TODO: secret_key */
/* TODO: cipher_key */
/* TODO: timeout support */

/* Maximum length of the HTTP reply. This buffer is dynamically allocated
 * only when loading the reply from the network. */
/* XXX: Replies of API calls longer than this will be discarded and instead,
 * PNR_FORMAT_ERROR will be reported. Specifically, this may cause lost
 * messages returned by subscribe if too many too large messages got queued. */
#ifndef PUBNUB_REPLY_MAXLEN
#define PUBNUB_REPLY_MAXLEN (2048-8-1)
#endif


/* Result codes for PubNub methods. */
enum PubNubRes {
    /* Success. */
    PNR_OK,
    /* Time out before the request has completed. */
    PNR_TIMEOUT,
    /* Communication error (network or HTTP response format). */
    PNR_IO_ERROR,
    /* HTTP error. */
    PNR_HTTP_ERROR,
    /* Unexpected input in received JSON. */
    PNR_FORMAT_ERROR,
    /* PubNub JSON reply indicates failure. */
    PNR_PUBNUB_ERROR,
};


/** A PubNub Client context. Declare it as a local or global variable,
 * then you may start calling the API immediately.
 *
 * All methods are blocking; if you need to communicate with
 * PubNub asynchronously, run PubNub in a dedicated thread.
 * Always use the PubNub context only in a single thread at once.
 *
 * Message are passed as strings instead of JSON structures due
 * to much higher RAM efficiency.  Often, ad hoc composing and
 * parsing JSON messages will work fine in practice.  Otherwise,
 * take a look at e.g. the picojson library. */
class PubNub {
public:
    /** Init a Pubnub Client context
     *
     * Note that the string parameters are not copied; do not
     * overwrite or free the memory where you stored the keys!
     * (If you are passing string literals, don't worry about it.)
     *
     * @param string publish_key required key to send messages.
     * @param string subscribe_key required key to receive messages.
     * @param string origin optional setting for cloud origin. */
    PubNub(const char *publish_key, const char *subscribe_key, const char *origin = "http://pubsub.pubnub.com");
    
    ~PubNub();

    /** Publish API call
     *
     * Send a message (assumed to be well-formed JSON) to a given channel.
     *
     * Examples:
     * @code
         p.publish("demo", "\"lala\"");
     * @endcode
     * or
     * @code
         if (p.publish("demo", "{\"lala\":1}") != PNR_OK) {
           blink_error();
         }
     * @endcode
     *
     * @param channel required channel name.
     * @param message required JSON message object.
     * @param reply optional pointer for passing the returned reply (free() after use).
     * @return PNR_OK on success. */
    PubNubRes publish(const char *channel, const char *message, char **reply = NULL);

    /** Subscribe API call
     *
     * Listen for a message on a given channel. The function will block
     * and return when a message arrives. Typically, you will run this
     * function in a loop to keep listening for messages indefinitely.
     *
     * As a reply, you will get a JSON message.  If you are used to
     * PubNub API in other environments, you would expect an array
     * of messages; here, even if the device received multiple messages
     * batched, they are spread over subsequent PubNub.subscribe() calls
     * and each returns only a single message. However, *reply can be
     * set NULL - in that case, simply retry the call, this indicates
     * an empty reply from the server (what happens e.g. after waiting
     * for certain interval, or immediately after subscribing).
     *
     * Contrary to publish(), you should NOT free() the reply yourself!
     * Instead, you are expected to call another subscribe() just after
     * processing the reply; subscribe() will release any memory it can
     * before waiting for new data from the server.
     *
     * Examples:
     * @code
         while (1) {
             char *reply;
             if (p.subscribe("demo", &reply) != PNR_OK) continue;
             if (!reply) continue;
             int code = -1;
             if (sscanf(reply, "{\"code\":%d}", &code) == 1)
               printf("received JSON msg with code %d\n", code);
         }
     * @endcode
     *
     * @param channel required channel name.
     * @param reply required pointer for passing the returned reply (do not free()).
     * @return PNR_OK on success. */
    PubNubRes subscribe(const char *channel, char **reply);

    /* TODO: subscribe_multi */

    /** History API call
     *
     * Receive list of the last N messages on the given channel.
     *
     * The messages are returned in the reply buffer, with each message
     * terminated by a NUL byte, i.e. being a standalone C string; to
     * iterate over all the messages, you can use the replysize. reply
     * can be NULL if there is no history for this channel.
     *
     * Example:
     * @code
        char *reply;
        int replysize;
        if (p.history("demo", &reply, &replysize) != PNR_OK) return;
        if (!reply) return;
        for (char *msg = reply; msg < reply + replysize; msg += strlen(msg)+1)
            printf("historic message: %s\n", msg);
        free(reply);
     * @endcode
     *
     * @param channel required channel name.
     * @param reply required pointer for passing the returned reply (free() after use).
     * @param replysize required pointer for returning the total reply size.
     * @param int limit optional number of messages to retrieve.
     * @return PNR_OK on success. */
    PubNubRes history(const char *channel, char **reply, int *replysize, int limit = 10);
    
    /** Time API call
     *
     * Receive the current server timestamp and store it in the
     * provided string buffer (a char[32] or larger).
     *
     * @param ts required pointer to the string buffer.
     * @return PNR_OK on success. */
    PubNubRes time(char *ts);

    /* TODO: here_now */

protected:
    const char *m_publish_key, *m_subscribe_key;

    const char *m_origin;
    const char *origin_hostname();

    char m_timetoken[32];
    char *m_replybuf;
    int m_replylen;

    /* Back-end post-processing of subscribe(). free()s *reply
     * in the process. */
    PubNubRes subscribe_processjson(char *reply, int replylen);
};

#endif