static void sublup_context_callback(pubnub_t*         pb,
                                    enum pubnub_trans trans,
                                    enum pubnub_res   result,
                                    void*             user_data)
{
    pubnub_subloop_t* pbsld = (pubnub_subloop_t*)user_data;

    PUBNUB_ASSERT_OPT(pbsld != NULL);

    pubnub_mutex_lock(pbsld->monitor);
    if (PBTT_SUBSCRIBE == trans) {
        if (PNR_OK == result) {
            char const* msg;
            for (msg = pubnub_get(pb); msg != NULL; msg = pubnub_get(pb)) {
                pbsld->cb(pb, msg, PNR_OK);
            }
        }
        else {
            pbsld->cb(pb, NULL, result);
        }
        result = pubnub_subscribe_ex(pbsld->pbp, pbsld->channel, pbsld->options);
        if (result != PNR_STARTED) {
            PUBNUB_LOG_ERROR("Failed to re-subscribe in the subscribe loop, "
                             "error code = %d\n",
                             result);
        }
    }
    pubnub_mutex_unlock(pbsld->monitor);
}
Ejemplo n.º 2
0
int main()
{
    enum pubnub_res pbresult;
    pubnub_t *ctx = pubnub_alloc();
    if (NULL == ctx) {
        puts("Couldn't allocate a Pubnub context");
        return -1;
    }
    
    char pubkey[] = "pub-c-9e002851-755d-4197-9037-cfe897af871d";
	char subkey[] = "sub-c-82c22366-19a3-11e6-9a17-0619f8945a4f";
	char chnlname[] = "hello_world";
	
	printf("pubnub info\npubkey %s\nsubkey %s\nchnlname %s\n",pubkey, subkey, chnlname);
	fflush(stdout);
    pubnub_init(ctx, pubkey, subkey);

    pubnub_subscribe(ctx, chnlname, NULL);
    pbresult = pubnub_await(ctx);
    if (pbresult != PNR_OK) {
        printf("Failed to subscribe, error %d\n", pbresult);
        pubnub_free(ctx);
        return -1;
    }

    while (1) {
    	fflush(stdout);
        pubnub_subscribe(ctx, chnlname, NULL);
        pbresult = pubnub_await(ctx);
        if (pbresult != PNR_OK) {
            printf("Failed to subscribe, error %d\n", pbresult);
            pubnub_free(ctx);
            return -1;
        }
        else {
            char const *msg = pubnub_get(ctx);
            while (msg != NULL) {
                
                // printf("Got message: %s\n", msg);
                put_data_buf(msg);
                msg = pubnub_get(ctx);
                // printf("Got message2: %s\n", msg);
            }
        }
    }
    pubnub_free(ctx);
    return 0;
}
Ejemplo n.º 3
0
void pnc_ops_parse_callback(enum pubnub_trans method_name, enum pubnub_res res, pubnub_t *pn)
{
    if (res == PNR_HTTP_ERROR) {
        printf("%d HTTP error / code: %d\n",
               method_name, pubnub_last_http_code(pn));
        return;
    }
    
    if (res == PNR_STARTED) {
        printf("%d returned unexpected: PNR_STARTED(%d)\n", method_name, res);
        return;
    }
    
    if (PNR_OK == res) {
        const char *msg;
        
        puts("***************************");
        printf("Result for %d: success!\n", method_name);
        puts("***************************");
        for (;;) {
            msg = pubnub_get(pn);
            if (NULL == msg) {
                break;
            }
            puts(msg);
        }
        puts("***************************");
    } 
    else {
        printf("%d failed, error code %d: %s !\n", method_name, res, pubnub_res_2_string(res));
    }
}
Ejemplo n.º 4
0
int srand_from_pubnub_time(pubnub_t *pbp)
{
    pubnub_res rslt = pubnub_time(pbp);
    if (rslt != PNR_STARTED) {
        return -1;
    }
    rslt = pubnub_await(pbp);
    if (rslt != PNR_OK) {
        return -1;
    }
    char const* pbtime = pubnub_get(pbp);
    if (0 == pbtime)  {
        return -1;
    }
    size_t length_of_time = strlen(pbtime);
    if (0 == length_of_time) {
        return -1;
    }
    char const *s = pbtime + length_of_time - 1;
    unsigned int val_for_srand = 0;
    for (int i = 0; (i < 10) && (s > pbtime); ++i, --s) {
        val_for_srand = val_for_srand * 10 + *s - '0';
    }
    
    srand(val_for_srand);
    
    return 0;
}
Ejemplo n.º 5
0
pubnub_bymebl_t pubnub_get_decrypted_alloc(pubnub_t *pb, char const* cipher_key)
{
    char *msg;
    size_t msg_len;
    pubnub_bymebl_t result = { NULL, 0 };

    PUBNUB_ASSERT(pb_valid_ctx_ptr(pb));
    PUBNUB_ASSERT_OPT(cipher_key != NULL);

    msg = (char*)pubnub_get(pb);
    if (NULL == msg) {
        return result;
    }
    msg_len = strlen(msg);
    if ((msg[0] != '"') || (msg[msg_len-1] != '"')) {
        return result;
    }
    msg[msg_len - 1] = '\0';
    ++msg;

    pubnub_json_string_unescape_slash(msg);

    result = pubnub_decrypt_alloc(cipher_key, msg);
    if (NULL != result.ptr) {
        result.ptr[result.size] = '\0';
    }

    return result;
}
Ejemplo n.º 6
0
enum pubnub_res pubnub_get_decrypted(pubnub_t *pb, char const* cipher_key, char *s, size_t *n)
{
    char *msg;
    size_t msg_len;
    uint8_t decoded_msg[PUBNUB_BUF_MAXLEN];
    pubnub_bymebl_t data = { (uint8_t*)s, *n };
    pubnub_bymebl_t buffer = { decoded_msg, PUBNUB_BUF_MAXLEN };

    PUBNUB_ASSERT(pb_valid_ctx_ptr(pb));
    PUBNUB_ASSERT_OPT(cipher_key != NULL);
    PUBNUB_ASSERT_OPT(s != NULL);
    PUBNUB_ASSERT_OPT(n != NULL);

    msg = (char*)pubnub_get(pb);
    if (NULL == msg) {
        return PNR_INTERNAL_ERROR;
    }
    msg_len = strlen(msg);
    if ((msg[0] != '"') || (msg[msg_len-1] != '"')) {
        return PNR_FORMAT_ERROR;
    }
    msg[msg_len - 1] = '\0';
    ++msg;

    pubnub_json_string_unescape_slash(msg);

    if (0 != pubnub_decrypt_buffered(cipher_key, msg, &data, &buffer)) {
        return PNR_INTERNAL_ERROR;
    }
    *n = data.size;
    data.ptr[data.size] = '\0';

    return PNR_OK;
}
Ejemplo n.º 7
0
bool pnfntst_got_message_on_channel(pubnub_t *p, char const *message, char const *channel)
{
	char const *msg;
	char const *chan;
    PUBNUB_ASSERT(pb_valid_ctx_ptr(p));
    PUBNUB_ASSERT_OPT(NULL != message);
    PUBNUB_ASSERT_OPT(NULL != channel);

	msg = pubnub_get(p);
	chan = pubnub_get_channel(p);
	if ((NULL == msg) || (NULL == chan)) {
		return false;
	}
    return (strcmp(msg, message) == 0) && (strcmp(chan, channel) == 0);
}
Ejemplo n.º 8
0
void pnc_ops_parse_response(const char *method_name, enum pubnub_res res, pubnub_t *pn)
{
    const char *msg;
    
    if (res != PNR_STARTED) {
        printf("%s returned error %d: %s\n", method_name, res, pubnub_res_2_string(res));
        return;
    }
    
    res = pubnub_await(pn);
    
    if (res == PNR_HTTP_ERROR) {
        printf("%s HTTP error / code: %d\n",
               method_name, pubnub_last_http_code(pn));
        return;
    }
    
    if (res == PNR_STARTED) {
        printf("%s returned unexpected: PNR_STARTED(%d)\n", method_name, res);
        return;
    }
    
    if (PNR_OK == res) {
        puts("\n****************************************");
        printf("Result for %s: success!\n", method_name);
        puts("****************************************");
        for (;;) {
            msg = pubnub_get(pn);
            if (NULL == msg) {
                break;
            }
            puts(msg);
        }
        puts("****************************************");
    }
    else {
        printf("%s failed! error code %d: %s\n", method_name, res, pubnub_res_2_string(res));
    }
}
Ejemplo n.º 9
0
bool pnfntst_got_messages(pubnub_t *p, ...)
{
    char const *aMsgs[16];
    uint16_t missing;
    size_t count = 0;
    va_list vl;

    PUBNUB_ASSERT(pb_valid_ctx_ptr(p));

    va_start(vl, p);
    while (count < 16) {
        char const *msg = va_arg(vl, char*);
        if (NULL == msg) {
            break;
        }
        aMsgs[count++] = msg;
    }
    va_end(vl);

    if ((0 == count) || (count > 16)) {
        return false;
    }

    missing = (0x01 << count) - 1;
    while (missing) {
        size_t i;
        char const *msg = pubnub_get(p);
        if (NULL == msg) {
            break;
        }
        for (i = 0; i < count; ++i) {
            if ((missing & (0x01 << i)) && (strcmp(msg, aMsgs[i]) == 0)) {
                missing &= ~(0x01 << i);
                break;
            }
        }
    }
    return !missing;
}
Ejemplo n.º 10
0
bool pnfntst_subscribe_and_check(pubnub_t *p, char const *channel, char const*chgroup, unsigned ms, ...)
{
	char const *aMsgs[16];
    char const *aChan[16];
    uint16_t missing;
    size_t count = 0;
	pnfntst_timer_t *tmr;
    va_list vl;

    PUBNUB_ASSERT(pb_valid_ctx_ptr(p));

    va_start(vl, ms);
    while (count < 16) {
        char const *msg = va_arg(vl, char*);
        if (NULL == msg) {
            break;
        }
        aMsgs[count] = msg;
		msg = va_arg(vl, char*);
        if (NULL == msg) {
            return false;
        }
		aChan[count] = msg;
		++count;
    }
    va_end(vl);

    if ((0 == count) || (count > 16)) {
        return false;
    }

    missing = (0x01 << count) - 1;
    tmr = pnfntst_alloc_timer();
    if (NULL == tmr) {
		puts("subscribe and check: timer alloc failed");
		return false;
	}
    pnfntst_start_timer(tmr, ms);
    while (pnfntst_timer_is_running(tmr) && missing) {
		enum pubnub_res pbres;
		if (PNR_STARTED != pubnub_subscribe(p, channel, chgroup)) {
			puts("subscribe and check: subscribe failed");
			break;
		}
		while (pnfntst_timer_is_running(tmr)) {
			pbres = pubnub_last_result(p);
			if (pbres != PNR_STARTED) {
				break;
			}
		}
		if (pbres != PNR_OK) {
			printf("subscribe and check: subscribe error %d\n", pbres);
			break;
		}
	
        do {
			size_t i;
			char const *msg = pubnub_get(p);
			char const *chan = pubnub_get_channel(p);
			if ((NULL == msg) || (NULL == chan)) {
				break;
			}
			for (i = 0; i < count; ++i) {
				if ((missing & (0x01 << i)) && (strcmp(msg, aMsgs[i]) == 0)
					 && (strcmp(chan, aChan[i]) == 0)
				 ) {
					missing &= ~(0x01 << i);
					break;
				}
			}
		} while (missing);
    }
    
	pnfntst_free_timer(tmr);
    
	return !missing;
}
Ejemplo n.º 11
0
int main()
{
    char const *msg;
    enum pubnub_res res;
    char const *chan = "hello_world";
    pubnub_t *pbp = pubnub_alloc();

    if (NULL == pbp) {
        printf("Failed to allocate Pubnub context!\n");
        return -1;
    }
    pubnub_init(pbp, "demo", "demo");

    pubnub_set_transaction_timeout(pbp, PUBNUB_DEFAULT_NON_SUBSCRIBE_TIMEOUT);
    
    /* Leave this commented out to use the default - which is
       blocking I/O on most platforms. Uncomment to use non-
       blocking I/O.
    */
//    pubnub_set_non_blocking_io(pbp);

    generate_uuid(pbp);

    pubnub_set_auth(pbp, "danaske");

    puts("Publishing...");
    res = pubnub_publish(pbp, chan, "\"Hello world from sync!\"");
    if (res != PNR_STARTED) {
        printf("pubnub_publish() returned unexpected: %d\n", res);
        pubnub_free(pbp);
        return -1;
    }
    res = pubnub_await(pbp);
    if (res == PNR_STARTED) {
        printf("pubnub_await() returned unexpected: PNR_STARTED(%d)\n", res);
        pubnub_free(pbp);
        return -1;
    }
    if (PNR_OK == res) {
        printf("Published! Response from Pubnub: %s\n", pubnub_last_publish_result(pbp));
    }
    else if (PNR_PUBLISH_FAILED == res) {
        printf("Published failed on Pubnub, description: %s\n", pubnub_last_publish_result(pbp));
    }
    else {
        printf("Publishing failed with code: %d\n", res);
    }

    puts("Subscribing...");
    res = pubnub_subscribe(pbp, chan, NULL);
    if (res != PNR_STARTED) {
        printf("pubnub_subscribe() returned unexpected: %d\n", res);
        pubnub_free(pbp);
        return -1;
    }
    res = pubnub_await(pbp);
    if (res == PNR_STARTED) {
        printf("pubnub_await() returned unexpected: PNR_STARTED(%d)\n", res);
        pubnub_free(pbp);
        return -1;
    }

    if (PNR_OK == res) {
        puts("Subscribed!");
    }
    else {
        printf("Subscribing failed with code: %d\n", res);
    }

    res = pubnub_subscribe(pbp, chan, NULL);
    if (res != PNR_STARTED) {
        printf("pubnub_subscribe() returned unexpected: %d\n", res);
        pubnub_free(pbp);
        return -1;
    }
    res = pubnub_await(pbp);
    if (res == PNR_STARTED) {
        printf("pubnub_await() returned unexpected: PNR_STARTED(%d)\n", res);
        pubnub_free(pbp);
        return -1;
    }

    if (PNR_OK == res) {
        puts("Subscribed! Got messages:");
        for (;;) {
            msg = pubnub_get(pbp);
            if (NULL == msg) {
                break;
            }
            puts(msg);
        }
    }
    else {
        printf("Subscribing failed with code: %d\n", res);
    }

    puts("Getting time...");
    res = pubnub_time(pbp);
    if (res != PNR_STARTED) {
        printf("pubnub_time() returned unexpected: %d\n", res);
        pubnub_free(pbp);
        return -1;
    }
    res = pubnub_await(pbp);
    if (res == PNR_STARTED) {
        printf("pubnub_await() returned unexpected: PNR_STARTED(%d)\n", res);
        pubnub_free(pbp);
        return -1;
    }

    if (PNR_OK == res) {
        printf("Gotten time: %s; last time token=%s\n", pubnub_get(pbp), pubnub_last_time_token(pbp));
    }
    else {
        printf("Getting time failed with code: %d\n", res);
    }

    puts("Getting history with include_token...");
    res = pubnub_history(pbp, chan, 10, true);
    if (res != PNR_STARTED) {
        printf("pubnub_history() returned unexpected: %d\n", res);
        pubnub_free(pbp);
        return -1;
    }
    res = pubnub_await(pbp);
    if (res == PNR_STARTED) {
        printf("pubnub_await() returned unexpected: PNR_STARTED(%d)\n", res);
        pubnub_free(pbp);
        return -1;
    }

    if (PNR_OK == res) {
        puts("Got history! Elements:");
        for (;;) {
            msg = pubnub_get(pbp);
            if (NULL == msg) {
                break;
            }
            puts(msg);
        }
    }
    else {
        printf("Getting history v2 with include_token failed with code: %d\n", res);
    }

    puts("Getting here_now presence...");
    res = pubnub_here_now(pbp, chan, NULL);
    if (res != PNR_STARTED) {
        printf("pubnub_here_now() returned unexpected: %d\n", res);
        pubnub_free(pbp);
        return -1;
    }
    res = pubnub_await(pbp);
    if (res == PNR_STARTED) {
        printf("pubnub_await() returned unexpected: PNR_STARTED(%d)\n", res);
        pubnub_free(pbp);
        return -1;
    }

    if (PNR_OK == res) {
        puts("Got here now presence!");
        for (;;) {
            msg = pubnub_get(pbp);
            if (NULL == msg) {
                break;
            }
            puts(msg);
        }
    }
    else {
        printf("Getting here-now presence failed with code: %d\n", res);
    }

    /** Global here_now presence for "demo" subscribe key is _very_
        long, but we have it here to show that we can handle very long
        response if the PUBNUB_DYNAMIC_REPLY_BUFFER is "on".
    */
    if (PUBNUB_DYNAMIC_REPLY_BUFFER) {
        puts("Getting global here_now presence...");
        res = pubnub_global_here_now(pbp);
        if (res != PNR_STARTED) {
            printf("pubnub_global_here_now() returned unexpected: %d\n", res);
            pubnub_free(pbp);
            return -1;
        }
        res = pubnub_await(pbp);
        if (res == PNR_STARTED) {
            printf("pubnub_await() returned unexpected: PNR_STARTED(%d)\n", res);
            pubnub_free(pbp);
            return -1;
        }
        
        if (PNR_OK == res) {
            puts("Got global here now presence!");
            for (;;) {
                msg = pubnub_get(pbp);
                if (NULL == msg) {
                    break;
                }
                puts(msg);
            }
        }
        else {
            printf("Getting global here-now presence failed with code: %d\n", res);
        }
    }

    puts("Getting where_now presence...");
    res = pubnub_where_now(pbp, pubnub_uuid_get(pbp));
    if (res != PNR_STARTED) {
        printf("pubnub_where_now() returned unexpected: %d\n", res);
        pubnub_free(pbp);
        return -1;
    }
    res = pubnub_await(pbp);
    if (res == PNR_STARTED) {
        printf("pubnub_await() returned unexpected: PNR_STARTED(%d)\n", res);
        pubnub_free(pbp);
        return -1;
    }

    if (PNR_OK == res) {
        puts("Got where now presence!");
        for (;;) {
            msg = pubnub_get(pbp);
            if (NULL == msg) {
                break;
            }
            puts(msg);
        }
    }
    else {
        printf("Getting where-now presence failed with code: %d\n", res);
    }

    puts("Setting state...");
    res = pubnub_set_state(pbp, chan, NULL, pubnub_uuid_get(pbp), "{\"x\":5}");
    if (res != PNR_STARTED) {
        printf("pubnub_set_state() returned unexpected: %d\n", res);
        pubnub_free(pbp);
        return -1;
    }
    res = pubnub_await(pbp);
    if (res == PNR_STARTED) {
        printf("pubnub_await() returned unexpected: PNR_STARTED(%d)\n", res);
        pubnub_free(pbp);
        return -1;
    }

    if (PNR_OK == res) {
        puts("Got set state response!");
        for (;;) {
            msg = pubnub_get(pbp);
            if (NULL == msg) {
                break;
            }
            puts(msg);
        }
    }
    else {
        printf("Setting state failed with code: %d\n", res);
    }

    puts("Getting state...");
    res = pubnub_state_get(pbp, chan, NULL, pubnub_uuid_get(pbp));
    if (res != PNR_STARTED) {
        printf("pubnub_state_get() returned unexpected: %d\n", res);
        pubnub_free(pbp);
        return -1;
    }
    res = pubnub_await(pbp);
    if (res == PNR_STARTED) {
        printf("pubnub_await() returned unexpected: PNR_STARTED(%d)\n", res);
        pubnub_free(pbp);
        return -1;
    }

    if (PNR_OK == res) {
        puts("Got state!");
        for (;;) {
            msg = pubnub_get(pbp);
            if (NULL == msg) {
                break;
            }
            puts(msg);
        }
    }
    else {
        printf("Getting state failed with code: %d\n", res);
    }

    puts("List channel group...");
    res = pubnub_list_channel_group(pbp, "channel-group");
    if (res != PNR_STARTED) {
        printf("pubnub_state_get() returned unexpected: %d\n", res);
        pubnub_free(pbp);
        return -1;
    }
    res = pubnub_await(pbp);
    if (res == PNR_STARTED) {
        printf("pubnub_await() returned unexpected: PNR_STARTED(%d)\n", res);
        pubnub_free(pbp);
        return -1;
    }

    if (PNR_OK == res) {
        puts("Got channel group list!");
        for (;;) {
            msg = pubnub_get_channel(pbp);
            if (NULL == msg) {
                break;
            }
            puts(msg);
        }
    }
    else {
        printf("Getting channel group list failed with code: %d ('%s')\n", res, pubnub_res_2_string(res));
    }
	
    /* We're done */
    if (pubnub_free(pbp) != 0) {
        printf("Failed to free the Pubnub context\n");
    }

    puts("Pubnub sync demo over.");

    return 0;
}
int main()
{
    /* This is a widely use channel, something should happen there
       from time to time
    */
    char const *chan = "hello_world";
    pubnub_t *pbp = pubnub_alloc();
    if (NULL == pbp) {
        printf("Failed to allocate Pubnub context!\n");
        return -1;
    }

    pubnub_init(pbp, "demo", "demo");
    srand(time(NULL));

    /* This is essential, as otherwise waiting for incoming data will
       block! Since we're doing this, be sure to not enable verbose
       debugging, as you won't see a thing except endless lines of
       some tracing.
    */
    pubnub_set_non_blocking_io(pbp);

    puts("--------------------------");
    puts("Subscribe loop starting...");
    puts("--------------------------");
	
    for (;;) {
        time_t t = time(NULL);
        bool stop = false;
        enum pubnub_res res = pubnub_subscribe(pbp, chan, NULL);
        if (res != PNR_STARTED) {
            printf("pubnub_subscribe() returned unexpected: %d\n", res);
            break;;
        }

        /* Don't await here, 'cause it will loop until done */
        while (!stop) {
            res = pubnub_last_result(pbp);
            if (res == PNR_STARTED) {
                /* Here we simulate the "get out of subscribe loop"
                   external signal with a random number. Basically,
                   this has a 4% chance of stopping the wait every
                   second.
                */
                if (time(NULL) != t) {
                    stop = (rand() % 25) == 3;
                    t = time(NULL);
                }
            }
            else {
                if (PNR_OK == res) {
                    puts("Subscribed! Got messages:");
                    for (;;) {
                        char const *msg = pubnub_get(pbp);
                        if (NULL == msg) {
                            break;
                        }
                        puts(msg);
                    }
                }
                else {
                    printf("Subscribing failed with code: %d\n", res);
                }
                break;
            }
        }
        if (stop) {
            puts("---------------------------");
            puts("Cancelling the Subscribe...");
            puts("---------------------------");
            pubnub_cancel(pbp);
            /* Now it's OK to await, since we don't have anything else
               to do
            */
            pubnub_await(pbp);
            break;
        }
    }

	
    /* We're done */
    if (pubnub_free(pbp) != 0) {
        printf("Failed to free the Pubnub context `pbp`\n");
    }

    puts("Pubnub callback demo over.");

    return 0;
}
int main()
{
    char const *msg;
    enum pubnub_res res;
    struct UserData user_data;
    struct UserData user_data_2;
    char const *chan = "hello_world";
    pubnub_t *pbp = pubnub_alloc();
    pubnub_t *pbp_2 = pubnub_alloc();
    if (NULL == pbp) {
        printf("Failed to allocate Pubnub context!\n");
        return -1;
    }
    if (NULL == pbp_2) {
        printf("Failed to allocate Pubnub context!\n");
        return -1;
    }

    InitUserData(&user_data, pbp);
    InitUserData(&user_data_2, pbp_2);

    pubnub_init(pbp, "demo", "demo");
    pubnub_register_callback(pbp, sample_callback, &user_data);
    pubnub_init(pbp_2, "demo", "demo");
    pubnub_register_callback(pbp_2, sample_callback, &user_data_2);

    puts("-----------------------");
    puts("Subscribing...");
    puts("-----------------------");
	
    /* First subscribe, to get the time token */
    res = pubnub_subscribe(pbp, chan, NULL);
    if (res != PNR_STARTED) {
        printf("pubnub_subscribe() returned unexpected: %d\n", res);
        pubnub_free(pbp);
        pubnub_free(pbp_2);
        return -1;
    }

    puts("Await subscribe");
    res = await(&user_data);
    if (res == PNR_STARTED) {
        printf("await() returned unexpected: PNR_STARTED(%d)\n", res);
        pubnub_free(pbp);
        pubnub_free(pbp_2);
        return -1;
    }
    if (PNR_OK == res) {
        puts("Subscribed!");
    }
    else {
        printf("Subscribing failed with code: %d\n", res);
    }

    /* The "real" subscribe, with the just acquired time token */
    res = pubnub_subscribe(pbp, chan, NULL);
    if (res != PNR_STARTED) {
        printf("pubnub_subscribe() returned unexpected: %d\n", res);
        pubnub_free(pbp);
        pubnub_free(pbp_2);
        return -1;
    }
	
    /* Don't do "full" await here, because we didn't publish anything yet! */
    start_await(&user_data);
    
    puts("-----------------------");
    puts("Publishing...");
    puts("-----------------------");
    /* Since the subscribe is ongoing in the `pbp` context, we can't
       publish on it, so we use a different context to publish
    */
    res = pubnub_publish(pbp_2, chan, "\"Hello world from subscribe-publish callback sample!\"");
    if (res != PNR_STARTED) {
        printf("pubnub_publish() returned unexpected: %d\n", res);
        pubnub_free(pbp);
        pubnub_free(pbp_2);
        return -1;
    }

    puts("Await publish");
    res = await(&user_data_2);
    if (res == PNR_STARTED) {
        printf("await() returned unexpected: PNR_STARTED(%d)\n", res);
        pubnub_free(pbp);
        pubnub_free(pbp_2);
        return -1;
    }
    if (PNR_OK == res) {
        printf("Published! Response from Pubnub: %s\n", pubnub_last_publish_result(pbp_2));
    }
    else if (PNR_PUBLISH_FAILED == res) {
        printf("Published failed on Pubnub, description: %s\n", pubnub_last_publish_result(pbp_2));
    }
    else {
        printf("Publishing failed with code: %d\n", res);
    }
	
    /* Don't need `pbp_2` no more */
    if (pubnub_free(pbp_2) != 0) {
        printf("Failed to free the Pubnub context `pbp_2`\n");
    }
	
    /* Now we await the subscribe on `pbp` */
    puts("Await subscribe");
    res = end_await(&user_data);
    if (res == PNR_STARTED) {
        printf("await() returned unexpected: PNR_STARTED(%d)\n", res);
        pubnub_free(pbp);
        return -1;
    }
    if (PNR_OK == res) {
        puts("Subscribed! Got messages:");
        for (;;) {
            msg = pubnub_get(pbp);
            if (NULL == msg) {
                break;
            }
            puts(msg);
        }
    }
    else {
        printf("Subscribing failed with code: %d\n", res);
    }

	
    /* We're done */
    if (pubnub_free(pbp) != 0) {
        printf("Failed to free the Pubnub context `pbp`\n");
    }

    puts("Pubnub subscribe-publish callback demo over.");

    return 0;
}