diff --git a/Source/PubnubLibrary/Private/PubnubLibrary.cpp b/Source/PubnubLibrary/Private/PubnubLibrary.cpp index 35d57e2..ff4d3a1 100644 --- a/Source/PubnubLibrary/Private/PubnubLibrary.cpp +++ b/Source/PubnubLibrary/Private/PubnubLibrary.cpp @@ -2,18 +2,33 @@ #include "PubnubLibrary.h" #include "Core.h" -#include "Kismet/KismetSystemLibrary.h" +#include "Interfaces/IPluginManager.h" #define LOCTEXT_NAMESPACE "FPubnubLibraryModule" void FPubnubLibraryModule::StartupModule() { +#if PLATFORM_MAC + FString BaseDir = IPluginManager::Get().FindPlugin("PubnubChat")->GetBaseDir(); + FString LibraryPath; + LibraryPath = FPaths::Combine(*BaseDir, TEXT("Source/ThirdParty/sdk/lib/macos/libpubnub-chat.dylib")); + + ChatSDKLibraryHandle = !LibraryPath.IsEmpty() ? FPlatformProcess::GetDllHandle(*LibraryPath) : nullptr; + + if (!ChatSDKLibraryHandle) + { + FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT("ChatSDKModuleHandle", "Failed to load pubnub third party library")); + } +#endif } void FPubnubLibraryModule::ShutdownModule() { - +#if PLATFORM_MAC + FPlatformProcess::FreeDllHandle(ChatSDKLibraryHandle); + ChatSDKLibraryHandle = nullptr; +#endif } #undef LOCTEXT_NAMESPACE diff --git a/Source/PubnubLibrary/Public/PubnubLibrary.h b/Source/PubnubLibrary/Public/PubnubLibrary.h index 04c12e1..b8c13b6 100644 --- a/Source/PubnubLibrary/Public/PubnubLibrary.h +++ b/Source/PubnubLibrary/Public/PubnubLibrary.h @@ -13,4 +13,5 @@ class FPubnubLibraryModule : public IModuleInterface virtual void StartupModule() override; virtual void ShutdownModule() override; + void* PubnubLibraryHandle; }; diff --git a/Source/ThirdParty/sdk/Include/core/Makefile b/Source/ThirdParty/sdk/Include/core/Makefile index 34dbb67..73c10d1 100644 --- a/Source/ThirdParty/sdk/Include/core/Makefile +++ b/Source/ThirdParty/sdk/Include/core/Makefile @@ -93,14 +93,14 @@ pbcc_crypto_unittest: $(PROJECT_SOURCEFILES) $(CRYPTO_SOURCEFILES) pbcc_crypto_u $(CGREEN_RUNNER) ./pbcc_crypto_unit_test.so #$(GCOVR) -r . --html --html-details -o coverage.html -pubnub_crypto_unittest: $(PROJECT_SOURCEFILES) $(CRYPTO_SOURCEFILES) pubnub_crypto_unit_tests.c - gcc -o pubnub_crypto_unit_test.so -shared $(CFLAGS) $(LDFLAGS) $(CRYPTO_INCLUDES) $(CRYPTO_LIBS) -D PUBNUB_CRYPTO_API=1 -Wall $(COVERAGE_FLAGS) -fPIC $(PROJECT_SOURCEFILES) $(CRYPTO_SOURCEFILES) test/pubnub_test_mocks.c pubnub_crypto_unit_tests.c -lcgreen -lm +SUBSCRIBE_V2_SOURCEFILES += pubnub_subscribe_v2.c pbcc_subscribe_v2.c + +pubnub_crypto_unittest: $(PROJECT_SOURCEFILES) $(CRYPTO_SOURCEFILES) $(SUBSCRIBE_V2_SOURCEFILES) pubnub_crypto_unit_tests.c + gcc -o pubnub_crypto_unit_test.so -shared $(CFLAGS) $(LDFLAGS) $(CRYPTO_INCLUDES) $(CRYPTO_LIBS) -D PUBNUB_CRYPTO_API=1 -D PUBNUB_USE_SUBSCRIBE_V2=1 -Wall $(COVERAGE_FLAGS) -fPIC $(PROJECT_SOURCEFILES) $(CRYPTO_SOURCEFILES) $(SUBSCRIBE_V2_SOURCEFILES) test/pubnub_test_mocks.c pubnub_crypto_unit_tests.c -lcgreen -lm # gcc -o pubnub_core_unit_testo $(CFLAGS) -Wall $(COVERAGE_FLAGS) $(PROJECT_SOURCEFILES) pubnub_crypto_unit_tests.c -lcgreen -lm $(CGREEN_RUNNER) ./pubnub_crypto_unit_test.so -SUBSCRIBE_V2_SOURCEFILES += pubnub_subscribe_v2.c pbcc_subscribe_v2.c - pubnub_subscribe_v2_unittest: $(PROJECT_SOURCEFILES) $(SUBSCRIBE_V2_SOURCEFILES) pubnub_subscribe_v2_unit_test.c gcc -o pubnub_subscribe_v2_unit_test.so -shared $(CFLAGS) $(LDFLAGS) -D PUBNUB_ORIGIN_SETTABLE=1 -D PUBNUB_USE_SUBSCRIBE_V2=1 -Wall $(COVERAGE_FLAGS) -fPIC $(PROJECT_SOURCEFILES) $(SUBSCRIBE_V2_SOURCEFILES) test/pubnub_test_mocks.c pubnub_subscribe_v2_unit_test.c -lcgreen -lm $(CGREEN_RUNNER) ./pubnub_subscribe_v2_unit_test.so diff --git a/Source/ThirdParty/sdk/Include/core/c99/stdbool.h b/Source/ThirdParty/sdk/Include/core/c99/stdbool.h index c005f8a..4d4c8f9 100644 --- a/Source/ThirdParty/sdk/Include/core/c99/stdbool.h +++ b/Source/ThirdParty/sdk/Include/core/c99/stdbool.h @@ -5,6 +5,10 @@ #define false 0 #define true 1 +#ifdef PUBNUB_BOOL_TYPE +#define bool PUBNUB_BOOL_TYPE +#else #define bool int +#endif -#endif /* !defined __cplusplus */ \ No newline at end of file +#endif /* !defined __cplusplus */ diff --git a/Source/ThirdParty/sdk/Include/core/pbcc_actions_api.c b/Source/ThirdParty/sdk/Include/core/pbcc_actions_api.c index 5cd52a2..b1400f3 100644 --- a/Source/ThirdParty/sdk/Include/core/pbcc_actions_api.c +++ b/Source/ThirdParty/sdk/Include/core/pbcc_actions_api.c @@ -17,17 +17,45 @@ /* Maximum number of actions to return in response */ #define MAX_ACTIONS_LIMIT 100 +#define MAX_ACTION_TYPE_LENGTH 15 enum pubnub_res pbcc_form_the_action_object(struct pbcc_context* pb, char* obj_buffer, size_t buffer_size, enum pubnub_action_type actype, - char const** val) -{ - char const* user_id = pbcc_user_id_get(pb); + char const** val) { char const* type_literal; + switch(actype) { + case pbactypReaction: + type_literal = "\"reaction\""; + break; + case pbactypReceipt: + type_literal = "\"receipt\""; + break; + case pbactypCustom: + type_literal = "\"custom\""; + break; + default: + PUBNUB_LOG_ERROR("pbcc_form_the_action_object(pbcc=%p) - " + "unknown action type = %d\n", + pb, + actype); + return PNR_INVALID_PARAMETERS; + } + + return pbcc_form_the_action_object_str(pb, obj_buffer, buffer_size, type_literal, val); +} + + +enum pubnub_res pbcc_form_the_action_object_str(struct pbcc_context* pb, + char* obj_buffer, + size_t buffer_size, + char const* action_type, + char const** val) { + char const* user_id = pbcc_user_id_get(pb); + PUBNUB_ASSERT_OPT(user_id != NULL); if (NULL == user_id) { @@ -42,25 +70,17 @@ enum pubnub_res pbcc_form_the_action_object(struct pbcc_context* pb, *val); return PNR_INVALID_PARAMETERS; } - switch(actype) { - case pbactypReaction: - type_literal = "reaction"; - break; - case pbactypReceipt: - type_literal = "receipt"; - break; - case pbactypCustom: - type_literal = "custom"; - break; - default: + if (('\"' != *action_type) || ('\"' != *(action_type + pb_strnlen_s(action_type, MAX_ACTION_TYPE_LENGTH) - 1))) { PUBNUB_LOG_ERROR("pbcc_form_the_action_object(pbcc=%p) - " - "unknown action type = %d\n", + "quotation marks on action type ends are missing: " + "action_type = %s\n", pb, - actype); + action_type); return PNR_INVALID_PARAMETERS; } + if (buffer_size < sizeof("{\"type\":\"\",\"value\":,\"user_id\":\"\"}") + - pb_strnlen_s(type_literal, sizeof "reaction") + + pb_strnlen_s(action_type, MAX_ACTION_TYPE_LENGTH) + pb_strnlen_s(*val, PUBNUB_MAX_OBJECT_LENGTH) + pb->user_id_len) { PUBNUB_LOG_ERROR("pbcc_form_the_action_object(pbcc=%p) - " @@ -70,15 +90,15 @@ enum pubnub_res pbcc_form_the_action_object(struct pbcc_context* pb, pb, (unsigned long)buffer_size, (unsigned long)(sizeof("{\"type\":\"\",\"value\":,\"user_id\":\"\"}") + - pb_strnlen_s(type_literal, sizeof "reaction") + + pb_strnlen_s(action_type, MAX_ACTION_TYPE_LENGTH) + pb_strnlen_s(*val, PUBNUB_MAX_OBJECT_LENGTH) + pb->user_id_len)); return PNR_TX_BUFF_TOO_SMALL; } snprintf(obj_buffer, buffer_size, - "{\"type\":\"%s\",\"value\":%s,\"user_id\":\"%s\"}", - type_literal, + "{\"type\":%s,\"value\":%s,\"user_id\":\"%s\"}", + action_type, *val, user_id); *val = obj_buffer; diff --git a/Source/ThirdParty/sdk/Include/core/pbcc_actions_api.h b/Source/ThirdParty/sdk/Include/core/pbcc_actions_api.h index b5c0cae..21b5d62 100644 --- a/Source/ThirdParty/sdk/Include/core/pbcc_actions_api.h +++ b/Source/ThirdParty/sdk/Include/core/pbcc_actions_api.h @@ -7,6 +7,7 @@ #include "pubnub_api_types.h" #include "pubnub_memory_block.h" +#include "lib/pb_deprecated.h" struct pbcc_context; @@ -25,14 +26,30 @@ enum pubnub_action_type { }; /** Forms the action object to be sent in 'pubnub_add_action' request body. + + @deprecated This function is deprecated. Use pbcc_form_the_action_object_str() instead. + The present declaration will be changed to the string version in the future. + @see pbcc_form_the_action_object_str + @return #PNR_OK on success, an error otherwise */ -enum pubnub_res pbcc_form_the_action_object(struct pbcc_context* pb, +PUBNUB_DEPRECATED enum pubnub_res pbcc_form_the_action_object(struct pbcc_context* pb, char* obj_buffer, size_t buffer_size, enum pubnub_action_type actype, char const** json); + +/** Forms the action object to be sent in 'pubnub_add_action' request body. + @return #PNR_OK on success, an error otherwise + */ +enum pubnub_res pbcc_form_the_action_object_str(struct pbcc_context* pb, + char* obj_buffer, + size_t buffer_size, + const char* action_type, + char const** json); + + /** Prepares the 'add_action' transaction, mostly by formatting the URI of the HTTP request. */ diff --git a/Source/ThirdParty/sdk/Include/core/pbcc_advanced_history.c b/Source/ThirdParty/sdk/Include/core/pbcc_advanced_history.c index 8f62e72..7fb1648 100644 --- a/Source/ThirdParty/sdk/Include/core/pbcc_advanced_history.c +++ b/Source/ThirdParty/sdk/Include/core/pbcc_advanced_history.c @@ -10,6 +10,7 @@ #include "pubnub_url_encode.h" #include "pubnub_assert.h" +#include "pubnub_helper.h" #include "pubnub_log.h" #else #error this module can only be used if PUBNUB_USE_ADVANCED_HISTORY is defined and set to 1 @@ -543,3 +544,131 @@ enum pubnub_res pbcc_message_counts_prep( PUBNUB_LOG_DEBUG("pbcc_message_counts_prep. REQUEST =%s\n", p->http_buf); return (rslt != PNR_OK) ? rslt : PNR_STARTED; } + +enum pubnub_res pbcc_delete_messages_prep(struct pbcc_context* pb, + char const* channel, + char const* start, + char const* end) +{ + char const* const uname = pubnub_uname(); + char const* user_id = pbcc_user_id_get(pb); +#if PUBNUB_CRYPTO_API + enum pubnub_res rslt = PNR_OK; +#endif + + PUBNUB_ASSERT_OPT(NULL != user_id); + + pb->msg_ofs = pb->msg_end = 0; + pb->http_content_len = 0; + + pb->http_buf_len = + snprintf(pb->http_buf, + sizeof pb->http_buf, + "/v3/history/sub-key/%s/channel/", + pb->subscribe_key); + APPEND_URL_ENCODED_M(pb, channel); + + URL_PARAMS_INIT(qparam, PUBNUB_MAX_URL_PARAMS); + if (uname) { ADD_URL_PARAM(qparam, pnsdk, uname); } + ADD_URL_PARAM(qparam, uuid, user_id); +#if PUBNUB_CRYPTO_API + if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } + ADD_TS_TO_URL_PARAM(); +#else + ADD_URL_AUTH_PARAM(pb, qparam, auth); +#endif + if (start) { ADD_URL_PARAM(qparam, start, start); } + if (end) { ADD_URL_PARAM(qparam, end, end); } + +#if PUBNUB_CRYPTO_API + SORT_URL_PARAMETERS(qparam); +#endif + ENCODE_URL_PARAMETERS(pb, qparam); +#if PUBNUB_CRYPTO_API + if (pb->secret_key != NULL) { + rslt = pbcc_sign_url(pb, "", pubnubSendViaGET, true); + } +#endif + + PUBNUB_LOG_DEBUG("pbcc_delete_messages_prep. REQUEST =%s\n", pb->http_buf); +#if PUBNUB_CRYPTO_API + return (rslt != PNR_OK) ? rslt : PNR_STARTED; +#else + return PNR_STARTED; +#endif +} + +pubnub_chamebl_t pbcc_get_delete_messages_response(struct pbcc_context* pb) +{ + pubnub_chamebl_t resp; + char const* reply = pb->http_reply; + int reply_len = pb->http_buf_len; + + if (PNR_OK != pb->last_result) { + PUBNUB_LOG_ERROR("pbcc_get_delete_messages_response(pb=%p) can be " + "called only if previous transactin " + "PBTT_DELETE_MESSAGES(%d) is finished successfully. " + "Transaction result was: %d('%s')\n", + pb, + PBTT_DELETE_MESSAGES, + pb->last_result, + pubnub_res_2_string(pb->last_result)); + resp.ptr = NULL; + resp.size = 0; + return resp; + } + + resp.ptr = (char*)reply; + resp.size = reply_len; + return resp; +} + +enum pubnub_res pbcc_parse_delete_messages_response(struct pbcc_context* pb) +{ + enum pbjson_object_name_parse_result jpresult; + struct pbjson_elem el; + struct pbjson_elem found; + char* reply = pb->http_reply; + int reply_len = pb->http_buf_len; + + if ((reply[0] != '{') || (reply[reply_len - 1] != '}')) { + PUBNUB_LOG_ERROR( + "Error: pbcc_parse_delete_messages_response(pbcc=%p) - " + "Response is not json object: response='%.*s'\n", + pb, + reply_len, + reply); + return PNR_FORMAT_ERROR; + } + el.start = reply; + el.end = reply + reply_len; + if (pbjson_value_for_field_found(&el, "status", "403")) { + PUBNUB_LOG_ERROR( + "Error: pbcc_parse_delete_messages_response(pbcc=%p) - " + "Access Denied: response='%.*s'\n", + pb, + reply_len, + reply); + return PNR_ACCESS_DENIED; + } + jpresult = pbjson_get_object_value(&el, "error", &found); + if (jonmpOK == jpresult) { + if (pbjson_elem_equals_string(&found, "true")) { + return PNR_ERROR_ON_SERVER; + } + } + else { + PUBNUB_LOG_ERROR( + "Error: pbcc_parse_delete_messages_response(pbcc=%p) - " + "'error' atribute not found in the response. error=%d\n" + "response='%.*s'\n", + pb, + jpresult, + reply_len, + reply); + return PNR_FORMAT_ERROR; + } + pb->chan_ofs = pb->chan_end = 0; + + return PNR_OK; +} \ No newline at end of file diff --git a/Source/ThirdParty/sdk/Include/core/pbcc_advanced_history.h b/Source/ThirdParty/sdk/Include/core/pbcc_advanced_history.h index 958bb6a..37340a0 100644 --- a/Source/ThirdParty/sdk/Include/core/pbcc_advanced_history.h +++ b/Source/ThirdParty/sdk/Include/core/pbcc_advanced_history.h @@ -70,6 +70,43 @@ enum pubnub_res pbcc_message_counts_prep( char const* channel, char const* timetoken, char const* channel_timetokens); + +/** + * @brief Prepare `delete messages` operation (transaction), mostly by + * formatting the URI of the HTTP request. + * + * @param pb PubNub context which provides resources to send request. + * @param channel Channel from which messages should be deleted. + * @param start Timetoken delimiting the start of time slice (exclusive) to + * delete messages from. + * @param end Timetoken delimiting the end of time slice (inclusive) to + * delete messages to. + * @return Results of `delete messages` transaction call. + */ +enum pubnub_res pbcc_delete_messages_prep(struct pbcc_context* pb, + char const* channel, + char const* start, + char const* end); + +/** + * @brief Get `delete messages` service response. + * + * @param pb PubNub context which has been used to delete channel messages. + * @return `pubnub_chamebl_t` with pointer to string with response. + */ +pubnub_chamebl_t pbcc_get_delete_messages_response(struct pbcc_context* pb); + + + +/** + * @brief Parses the string received as a response for a history v3 + * operation (transaction). + * + * @param pb PubNub context to parse delete channel messages response. + * @return PNR_OK: OK, !PNR_OK: error (invalid response) +*/ +enum pubnub_res pbcc_parse_delete_messages_response(struct pbcc_context* pb); + #endif /* INC_PBCC_ADVANCED_HISTORY */ #endif /* PUBNUB_USE_ADVANCED_HISTORY */ diff --git a/Source/ThirdParty/sdk/Include/core/pbcc_crypto.c b/Source/ThirdParty/sdk/Include/core/pbcc_crypto.c index e1a9049..c0e8b83 100644 --- a/Source/ThirdParty/sdk/Include/core/pbcc_crypto.c +++ b/Source/ThirdParty/sdk/Include/core/pbcc_crypto.c @@ -288,3 +288,54 @@ void pbcc_set_crypto_module(struct pbcc_context *ctx, struct pubnub_crypto_provi pubnub_crypto_provider_t *pbcc_get_crypto_module(struct pbcc_context *ctx) { return ctx->crypto_module; } + +#if PUBNUB_CRYPTO_API +const char* pbcc_decrypt_message(struct pbcc_context *pb, const char* message, size_t len, size_t* out_len) { + char* trimmed = (char*)malloc(len + 1); // same length as message + if (NULL == trimmed) { + PUBNUB_LOG_ERROR("pbcc_get_msg(pbcc=%p) - failed to allocate memory for trimmed string. Returning original message!\n", pb); + return NULL; + } + snprintf(trimmed, len + 1, "%s", message); + + trimmed[strlen(trimmed) - 1] = '\0'; + + pubnub_bymebl_t encrypted = pbcc_base64_decode(trimmed + 1); + free(trimmed); + + if (NULL == encrypted.ptr) { + PUBNUB_LOG_WARNING("pbcc_get_msg(pbcc=%p) - base64 decoding failed. Returning original message!\n", pb); + if (NULL != out_len) { + *out_len = strlen(message); + } + return message; + } + + pubnub_bymebl_t rslt_block = pb->crypto_module->decrypt(pb->crypto_module, encrypted); + free(encrypted.ptr); + if (NULL == rslt_block.ptr) { + PUBNUB_LOG_WARNING("pbcc_get_msg(pbcc=%p) - decryption failed. Returning original message!\n", pb); + if (NULL != out_len) { + *out_len = strlen(message); + } + return message; + } + + if (pb->decrypted_message_count >= PUBNUB_MAX_DECRYPTED_MESSAGES) { + PUBNUB_LOG_ERROR("pbcc_get_msg(pbcc=%p) - maximum number of decrypted messages reached. Returning original message!\n", pb); + if (NULL != out_len) { + *out_len = 0; + } + return NULL; + } + + pb->decrypted_messages[pb->decrypted_message_count] = rslt_block.ptr; + pb->decrypted_message_count++; + + if (NULL != out_len) { + *out_len = rslt_block.size; + } + + return (char*)rslt_block.ptr; +} +#endif /* PUBNUB_CRYPTO_API */ diff --git a/Source/ThirdParty/sdk/Include/core/pbcc_crypto.h b/Source/ThirdParty/sdk/Include/core/pbcc_crypto.h index 1ac89e6..90fae34 100644 --- a/Source/ThirdParty/sdk/Include/core/pbcc_crypto.h +++ b/Source/ThirdParty/sdk/Include/core/pbcc_crypto.h @@ -293,6 +293,21 @@ void pbcc_set_crypto_module(struct pbcc_context *ctx, struct pubnub_crypto_provi @return Pointer to the crypto provider used by the pubnub context. */ pubnub_crypto_provider_t *pbcc_get_crypto_module(struct pbcc_context *ctx); + +#if PUBNUB_CRYPTO_API +/** + Decrypt the message received from PubNub with the crypto module. + + This function takes the message received from PubNub and decrypts it + for the user. It uses the crypto module used by the pubnub context. + + @param pubnub Pointer to the pubnub context. + @param message The message received from PubNub. + + @return The decrypted message or NULL on error. +*/ +const char* pbcc_decrypt_message(struct pbcc_context *ctx, const char* message, size_t len, size_t* out_len); +#endif /* PUBNUB_CRYPTO_API */ #endif /* PBCC_CRYPTO_H */ diff --git a/Source/ThirdParty/sdk/Include/core/pbcc_crypto_legacy.c b/Source/ThirdParty/sdk/Include/core/pbcc_crypto_legacy.c index ea4d12a..adbca8f 100644 --- a/Source/ThirdParty/sdk/Include/core/pbcc_crypto_legacy.c +++ b/Source/ThirdParty/sdk/Include/core/pbcc_crypto_legacy.c @@ -55,7 +55,11 @@ static size_t estimated_enc_buffer_size(size_t n) { } static size_t estimated_dec_buffer_size(size_t n) { - return n + 1; // for the terminating array + // In most cases formula (n + 1) is enough to + // handle the amount of decrypted bytes. + // Addition AES_BLOCK_SIZE just to be sure if message + // contains very specific padding. + return n + AES_BLOCK_SIZE + 1; } static int legacy_encrypt( diff --git a/Source/ThirdParty/sdk/Include/core/pbcc_fetch_history.c b/Source/ThirdParty/sdk/Include/core/pbcc_fetch_history.c index 90d0666..24b45a6 100644 --- a/Source/ThirdParty/sdk/Include/core/pbcc_fetch_history.c +++ b/Source/ThirdParty/sdk/Include/core/pbcc_fetch_history.c @@ -58,16 +58,16 @@ enum pubnub_res pbcc_fetch_history_prep(struct pbcc_context* pb, sprintf(max_per_ch_cnt_buf, "%d", max_per_channel); if (max_per_channel) { ADD_URL_PARAM(qparam, max, max_per_ch_cnt_buf); } - if (include_meta != pbccNotSet) { ADD_URL_PARAM(qparam, include_meta, include_meta == pbccTrue ? "1" : "0"); } - if (include_message_type != pbccNotSet) { ADD_URL_PARAM(qparam, include_message_type, include_meta == pbccTrue ? "1" : "0"); } - if (include_user_id != pbccNotSet) { ADD_URL_PARAM(qparam, include_uuid, include_user_id == pbccTrue ? "1" : "0"); } + if (include_meta != pbccNotSet) { ADD_URL_PARAM(qparam, include_meta, include_meta == pbccTrue ? "true" : "false"); } + if (include_message_type != pbccNotSet) { ADD_URL_PARAM(qparam, include_message_type, include_meta == pbccTrue ? "true" : "false"); } + if (include_user_id != pbccNotSet) { ADD_URL_PARAM(qparam, include_uuid, include_user_id == pbccTrue ? "true" : "false"); } #if PUBNUB_CRYPTO_API if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } ADD_TS_TO_URL_PARAM(); #else ADD_URL_AUTH_PARAM(pb, qparam, auth); #endif - if (reverse != pbccNotSet) { ADD_URL_PARAM(qparam, reverse, reverse == pbccTrue ? "1" : "0"); } + if (reverse != pbccNotSet) { ADD_URL_PARAM(qparam, reverse, reverse == pbccTrue ? "true" : "false"); } if (start) { ADD_URL_PARAM(qparam, start, start); } if (end) { ADD_URL_PARAM(qparam, end, end); } diff --git a/Source/ThirdParty/sdk/Include/core/pbcc_objects_api.c b/Source/ThirdParty/sdk/Include/core/pbcc_objects_api.c index 68f64c3..c81d61b 100644 --- a/Source/ThirdParty/sdk/Include/core/pbcc_objects_api.c +++ b/Source/ThirdParty/sdk/Include/core/pbcc_objects_api.c @@ -77,6 +77,8 @@ enum pubnub_res pbcc_getall_uuidmetadata_prep( char const* start, char const* end, enum pubnub_tribool count, + char const* filter, + char const* sort, enum pubnub_trans pt) { char const* const uname = pubnub_uname(); @@ -102,6 +104,9 @@ enum pubnub_res pbcc_getall_uuidmetadata_prep( if (count != pbccNotSet) { ADD_URL_PARAM(qparam, count, count == pbccTrue ? "true" : "false"); } + if (NULL != filter) { ADD_URL_PARAM(qparam, filter, filter); } + if (NULL != sort) { ADD_URL_PARAM(qparam, sort, sort); } + if (user_id) { ADD_URL_PARAM(qparam, uuid, user_id); } #if PUBNUB_CRYPTO_API if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } @@ -292,6 +297,8 @@ enum pubnub_res pbcc_getall_channelmetadata_prep(struct pbcc_context* pb, char const* start, char const* end, enum pubnub_tribool count, + char const* filter, + char const* sort, enum pubnub_trans pt) { char const* const uname = pubnub_uname(); @@ -316,6 +323,10 @@ enum pubnub_res pbcc_getall_channelmetadata_prep(struct pbcc_context* pb, if (end != NULL) { ADD_URL_PARAM(qparam, end, end); } if (count != pbccNotSet) { ADD_URL_PARAM(qparam, count, count == pbccTrue ? "true" : "false"); } + + if (NULL != filter) { ADD_URL_PARAM(qparam, filter, filter); } + if (NULL != sort) { ADD_URL_PARAM(qparam, sort, sort); } + if (user_id) { ADD_URL_PARAM(qparam, uuid, user_id); } #if PUBNUB_CRYPTO_API if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } @@ -515,6 +526,8 @@ enum pubnub_res pbcc_get_memberships_prep(struct pbcc_context* pb, char const* start, char const* end, enum pubnub_tribool count, + char const* filter, + char const* sort, enum pubnub_trans pt) { char const* const uname = pubnub_uname(); @@ -542,6 +555,10 @@ enum pubnub_res pbcc_get_memberships_prep(struct pbcc_context* pb, if (start) { ADD_URL_PARAM(qparam, start, start); } if (end) { ADD_URL_PARAM(qparam, end, end); } if (count != pbccNotSet) { ADD_URL_PARAM(qparam, count, count == pbccTrue ? "true" : "false"); } + + if (NULL != filter) { ADD_URL_PARAM(qparam, filter, filter); } + if (NULL != sort) { ADD_URL_PARAM(qparam, sort, sort); } + if (user_id) { ADD_URL_PARAM(qparam, uuid, user_id); } #if PUBNUB_CRYPTO_API if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } @@ -574,6 +591,12 @@ enum pubnub_res pbcc_set_memberships_prep(struct pbcc_context* pb, char const* uuid_metadataid, char const* include, char const* set_obj, + char const* filter, + char const* sort, + size_t limit, + char const* start, + char const* end, + enum pubnub_tribool count, enum pubnub_trans pt) { char const* const uname = pubnub_uname(); @@ -598,6 +621,16 @@ enum pubnub_res pbcc_set_memberships_prep(struct pbcc_context* pb, URL_PARAMS_INIT(qparam, PUBNUB_MAX_URL_PARAMS); if (uname) { ADD_URL_PARAM(qparam, pnsdk, uname); } if (user_id) { ADD_URL_PARAM(qparam, uuid, user_id); } + + if (limit > 0) { ADD_URL_PARAM_SIZET(qparam, limit, limit); } + if (NULL != start) { ADD_URL_PARAM(qparam, start, start); } + if (NULL != end) { ADD_URL_PARAM(qparam, end, end); } + + if (count != pbccNotSet) { ADD_URL_PARAM(qparam, count, count == pbccTrue ? "true" : "false"); } + + if (NULL != filter) { ADD_URL_PARAM(qparam, filter, filter); } + if (NULL != sort) { ADD_URL_PARAM(qparam, sort, sort); } + #if PUBNUB_CRYPTO_API if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } ADD_TS_TO_URL_PARAM(); @@ -633,6 +666,8 @@ enum pubnub_res pbcc_get_members_prep(struct pbcc_context* pb, size_t limit, char const* start, char const* end, + char const* filter, + char const* sort, enum pubnub_tribool count, enum pubnub_trans pt) { @@ -663,6 +698,10 @@ enum pubnub_res pbcc_get_members_prep(struct pbcc_context* pb, if (start) { ADD_URL_PARAM(qparam, start, start); } if (end) { ADD_URL_PARAM(qparam, end, end); } if (count != pbccNotSet) { ADD_URL_PARAM(qparam, count, count == pbccTrue ? "true" : "false"); } + + if (NULL != filter) { ADD_URL_PARAM(qparam, filter, filter); } + if (NULL != sort) { ADD_URL_PARAM(qparam, sort, sort); } + if (user_id) { ADD_URL_PARAM(qparam, uuid, user_id); } #if PUBNUB_CRYPTO_API if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } @@ -695,6 +734,12 @@ enum pubnub_res pbcc_set_members_prep(struct pbcc_context* pb, char const* channel_metadataid, char const* include, char const* set_obj, + char const* filter, + char const* sort, + size_t limit, + char const* start, + char const* end, + enum pubnub_tribool count, enum pubnub_trans pt) { char const* const uname = pubnub_uname(); @@ -720,6 +765,15 @@ enum pubnub_res pbcc_set_members_prep(struct pbcc_context* pb, URL_PARAMS_INIT(qparam, PUBNUB_MAX_URL_PARAMS); if (uname) { ADD_URL_PARAM(qparam, pnsdk, uname); } if (user_id) { ADD_URL_PARAM(qparam, uuid, user_id); } + + if (limit > 0) { ADD_URL_PARAM_SIZET(qparam, limit, limit); } + if (NULL != start) { ADD_URL_PARAM(qparam, start, start); } + if (NULL != end) { ADD_URL_PARAM(qparam, end, end); } + + if (count != pbccNotSet) { ADD_URL_PARAM(qparam, count, count == pbccTrue ? "true" : "false"); } + + if (NULL != filter) { ADD_URL_PARAM(qparam, filter, filter); } + if (NULL != sort) { ADD_URL_PARAM(qparam, sort, sort); } #if PUBNUB_CRYPTO_API if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } ADD_TS_TO_URL_PARAM(); diff --git a/Source/ThirdParty/sdk/Include/core/pbcc_objects_api.h b/Source/ThirdParty/sdk/Include/core/pbcc_objects_api.h index 5557928..ab64f02 100644 --- a/Source/ThirdParty/sdk/Include/core/pbcc_objects_api.h +++ b/Source/ThirdParty/sdk/Include/core/pbcc_objects_api.h @@ -26,6 +26,8 @@ enum pubnub_res pbcc_find_objects_id(struct pbcc_context* pb, char const* file, int line); +// TODO: maybe we should decrease amount of parameters in these functions + /** Prepares the 'get_users' transaction, mostly by formatting the URI of the HTTP request. */ @@ -35,6 +37,8 @@ enum pubnub_res pbcc_getall_uuidmetadata_prep(struct pbcc_context* pb, char const* start, char const* end, enum pubnub_tribool count, + char const* filter, + char const* sort, enum pubnub_trans pt); /** Prepares the 'set_uuidmetadata' transaction, mostly by @@ -70,6 +74,8 @@ enum pubnub_res pbcc_getall_channelmetadata_prep(struct pbcc_context* pb, char const* start, char const* end, enum pubnub_tribool count, + char const* filter, + char const* sort, enum pubnub_trans pt); @@ -108,6 +114,8 @@ enum pubnub_res pbcc_get_memberships_prep(struct pbcc_context* pb, char const* start, char const* end, enum pubnub_tribool count, + char const* filter, + char const* sort, enum pubnub_trans pt); @@ -118,6 +126,12 @@ enum pubnub_res pbcc_set_memberships_prep(struct pbcc_context* pb, char const* uuid_metadataid, char const* include, char const* update_obj, + char const* filter, + char const* sort, + size_t limit, + char const* start, + char const* end, + enum pubnub_tribool count, enum pubnub_trans pt); /** Prepares the 'get_members' transaction, mostly by @@ -129,6 +143,8 @@ enum pubnub_res pbcc_get_members_prep(struct pbcc_context* pb, size_t limit, char const* start, char const* end, + char const* filter, + char const* sort, enum pubnub_tribool count, enum pubnub_trans pt); @@ -139,6 +155,12 @@ enum pubnub_res pbcc_set_members_prep(struct pbcc_context* pb, char const* channel_metadataid, char const* include, char const* set_obj, + char const* filter, + char const* sort, + size_t limit, + char const* start, + char const* end, + enum pubnub_tribool count, enum pubnub_trans pt); diff --git a/Source/ThirdParty/sdk/Include/core/pbcc_set_state.c b/Source/ThirdParty/sdk/Include/core/pbcc_set_state.c index 5670633..d0453bc 100644 --- a/Source/ThirdParty/sdk/Include/core/pbcc_set_state.c +++ b/Source/ThirdParty/sdk/Include/core/pbcc_set_state.c @@ -70,8 +70,7 @@ void pbcc_adjust_state(struct pbcc_context* core, if (ch_len == 0) { continue; } char* curr_ch = (char*)malloc(ch_len + 1); - strncpy(curr_ch, str_ch, ch_len); - curr_ch[ch_len] = '\0'; + strcpy(curr_ch, str_ch); mem_len = json_kvp_builder(json_state, mem_len, curr_ch, (char*)state); @@ -98,8 +97,7 @@ void pbcc_adjust_state(struct pbcc_context* core, if (cg_len == 0) { continue; } char* curr_cg = (char*)malloc(cg_len + 1); - strncpy(curr_cg, str_cg, cg_len); - curr_cg[cg_len] = '\0'; + strcpy(curr_cg, str_cg); mem_len = json_kvp_builder(json_state, mem_len, curr_cg, (char*)state); diff --git a/Source/ThirdParty/sdk/Include/core/pbcc_subscribe_v2.c b/Source/ThirdParty/sdk/Include/core/pbcc_subscribe_v2.c index 09a3d5d..90b2e36 100644 --- a/Source/ThirdParty/sdk/Include/core/pbcc_subscribe_v2.c +++ b/Source/ThirdParty/sdk/Include/core/pbcc_subscribe_v2.c @@ -1,5 +1,6 @@ /* -*- c-file-style:"stroustrup"; indent-tabs-mode: nil -*- */ +#include "pbcc_crypto.h" #if PUBNUB_USE_SUBSCRIBE_V2 #include "pubnub_internal.h" @@ -55,6 +56,13 @@ enum pubnub_res pbcc_subscribe_v2_prep(struct pbcc_context* p, p->http_content_len = 0; p->msg_ofs = p->msg_end = 0; +#if PUBNUB_CRYPTO_API + for (size_t i = 0; i < p->decrypted_message_count; i++) { + free(p->decrypted_messages[i]); + } + p->decrypted_message_count = 0; +#endif + p->http_buf_len = snprintf( p->http_buf, sizeof p->http_buf, "/v2/subscribe/%s/", p->subscribe_key); APPEND_URL_ENCODED_M(p, channel); @@ -80,7 +88,7 @@ enum pubnub_res pbcc_subscribe_v2_prep(struct pbcc_context* p, #endif if (filter_expr) { ADD_URL_PARAM(qparam, filter-expr, filter_expr); } - if (heartbeat) { ADD_URL_PARAM_SIZET(qparam, heartbeat, (unsigned long)*heartbeat); } + if (heartbeat) { ADD_URL_PARAM_SIZET(qparam, heartbeat, (size_t)*heartbeat); } #if PUBNUB_CRYPTO_API SORT_URL_PARAMETERS(qparam); @@ -212,12 +220,15 @@ struct pubnub_v2_message pbcc_get_msg_v2(struct pbcc_context* p) } PUBNUB_LOG_DEBUG("RESPONSE = %s\n", p->http_reply); start = p->http_reply + p->msg_ofs; + if (*start != '{') { PUBNUB_LOG_ERROR( "Message subscribe V2 response is not a JSON object\n"); return rslt; } + end = p->http_reply + p->msg_end; + seeker = pbjson_find_end_complex(start, end); if (seeker == end) { PUBNUB_LOG_ERROR( @@ -235,8 +246,19 @@ struct pubnub_v2_message pbcc_get_msg_v2(struct pbcc_context* p) jpresult = pbjson_get_object_value(&el, "d", &found); if (jonmpOK == jpresult) { +#if PUBNUB_CRYPTO_API + if (NULL != p->crypto_module) { + rslt.payload.ptr = (char*)pbcc_decrypt_message( + p, + (char*)found.start, + found.end - found.start, + &rslt.payload.size + ); + } +#else rslt.payload.ptr = (char*)found.start; rslt.payload.size = found.end - found.start; +#endif /* PUBNUB_CRYPTO_API */ } else { PUBNUB_LOG_ERROR("pbcc=%p: No message payload in subscribe V2 response " diff --git a/Source/ThirdParty/sdk/Include/core/pbgzip_compress.c b/Source/ThirdParty/sdk/Include/core/pbgzip_compress.c index 78ab08d..e7f8319 100644 --- a/Source/ThirdParty/sdk/Include/core/pbgzip_compress.c +++ b/Source/ThirdParty/sdk/Include/core/pbgzip_compress.c @@ -128,7 +128,7 @@ enum pubnub_res pbgzip_compress(pubnub_t* pb, char const* message) /* flags: no file_name, no f_extras, no f_comment, no f_hcrc */ memset(data + 3, '\0', 7); size = strlen(message); - PUBNUB_LOG_TRACE("pbgzip_compress(pb=%p) - Length before compression:%lu bytes\n", pb, size); + PUBNUB_LOG_TRACE("pbgzip_compress(pb=%p) - Length before compression:%lu bytes\n", pb, (long unsigned int)size); return deflate_total_to_context_buffer(pb, message, size); } diff --git a/Source/ThirdParty/sdk/Include/core/pbhttp_digest.c b/Source/ThirdParty/sdk/Include/core/pbhttp_digest.c index 1eb88ba..4c731e0 100644 --- a/Source/ThirdParty/sdk/Include/core/pbhttp_digest.c +++ b/Source/ThirdParty/sdk/Include/core/pbhttp_digest.c @@ -267,7 +267,7 @@ int pbhttp_digest_prep_header_to_send(struct pbhttp_digest_context* ctx, if (pbhtdigqopNone != ctx->qop) { char const* qop_str = pbhttp_digest_qop2str(ctx->qop); char nonce_count_str[9]; - snprintf(nonce_count_str, sizeof nonce_count_str, "%08x", ctx->nc); + snprintf(nonce_count_str, sizeof nonce_count_str, "%08lx", (long unsigned int)ctx->nc); pbmd5_update(&md5, ":", 1); pbmd5_update(&md5, nonce_count_str, sizeof nonce_count_str - 1); pbmd5_update(&md5, ":", 1); @@ -302,7 +302,7 @@ int pbhttp_digest_prep_header_to_send(struct pbhttp_digest_context* ctx, snprintf(buf->ptr, buf->size, "username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", " - "cnonce=\"%s\", nc=\"%08x\", qop=\"%s\", response=\"%s\"" + "cnonce=\"%s\", nc=\"%08lx\", qop=\"%s\", response=\"%s\"" "%s%s" "%s%s", username, @@ -310,7 +310,7 @@ int pbhttp_digest_prep_header_to_send(struct pbhttp_digest_context* ctx, ctx->nonce, uri, ctx->client_nonce, - ctx->nc, + (long unsigned int)ctx->nc, pbhttp_digest_qop2str(ctx->qop), response, (ctx->opaque[0] == '\0' ? "" : ", opaque="), diff --git a/Source/ThirdParty/sdk/Include/core/pubnub_actions_api.c b/Source/ThirdParty/sdk/Include/core/pubnub_actions_api.c index af1c9e8..4850524 100644 --- a/Source/ThirdParty/sdk/Include/core/pubnub_actions_api.c +++ b/Source/ThirdParty/sdk/Include/core/pubnub_actions_api.c @@ -17,12 +17,40 @@ #include -enum pubnub_res pubnub_add_message_action(pubnub_t* pb, +enum pubnub_res pubnub_add_message_action(pubnub_t *pb, + const char *channel, + const char *message_timetoken, + enum pubnub_action_type actype, + const char *value) { + char const* type_literal; + + switch(actype) { + case pbactypReaction: + type_literal = "\"reaction\""; + break; + case pbactypReceipt: + type_literal = "\"receipt\""; + break; + case pbactypCustom: + type_literal = "\"custom\""; + break; + default: + PUBNUB_LOG_ERROR("pubnub_add_message_action(pbcc=%p) - " + "unknown action type = %d\n", + pb, + actype); + return PNR_INVALID_PARAMETERS; + } + + return pubnub_add_message_action_str(pb, channel, message_timetoken, type_literal, value); +} + + +enum pubnub_res pubnub_add_message_action_str(pubnub_t* pb, char const* channel, char const* message_timetoken, - enum pubnub_action_type actype, - char const* value) -{ + char const* actype, + char const* value) { enum pubnub_res rslt; char obj_buffer[PUBNUB_BUF_MAXLEN]; @@ -34,7 +62,7 @@ enum pubnub_res pubnub_add_message_action(pubnub_t* pb, pubnub_mutex_unlock(pb->monitor); return PNR_IN_PROGRESS; } - rslt = pbcc_form_the_action_object(&pb->core, + rslt = pbcc_form_the_action_object_str(&pb->core, obj_buffer, sizeof obj_buffer, actype, diff --git a/Source/ThirdParty/sdk/Include/core/pubnub_actions_api.h b/Source/ThirdParty/sdk/Include/core/pubnub_actions_api.h index 47abbfc..22cc6f5 100644 --- a/Source/ThirdParty/sdk/Include/core/pubnub_actions_api.h +++ b/Source/ThirdParty/sdk/Include/core/pubnub_actions_api.h @@ -7,6 +7,7 @@ #include "lib/pb_extern.h" #include "pbcc_actions_api.h" +#include "lib/pb_deprecated.h" #include @@ -18,6 +19,12 @@ If the transaction is finished successfully response will have 'data' field with added action data. If there is no data, nor error description in the response, response parsing function returns format error. + + @deprecated This function is deprecated. Use pubnub_add_message_action_str() instead. + The present declaration will be changed to the string version in the future. + @see pubnub_add_message_action_str() + @see pbcc_action_type_to_str + @param pb The pubnub context. Can't be NULL @param channel The channel on which action is referring to. @param message_timetoken The timetoken(unquoted) of a published message action is @@ -26,13 +33,39 @@ @param value Json string describing the action that is to be added @return #PNR_STARTED on success, an error otherwise */ -PUBNUB_EXTERN enum pubnub_res pubnub_add_message_action(pubnub_t* pb, +PUBNUB_EXTERN PUBNUB_DEPRECATED enum pubnub_res pubnub_add_message_action(pubnub_t* pb, char const* channel, char const* message_timetoken, enum pubnub_action_type actype, char const* value); +/** Adds new type of message called action as a support for user reactions on a published + messages. + Json string @p value is checked for its quotation marks at its ends. If any of the + quotation marks is missing function returns parameter error. + If the transaction is finished successfully response will have 'data' field with + added action data. If there is no data, nor error description in the response, + response parsing function returns format error. + + @deprecated This function is deprecated. Use pubnub_add_message_action_str() instead. + @see pubnub_add_message_action_str() + + @param pb The pubnub context. Can't be NULL + @param channel The channel on which action is referring to. + @param message_timetoken The timetoken(unquoted) of a published message action is + applying to + @param action_type Jsoned string describing the action type (Max 15 characters without whitespaces) + @param value Json string describing the action that is to be added + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_add_message_action_str(pubnub_t* pb, + char const* channel, + char const* message_timetoken, + char const* action_type, + char const* value); + + /** Searches the response(if previous transaction on the @p pb context had been pubnub_add_message_action and was accomplished successfully) and retrieves timetoken of a message action was added on. diff --git a/Source/ThirdParty/sdk/Include/core/pubnub_advanced_history.c b/Source/ThirdParty/sdk/Include/core/pubnub_advanced_history.c index 8f6101e..bb5b312 100644 --- a/Source/ThirdParty/sdk/Include/core/pubnub_advanced_history.c +++ b/Source/ThirdParty/sdk/Include/core/pubnub_advanced_history.c @@ -14,7 +14,7 @@ int pubnub_get_error_message(pubnub_t* pb, pubnub_chamebl_t* o_msg) { int rslt; - + PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); pubnub_mutex_lock(pb->monitor); @@ -30,7 +30,7 @@ int pubnub_get_error_message(pubnub_t* pb, pubnub_chamebl_t* o_msg) int pubnub_get_chan_msg_counts_size(pubnub_t* pb) -{ +{ /* Number of '"channel":msg_count' pairs */ int rslt; @@ -42,14 +42,14 @@ int pubnub_get_chan_msg_counts_size(pubnub_t* pb) return -1; } rslt = pbcc_get_chan_msg_counts_size(&(pb->core)); - + pubnub_mutex_unlock(pb->monitor); return rslt; } enum pubnub_res pubnub_message_counts(pubnub_t* pb, - char const* channel, + char const* channel, char const* timetoken) { enum pubnub_res rslt; @@ -65,10 +65,12 @@ enum pubnub_res pubnub_message_counts(pubnub_t* pb, } if (strchr(timetoken, ',') == NULL) { - rslt = pbcc_message_counts_prep(PBTT_MESSAGE_COUNTS , &(pb->core), channel, timetoken, NULL); + rslt = pbcc_message_counts_prep( + PBTT_MESSAGE_COUNTS, &(pb->core), channel, timetoken, NULL); } else { - rslt = pbcc_message_counts_prep(PBTT_MESSAGE_COUNTS , &(pb->core), channel, NULL, timetoken); + rslt = pbcc_message_counts_prep( + PBTT_MESSAGE_COUNTS, &(pb->core), channel, NULL, timetoken); } if (PNR_STARTED == rslt) { pb->trans = PBTT_MESSAGE_COUNTS; @@ -82,8 +84,8 @@ enum pubnub_res pubnub_message_counts(pubnub_t* pb, } -int pubnub_get_chan_msg_counts(pubnub_t* pb, - size_t* io_count, +int pubnub_get_chan_msg_counts(pubnub_t* pb, + size_t* io_count, struct pubnub_chan_msg_count* chan_msg_counters) { int rslt; @@ -98,7 +100,7 @@ int pubnub_get_chan_msg_counts(pubnub_t* pb, return -1; } rslt = pbcc_get_chan_msg_counts(&(pb->core), io_count, chan_msg_counters); - + pubnub_mutex_unlock(pb->monitor); return rslt; } @@ -107,7 +109,7 @@ int pubnub_get_chan_msg_counts(pubnub_t* pb, int pubnub_get_message_counts(pubnub_t* pb, char const* channel, int* o_count) { int rslt; - + PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); PUBNUB_ASSERT_OPT(channel != NULL); PUBNUB_ASSERT_OPT(o_count != NULL); @@ -118,9 +120,73 @@ int pubnub_get_message_counts(pubnub_t* pb, char const* channel, int* o_count) return -1; } rslt = pbcc_get_message_counts(&(pb->core), channel, o_count); - + + pubnub_mutex_unlock(pb->monitor); + return rslt; +} + +struct pubnub_delete_messages_options pubnub_delete_messages_defopts(void) +{ + struct pubnub_delete_messages_options options; + + options.start = NULL; + options.end = NULL; + + return options; +} + +enum pubnub_res pubnub_delete_messages(pubnub_t* pb, + char const* channel, + struct pubnub_delete_messages_options options) +{ + PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); + PUBNUB_ASSERT_OPT(NULL != channel); + + pubnub_mutex_lock(pb->monitor); + if (!pbnc_can_start_transaction(pb)) { + pubnub_mutex_unlock(pb->monitor); + return PNR_IN_PROGRESS; + } + + enum pubnub_res rslt = + pbcc_delete_messages_prep(&pb->core, channel, options.start, options.end); + + if (PNR_STARTED == rslt) { + pb->trans = PBTT_DELETE_MESSAGES; + pb->method = pubnubUseDELETE; + pb->core.last_result = PNR_STARTED; + pbnc_fsm(pb); + rslt = pb->core.last_result; + } pubnub_mutex_unlock(pb->monitor); + return rslt; } +pubnub_chamebl_t pubnub_get_delete_messages_response(pubnub_t* pb) +{ + pubnub_chamebl_t resp; + PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); + + pubnub_mutex_lock(pb->monitor); + if (PBTT_DELETE_MESSAGES != pb->trans) { + PUBNUB_LOG_ERROR( + "pubnub_get_delete_messages_response(pb=%p) can be " + "called only if previous transaction is " + "PBTT_DELETE_MESSAGES(%d). Previous transaction was: %d\n", + pb, + PBTT_DELETE_MESSAGES, + pb->trans); + pubnub_mutex_unlock(pb->monitor); + resp.ptr = NULL; + resp.size = 0; + return resp; + } + + resp = pbcc_get_delete_messages_response(&pb->core); + pubnub_mutex_unlock(pb->monitor); + + return resp; +} + #endif /* PUBNUB_USE_ADVANCED_HISTORY */ diff --git a/Source/ThirdParty/sdk/Include/core/pubnub_advanced_history.h b/Source/ThirdParty/sdk/Include/core/pubnub_advanced_history.h index 234614b..050f132 100644 --- a/Source/ThirdParty/sdk/Include/core/pubnub_advanced_history.h +++ b/Source/ThirdParty/sdk/Include/core/pubnub_advanced_history.h @@ -20,6 +20,20 @@ struct pubnub_chan_msg_count { size_t message_count; }; +// Delete messages endpoint configuration definition. +struct pubnub_delete_messages_options { + /** + * @brief Timetoken delimiting the start of time slice (exclusive) to delete + * messages from. + */ + char const* start; + /** + * @brief Timetoken delimiting the end of time slice (inclusive) to delete + * messages to. + */ + char const* end; +}; + /** If successful returns number of members(key:value pairs) of JSON object 'channels', or -1 on error(transaction still in progress, or so) @@ -63,6 +77,40 @@ PUBNUB_EXTERN int pubnub_get_chan_msg_counts(pubnub_t* pb, */ PUBNUB_EXTERN int pubnub_get_message_counts(pubnub_t* pb, char const*channel, int* o_count); +/** + * @brief Delete message transaction default options. + * + * @note It's best to always call `pubnub_delete_messages_defopts()` to + * initialize `pubnub_delete_messages_options`. since it has serveral + * parameters which maybe extended in the future. + * + * @return Default options for delete message transaction. + */ +PUBNUB_EXTERN struct pubnub_delete_messages_options pubnub_delete_messages_defopts(void); + +/** + * @brief Remove messages from the `channel`. + * + * Start `delete_messages` transaction to permanently remove messages from the `channel` storage. + * + * @param pb PubNub context which should be used to perform + * `delete messages` transaction. + * @param channel Channel from which messages should be deleted. + * @param options Additional `delete messages` transaction configuration object. + * @return Results of `delete messages` transaction call. + */ +PUBNUB_EXTERN enum pubnub_res +pubnub_delete_messages(pubnub_t* pb, + char const* channel, + struct pubnub_delete_messages_options options); + +/** + * @brief Get `delete messages` service response. + * + * @param pb PubNub context which has been used to delete channel messages. + * @return `pubnub_chamebl_t` with pointer to string with response. + */ +PUBNUB_EXTERN pubnub_chamebl_t pubnub_get_delete_messages_response(pubnub_t* pb); #endif /* !defined INC_PUBNUB_ADVANCED_HISTORY */ diff --git a/Source/ThirdParty/sdk/Include/core/pubnub_api_types.h b/Source/ThirdParty/sdk/Include/core/pubnub_api_types.h index 816ec3b..92f6e5c 100644 --- a/Source/ThirdParty/sdk/Include/core/pubnub_api_types.h +++ b/Source/ThirdParty/sdk/Include/core/pubnub_api_types.h @@ -200,6 +200,13 @@ enum pubnub_trans { history counts for channels listed. */ PBTT_MESSAGE_COUNTS, + /** + * @brief History V3 (delete messages) operation/transaction. + * + * @note All `channel` messages will be removed If neither `start`, nor + * `end` has been passed. + */ + PBTT_DELETE_MESSAGES, #endif #if PUBNUB_USE_OBJECTS_API /** Objects API transaction Returns a paginated list of users associated with the diff --git a/Source/ThirdParty/sdk/Include/core/pubnub_ccore_pubsub.c b/Source/ThirdParty/sdk/Include/core/pubnub_ccore_pubsub.c index b14d205..4ff54b0 100644 --- a/Source/ThirdParty/sdk/Include/core/pubnub_ccore_pubsub.c +++ b/Source/ThirdParty/sdk/Include/core/pubnub_ccore_pubsub.c @@ -113,49 +113,20 @@ bool pbcc_ensure_reply_buffer(struct pbcc_context* p) char const* pbcc_get_msg(struct pbcc_context* pb) { +#if PUBNUB_CRYPTO_API + size_t len; +#endif // PUBNUB_CRYPTO_API if (pb->msg_ofs < pb->msg_end) { PUBNUB_LOG_DEBUG("RESPONSE = %s\n", pb->http_reply); char const* rslt = pb->http_reply + pb->msg_ofs; pb->msg_ofs += strlen(rslt); if (pb->msg_ofs++ <= pb->msg_end) { #if PUBNUB_CRYPTO_API - if (NULL != pb->crypto_module) { - char* trimmed = (char*)malloc(strlen(rslt) + 1); // same length as rslt - if (NULL == trimmed) { - PUBNUB_LOG_ERROR("pbcc_get_msg(pbcc=%p) - failed to allocate memory for trimmed string. Returning original message!\n", pb); - return NULL; - } - sprintf(trimmed, "%s", rslt); - - trimmed[strlen(trimmed) - 1] = '\0'; - - pubnub_bymebl_t encrypted = pbcc_base64_decode(trimmed + 1); - free(trimmed); - - if (NULL == encrypted.ptr) { - PUBNUB_LOG_WARNING("pbcc_get_msg(pbcc=%p) - base64 decoding failed. Returning original message!\n", pb); - return rslt; - } - - pubnub_bymebl_t rslt_block = pb->crypto_module->decrypt(pb->crypto_module, encrypted); - free(encrypted.ptr); - if (NULL == rslt_block.ptr) { - PUBNUB_LOG_WARNING("pbcc_get_msg(pbcc=%p) - decryption failed. Returning original message!\n", pb); - return rslt; - } - - if (pb->decrypted_message_count >= PUBNUB_MAX_DECRYPTED_MESSAGES) { - PUBNUB_LOG_ERROR("pbcc_get_msg(pbcc=%p) - maximum number of decrypted messages reached. Returning original message!\n", pb); - return NULL; - } - - pb->decrypted_messages[pb->decrypted_message_count] = rslt_block.ptr; - pb->decrypted_message_count++; - - rslt = (char*)rslt_block.ptr; + if (pb->crypto_module != NULL) { + len = strlen(rslt); + rslt = pbcc_decrypt_message(pb, rslt, len, NULL); } #endif // PUBNUB_CRYPTO_API - return rslt; } } @@ -199,8 +170,7 @@ enum pubnub_res pbcc_set_user_id(struct pbcc_context* pb, const char* user_id) pb->user_id_len = 0; return PNR_OUT_OF_MEMORY; } - strncpy(pb->user_id, user_id, pb->user_id_len); - pb->user_id[pb->user_id_len] = '\0'; + strcpy(pb->user_id, user_id); } return PNR_OK; } @@ -528,18 +498,18 @@ enum pubnub_res pbcc_append_url_param_encoded(struct pbcc_context* pb, return pbcc_url_encode(pb, param_val, pt); } - enum pubnub_res pbcc_publish_prep(struct pbcc_context* pb, const char* channel, const char* message, bool store_in_history, bool norep, char const* meta, + const size_t ttl, enum pubnub_method method) { - char const* const uname = pubnub_uname(); - char const* user_id = pbcc_user_id_get(pb); - enum pubnub_res rslt = PNR_OK; + char const* const uname = pubnub_uname(); + char const* user_id = pbcc_user_id_get(pb); + enum pubnub_res rslt = PNR_OK; PUBNUB_ASSERT_OPT(user_id != NULL); PUBNUB_ASSERT_OPT(message != NULL); @@ -556,10 +526,11 @@ enum pubnub_res pbcc_publish_prep(struct pbcc_context* pb, #if PUBNUB_CRYPTO_API if (NULL != pb->crypto_module) { pubnub_bymebl_t message_block; - message_block.ptr = (uint8_t*)message; + message_block.ptr = (uint8_t*)message; message_block.size = strlen(message); - pubnub_bymebl_t encrypted = pb->crypto_module->encrypt(pb->crypto_module, message_block); + pubnub_bymebl_t encrypted = + pb->crypto_module->encrypt(pb->crypto_module, message_block); if (NULL == encrypted.ptr) { PUBNUB_LOG_ERROR("pbcc_publish_prep(pbcc=%p) - encryption failed\n", pb); @@ -571,15 +542,19 @@ enum pubnub_res pbcc_publish_prep(struct pbcc_context* pb, message = pbcc_base64_encode(encrypted); free(encrypted.ptr); - + if (NULL == message) { - PUBNUB_LOG_ERROR("pbcc_publish_prep(pbcc=%p) - base64 encoding failed\n", pb); + PUBNUB_LOG_ERROR( + "pbcc_publish_prep(pbcc=%p) - base64 encoding failed\n", pb); return PNR_INTERNAL_ERROR; } - char* quoted_message = (char*)malloc(strlen(message) + 3); // quotes + null-terminator + char* quoted_message = + (char*)malloc(strlen(message) + 3); // quotes + null-terminator if (NULL == quoted_message) { - PUBNUB_LOG_ERROR("pbcc_publish_prep(pbcc=%p) - failed to allocate memory for quoted message\n", pb); + PUBNUB_LOG_ERROR("pbcc_publish_prep(pbcc=%p) - failed to allocate " + "memory for quoted message\n", + pb); free((void*)message); return PNR_OUT_OF_MEMORY; } @@ -596,7 +571,8 @@ enum pubnub_res pbcc_publish_prep(struct pbcc_context* pb, } URL_PARAMS_INIT(qparam, PUBNUB_MAX_URL_PARAMS); if (uname) { ADD_URL_PARAM(qparam, pnsdk, uname); } - if (user_id) { ADD_URL_PARAM(qparam, uuid, user_id); } + ADD_URL_PARAM(qparam, uuid, user_id); + if (ttl != SIZE_MAX) { ADD_URL_PARAM_SIZET(qparam, ttl, ttl); } #if PUBNUB_CRYPTO_API if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); } ADD_TS_TO_URL_PARAM(); @@ -608,14 +584,15 @@ enum pubnub_res pbcc_publish_prep(struct pbcc_context* pb, if (meta) { ADD_URL_PARAM(qparam, meta, meta); } #if PUBNUB_CRYPTO_API - SORT_URL_PARAMETERS(qparam); + SORT_URL_PARAMETERS(qparam); #endif ENCODE_URL_PARAMETERS(pb, qparam); #if PUBNUB_CRYPTO_API if (pb->secret_key != NULL) { rslt = pbcc_sign_url(pb, message, method, false); if (rslt != PNR_OK) { - PUBNUB_LOG_ERROR("pbcc_sign_url failed. pb=%p, message=%s, method=%d", pb, message, method); + PUBNUB_LOG_ERROR( + "pbcc_sign_url failed. pb=%p, message=%s, method=%d", pb, message, method); } } #endif @@ -625,10 +602,7 @@ enum pubnub_res pbcc_publish_prep(struct pbcc_context* pb, } PUBNUB_LOG_DEBUG("pbcc_publish_prep. REQUEST =%s\n", pb->http_buf); #if PUBNUB_CRYPTO_API - if (NULL != pb->crypto_module) - { - free((void*) message); - } + if (NULL != pb->crypto_module) { free((void*)message); } #endif return (rslt != PNR_OK) ? rslt : PNR_STARTED; diff --git a/Source/ThirdParty/sdk/Include/core/pubnub_ccore_pubsub.h b/Source/ThirdParty/sdk/Include/core/pubnub_ccore_pubsub.h index c4a4dfb..ba70365 100644 --- a/Source/ThirdParty/sdk/Include/core/pubnub_ccore_pubsub.h +++ b/Source/ThirdParty/sdk/Include/core/pubnub_ccore_pubsub.h @@ -309,12 +309,12 @@ struct pbcc_context { else if (pb->auth != NULL) { ADD_URL_PARAM(name, key, pb->auth); } #define ADD_URL_PARAM_SIZET(name, key, value) \ - int val_len = snprintf(NULL, 0, "%lu", value); \ + int val_len = snprintf(NULL, 0, "%lu", (long unsigned int)value); \ if (val_len >= 21) { \ PUBNUB_LOG_ERROR("Error: in ADD_URL_PARAM_SIZET:\n"); \ return PNR_TX_BUFF_TOO_SMALL; \ } \ - snprintf(name##_val_str, val_len + 1, "%lu", value); \ + snprintf(name##_val_str, val_len + 1, "%lu", (long unsigned int)value); \ name[(int)(name##_index)].param_key = #key; \ name[(int)(name##_index)].key_size = sizeof(#key)-1; \ name[(int)(name##_index)].param_val = name##_val_str; \ @@ -457,6 +457,7 @@ enum pubnub_res pbcc_publish_prep(struct pbcc_context* pb, bool store_in_history, bool norep, char const* meta, + size_t ttl, enum pubnub_method method); /** Prepares the Signal operation (transaction), mostly by diff --git a/Source/ThirdParty/sdk/Include/core/pubnub_coreapi_ex.c b/Source/ThirdParty/sdk/Include/core/pubnub_coreapi_ex.c index e746eda..119a28c 100644 --- a/Source/ThirdParty/sdk/Include/core/pubnub_coreapi_ex.c +++ b/Source/ThirdParty/sdk/Include/core/pubnub_coreapi_ex.c @@ -32,6 +32,7 @@ struct pubnub_publish_options pubnub_publish_defopts(void) result.replicate = true; result.meta = NULL; result.method = pubnubSendViaGET; + result.ttl = SIZE_MAX; return result; } @@ -54,11 +55,15 @@ enum pubnub_res pubnub_publish_ex(pubnub_t* pb, } #if PUBNUB_CRYPTO_API if (NULL != pb->core.crypto_module && NULL != opts.cipher_key) { - PUBNUB_LOG_WARNING("pubnub_publish_ex(pb=%p).cipher_key called while client crypto module is set! Using crypto module instead!\n", pb); - } else if (NULL != opts.cipher_key) { + PUBNUB_LOG_WARNING( + "pubnub_publish_ex(pb=%p).cipher_key called while client crypto " + "module is set! Using crypto module instead!\n", + pb); + } + else if (NULL != opts.cipher_key) { pubnub_bymebl_t to_encrypt; - char* encrypted_msg = pb->core.encrypted_msg_buf; - size_t n = sizeof pb->core.encrypted_msg_buf - sizeof("\"\""); + char* encrypted_msg = pb->core.encrypted_msg_buf; + size_t n = sizeof pb->core.encrypted_msg_buf - sizeof("\"\""); to_encrypt.ptr = (uint8_t*)message; to_encrypt.size = strlen(message); @@ -73,11 +78,18 @@ enum pubnub_res pubnub_publish_ex(pubnub_t* pb, #endif #if PUBNUB_USE_GZIP_COMPRESSION if (pubnubSendViaPOSTwithGZIP == opts.method) { - message = (pbgzip_compress(pb, message) == PNR_OK) ? pb->core.gzip_msg_buf : message; + message = (pbgzip_compress(pb, message) == PNR_OK) ? pb->core.gzip_msg_buf + : message; } #endif - rslt = pbcc_publish_prep( - &pb->core, channel, message, opts.store, !opts.replicate, opts.meta, opts.method); + rslt = pbcc_publish_prep(&pb->core, + channel, + message, + opts.store, + !opts.replicate, + opts.meta, + opts.ttl, + opts.method); if (PNR_STARTED == rslt) { pb->trans = PBTT_PUBLISH; pb->core.last_result = PNR_STARTED; diff --git a/Source/ThirdParty/sdk/Include/core/pubnub_coreapi_ex.h b/Source/ThirdParty/sdk/Include/core/pubnub_coreapi_ex.h index ceec8be..79a88b3 100644 --- a/Source/ThirdParty/sdk/Include/core/pubnub_coreapi_ex.h +++ b/Source/ThirdParty/sdk/Include/core/pubnub_coreapi_ex.h @@ -60,7 +60,11 @@ struct pubnub_publish_options { */ char const* meta; /** Defines the method by which publish transaction will be performed */ - enum pubnub_method method; + enum pubnub_method method; + /** For how many hours message should be kept and available with history + API. + */ + size_t ttl; }; /** This returns the default options for publish V1 transactions. diff --git a/Source/ThirdParty/sdk/Include/core/pubnub_crypto_unit_tests.c b/Source/ThirdParty/sdk/Include/core/pubnub_crypto_unit_tests.c index 44b57df..da40a75 100644 --- a/Source/ThirdParty/sdk/Include/core/pubnub_crypto_unit_tests.c +++ b/Source/ThirdParty/sdk/Include/core/pubnub_crypto_unit_tests.c @@ -5,6 +5,8 @@ #include "cgreen/cgreen.h" #include "cgreen/constraint_syntax_helpers.h" #include "cgreen/mocks.h" +#include "pubnub_coreapi_ex.h" +#include "pubnub_helper.h" #include "pubnub_memory_block.h" #include "test/pubnub_test_mocks.h" @@ -18,6 +20,8 @@ #include "pubnub_coreapi.h" #include "pubnub_crypto.h" #include "pbcc_crypto.h" +#include "pubnub_subscribe_v2.h" +#include "pubnub_subscribe_v2_message.h" #include #include @@ -167,6 +171,45 @@ Ensure(crypto_api, client_should_use_cryptors_for_history) { assert_that(pubnub_last_http_code(pbp), is_equal_to(200)); } +Ensure(crypto_api, client_should_use_cryptors_for_subscribe_v2) { + pubnub_set_crypto_module(pbp, pubnub_crypto_module_init(&x_cryptor, &y_cryptor, 1)); + + assert_that(pubnub_last_time_token(pbp), is_equal_to_string("0")); + expect_have_dns_for_pubnub_origin_on_ctx(pbp); + expect_outgoing_with_url_no_params_on_ctx(pbp, + "/v2/subscribe/sub_key/my-channel/0"); + incoming("HTTP/1.1 200\r\nContent-Length: " + "44\r\n\r\n{\"t\":{\"t\":\"15628652479932717\",\"r\":4},\"m\":[]}", + NULL); + expect(pbntf_lost_socket, when(pb, is_equal_to(pbp))); + expect(pbntf_trans_outcome, when(pb, is_equal_to(pbp))); + assert_that(pubnub_subscribe_v2(pbp, "my-channel", pubnub_subscribe_v2_defopts()), is_equal_to(PNR_OK)); + + assert_that(pubnub_get(pbp), is_equal_to(NULL)); + assert_that(pubnub_last_http_code(pbp), is_equal_to(200)); + assert_that(pubnub_last_time_token(pbp), is_equal_to_string("15628652479932717")); + /* Not publish operation */ + assert_that(pubnub_last_publish_result(pbp), is_equal_to_string("")); + + expect(pbntf_enqueue_for_processing, when(pb, is_equal_to(pbp)), will_return(0)); + expect(pbntf_got_socket, when(pb, is_equal_to(pbp)), will_return(0)); + expect_outgoing_with_url_no_params_on_ctx(pbp, + "/v2/subscribe/sub_key/my-channel/0"); + incoming("HTTP/1.1 200\r\nContent-Length: " + "198\r\n\r\n{\"t\":{\"t\":\"15628652479932717\",\"r\":4},\"m\":[{\"a\":\"1\",\"f\":514,\"i\":\"publisher_id\",\"s\":1,\"p\":{\"t\":\"15628652479933927\",\"r\":4},\"k\":\"demo\",\"c\":\"my-channel\",\"d\":\"UE5FRAF4eHh4BG1ldGF4eHh4\",\"b\":\"my-channel\"}]}", + NULL); + expect(pbntf_lost_socket, when(pb, is_equal_to(pbp))); + expect(pbntf_trans_outcome, when(pb, is_equal_to(pbp))); + assert_that(pubnub_subscribe_v2(pbp, "my-channel", pubnub_subscribe_v2_defopts()), is_equal_to(PNR_OK)); + assert_that(pubnub_last_time_token(pbp), is_equal_to_string("15628652479932717")); + + struct pubnub_v2_message msg = pubnub_get_v2(pbp); + assert_that(msg.payload.ptr, is_equal_to_string(X)); + assert_that(pubnub_get_v2(pbp).payload.ptr, is_equal_to(NULL)); + assert_that(pubnub_last_http_code(pbp), is_equal_to(200)); +} + + int x_encrypt(pubnub_cryptor_t const* _c, struct pubnub_encrypted_data *result, pubnub_bymebl_t _d) { result->data.ptr = (uint8_t*)X; result->data.size = X_SIZE; diff --git a/Source/ThirdParty/sdk/Include/core/pubnub_generate_uuid.c b/Source/ThirdParty/sdk/Include/core/pubnub_generate_uuid.c index c6e0af4..0290422 100644 --- a/Source/ThirdParty/sdk/Include/core/pubnub_generate_uuid.c +++ b/Source/ThirdParty/sdk/Include/core/pubnub_generate_uuid.c @@ -46,8 +46,8 @@ int pubnub_generate_uuid_v1_time( ud->clock_seq_low = *io_clock_seq & 0xFF; ud->clock_seq_hi_and_reserved = (*io_clock_seq & 0x3F00) >> 8; ud->clock_seq_hi_and_reserved |= 0x80; - memcpy(&ud->node, &i_node, sizeof ud->node); + memcpy(&ud->node, &i_node, sizeof ud->node); memcpy(s_timestamp, i_timestamp, sizeof s_timestamp); return 0; @@ -93,12 +93,22 @@ struct Pubnub_UUID_String pubnub_uuid_to_string(struct Pubnub_UUID const *uuid) struct Pubnub_UUID_String rslt; struct Pubnub_UUID_decomposed const*u = (struct Pubnub_UUID_decomposed const*)uuid; +#ifdef ESP_PLATFORM +// Compiler on ESP32 treats uint32_t as long unsigned int + snprintf(rslt.uuid, sizeof rslt.uuid, + "%8.8lx-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x", + u->time_low, u->time_mid, u->time_hi_and_version, + u->clock_seq_hi_and_reserved, u->clock_seq_low, + u->node[0], u->node[1], u->node[2], u->node[3], u->node[4], u->node[5] + ); +#else snprintf(rslt.uuid, sizeof rslt.uuid, "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x", u->time_low, u->time_mid, u->time_hi_and_version, u->clock_seq_hi_and_reserved, u->clock_seq_low, u->node[0], u->node[1], u->node[2], u->node[3], u->node[4], u->node[5] ); +#endif /* ESP_PLATFORM */ return rslt; } diff --git a/Source/ThirdParty/sdk/Include/core/pubnub_netcore.c b/Source/ThirdParty/sdk/Include/core/pubnub_netcore.c index 697ed42..29369fa 100644 --- a/Source/ThirdParty/sdk/Include/core/pubnub_netcore.c +++ b/Source/ThirdParty/sdk/Include/core/pubnub_netcore.c @@ -295,6 +295,7 @@ static PFpbcc_parse_response_T m_aParseResponse[] = { dont_parse, #endif #if PUBNUB_USE_ADVANCED_HISTORY , pbcc_parse_message_counts_response /* PBTT_MESSAGE_COUNTS */ + , pbcc_parse_delete_messages_response /* PBTT_DELETE_MESSAGES */ #endif #if PUBNUB_USE_OBJECTS_API , pbcc_parse_objects_api_response /* PBTT_GET_USERS */ diff --git a/Source/ThirdParty/sdk/Include/core/pubnub_objects_api.c b/Source/ThirdParty/sdk/Include/core/pubnub_objects_api.c index 6d87d93..7dab020 100644 --- a/Source/ThirdParty/sdk/Include/core/pubnub_objects_api.c +++ b/Source/ThirdParty/sdk/Include/core/pubnub_objects_api.c @@ -38,6 +38,26 @@ do { json = (obj_buffer); \ } while(0) +const struct pubnub_page_object pubnub_null_page = {NULL, NULL}; + +const struct pubnub_user_data pubnub_null_user_data = {NULL, NULL, NULL, NULL, NULL}; + +const struct pubnub_channel_data pubnub_null_channel_data = {NULL, NULL, NULL}; + + +struct pubnub_getall_metadata_opts pubnub_getall_metadata_defopts(void) +{ + struct pubnub_getall_metadata_opts opts; + opts.include = NULL; + opts.filter = NULL; + opts.sort = NULL; + opts.limit = 100; + opts.count = pbccNotSet; + opts.page = pubnub_null_page; + + return opts; +} + enum pubnub_res pubnub_getall_uuidmetadata(pubnub_t* pb, char const* include, @@ -45,6 +65,19 @@ enum pubnub_res pubnub_getall_uuidmetadata(pubnub_t* pb, char const* start, char const* end, enum pubnub_tribool count) +{ + struct pubnub_getall_metadata_opts opts = pubnub_getall_metadata_defopts(); + opts.include = include; + opts.limit = limit; + opts.page.next = start; + opts.page.prev = end; + opts.count = count; + + return pubnub_getall_uuidmetadata_ex(pb, opts); +} + + +enum pubnub_res pubnub_getall_uuidmetadata_ex(pubnub_t* pb, struct pubnub_getall_metadata_opts opts) { enum pubnub_res rslt; @@ -57,11 +90,13 @@ enum pubnub_res pubnub_getall_uuidmetadata(pubnub_t* pb, } pb->trans = PBTT_GETALL_UUIDMETADATA; rslt = pbcc_getall_uuidmetadata_prep(&pb->core, - include, - limit, - start, - end, - count, + opts.include, + opts.limit, + opts.page.next, + opts.page.prev, + opts.count, + opts.filter, + opts.sort, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_GETALL_UUIDMETADATA; @@ -75,6 +110,17 @@ enum pubnub_res pubnub_getall_uuidmetadata(pubnub_t* pb, } +struct pubnub_set_uuidmetadata_opts pubnub_set_uuidmetadata_defopts(void) +{ + struct pubnub_set_uuidmetadata_opts opts; + opts.uuid = NULL; + opts.include = NULL; + opts.data = pubnub_null_user_data; + + return opts; +} + + enum pubnub_res pubnub_set_uuidmetadata(pubnub_t* pb, char const* uuid_metadataid, char const* include, @@ -92,7 +138,11 @@ enum pubnub_res pubnub_set_uuidmetadata(pubnub_t* pb, pb->method = pubnubUsePATCH; pb->trans = PBTT_SET_UUIDMETADATA; - rslt = pbcc_set_uuidmetadata_prep(&pb->core, uuid_metadataid, include, uuid_metadata_obj, pb->trans); + rslt = pbcc_set_uuidmetadata_prep(&pb->core, + uuid_metadataid, + include, + uuid_metadata_obj, + pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_SET_UUIDMETADATA; pb->core.last_result = PNR_STARTED; @@ -106,6 +156,71 @@ enum pubnub_res pubnub_set_uuidmetadata(pubnub_t* pb, } +enum pubnub_res pubnub_set_uuidmetadata_ex(pubnub_t* pb, + struct pubnub_set_uuidmetadata_opts opts) +{ + char* obj_buffer = NULL; + enum pubnub_res result; + size_t obj_len = 0; + + obj_len = NULL != opts.data.custom ? strlen(opts.data.custom) : 0; + obj_len += NULL != opts.data.email ? strlen(opts.data.email) : 0; + obj_len += NULL != opts.data.name ? strlen(opts.data.name) : 0; + obj_len += NULL != opts.data.external_id ? strlen(opts.data.external_id) : 0; + obj_len += NULL != opts.data.profile_url ? strlen(opts.data.profile_url) : 0; + + obj_buffer = (char*)malloc(obj_len + 64); // 64 is for the JSON object structure with small buffer + int offset = snprintf(obj_buffer, obj_len, "{"); + + // TODO: maybe it will be a good idea to add serialization at some point to this SDK + if (NULL != opts.data.custom) { + offset += snprintf(obj_buffer + offset, + obj_len - offset, + "\"custom\":%s", + opts.data.custom); + } + + if (NULL != opts.data.email) { + offset += snprintf(obj_buffer + offset, + obj_len - offset, + "%s\"email\":\"%s\"", + offset > 1 ? "," : "", + opts.data.email); + } + + if (NULL != opts.data.name) { + offset += snprintf(obj_buffer + offset, + obj_len - offset, + "%s\"name\":\"%s\"", + offset > 1 ? "," : "", + opts.data.name); + } + + if (NULL != opts.data.external_id) { + offset += snprintf(obj_buffer + offset, + obj_len - offset, + "%s\"externalId\":\"%s\"", + offset > 1 ? "," : "", + opts.data.external_id); + } + + if (NULL != opts.data.profile_url) { + offset += snprintf(obj_buffer + offset, + obj_len - offset, + "%s\"profileUrl\":\"%s\"", + offset > 1 ? "," : "", + opts.data.profile_url); + } + snprintf(obj_buffer + offset, obj_len - offset, "}"); + + result = pubnub_set_uuidmetadata(pb, opts.uuid, opts.include, obj_buffer); + free(obj_buffer); + + return result; +} + + + enum pubnub_res pubnub_get_uuidmetadata(pubnub_t* pb, char const* include, char const* uuid_metadataid) @@ -166,6 +281,20 @@ enum pubnub_res pubnub_getall_channelmetadata(pubnub_t* pb, char const* start, char const* end, enum pubnub_tribool count) +{ + struct pubnub_getall_metadata_opts opts = pubnub_getall_metadata_defopts(); + opts.include = include; + opts.limit = limit; + opts.page.next = start; + opts.page.prev = end; + opts.count = count; + + return pubnub_getall_channelmetadata_ex(pb, opts); +} + + +enum pubnub_res pubnub_getall_channelmetadata_ex(pubnub_t* pb, + struct pubnub_getall_metadata_opts opts) { enum pubnub_res rslt; @@ -178,11 +307,13 @@ enum pubnub_res pubnub_getall_channelmetadata(pubnub_t* pb, } pb->trans = PBTT_GETALL_CHANNELMETADATA; rslt = pbcc_getall_channelmetadata_prep(&pb->core, - include, - limit, - start, - end, - count, + opts.include, + opts.limit, + opts.page.next, + opts.page.prev, + opts.count, + opts.filter, + opts.sort, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_GETALL_CHANNELMETADATA; @@ -196,6 +327,16 @@ enum pubnub_res pubnub_getall_channelmetadata(pubnub_t* pb, } +struct pubnub_set_channelmetadata_opts pubnub_set_channelmetadata_defopts(void) +{ + struct pubnub_set_channelmetadata_opts opts; + opts.include = NULL; + opts.data = pubnub_null_channel_data; + + return opts; +} + + enum pubnub_res pubnub_set_channelmetadata(pubnub_t* pb, char const* channel_metadataid, char const* include, @@ -213,7 +354,11 @@ enum pubnub_res pubnub_set_channelmetadata(pubnub_t* pb, pb->method = pubnubUsePATCH; pb->trans = PBTT_SET_CHANNELMETADATA; - rslt = pbcc_set_channelmetadata_prep(&pb->core, channel_metadataid, include, channel_metadata_obj, pb->trans); + rslt = pbcc_set_channelmetadata_prep(&pb->core, + channel_metadataid, + include, + channel_metadata_obj, + pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_SET_CHANNELMETADATA; pb->core.last_result = PNR_STARTED; @@ -227,6 +372,50 @@ enum pubnub_res pubnub_set_channelmetadata(pubnub_t* pb, } +enum pubnub_res pubnub_set_channelmetadata_ex(pubnub_t* pb, + char const* channel, + struct pubnub_set_channelmetadata_opts opts) +{ + char* obj_buffer = NULL; + enum pubnub_res result; + size_t obj_len = 0; + + obj_len = NULL != opts.data.custom ? strlen(opts.data.custom) : 0; + obj_len += NULL != opts.data.description ? strlen(opts.data.description) : 0; + obj_len += NULL != opts.data.name ? strlen(opts.data.name) : 0; + + obj_buffer = (char*)malloc(obj_len + 64); // 64 is for the JSON object structure with small buffer + int offset = snprintf(obj_buffer, obj_len, "{"); + + if (NULL != opts.data.custom) { + offset += snprintf(obj_buffer, obj_len, "\"custom\":%s", opts.data.custom); + } + + if (NULL != opts.data.description) { + offset += snprintf(obj_buffer + offset, + obj_len - offset, + "%s\"description\":\"%s\"", + offset > 1 ? "," : "", + opts.data.description); + } + + if (NULL != opts.data.name) { + offset += snprintf(obj_buffer + offset, + obj_len - offset, + "%s\"name\":\"%s\"", + offset > 1 ? "," : "", + opts.data.name); + } + + offset += snprintf(obj_buffer + offset, obj_len - offset, "}\0"); + + result = pubnub_set_channelmetadata(pb, channel, opts.include, obj_buffer); + free(obj_buffer); + + return result; +} + + enum pubnub_res pubnub_get_channelmetadata(pubnub_t* pb, char const* include, char const* channel_metadataid) @@ -282,6 +471,20 @@ enum pubnub_res pubnub_remove_channelmetadata(pubnub_t* pb, char const* channel_ } +struct pubnub_membership_opts pubnub_memberships_defopts(void) +{ + struct pubnub_membership_opts opts; + opts.uuid = NULL; + opts.include = NULL; + opts.page = pubnub_null_page; + opts.filter = NULL; + opts.sort = NULL; + opts.limit = 100; + + return opts; +} + + enum pubnub_res pubnub_get_memberships(pubnub_t* pb, char const* uuid_metadataid, char const* include, @@ -289,9 +492,28 @@ enum pubnub_res pubnub_get_memberships(pubnub_t* pb, char const* start, char const* end, enum pubnub_tribool count) +{ + struct pubnub_membership_opts opts = pubnub_memberships_defopts(); + opts.uuid = uuid_metadataid; + opts.include = include; + opts.limit = limit; + opts.page.next = start; + opts.page.prev = end; + opts.count = count; + + return pubnub_get_memberships_ex(pb, opts); +} + + +enum pubnub_res pubnub_get_memberships_ex(pubnub_t* pb, + struct pubnub_membership_opts opts) { enum pubnub_res rslt; + if (NULL == opts.uuid) { + opts.uuid = pb->core.user_id; + } + PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); pubnub_mutex_lock(pb->monitor); @@ -301,12 +523,14 @@ enum pubnub_res pubnub_get_memberships(pubnub_t* pb, } pb->trans = PBTT_GET_MEMBERSHIPS; rslt = pbcc_get_memberships_prep(&pb->core, - uuid_metadataid, - include, - limit, - start, - end, - count, + opts.uuid, + opts.include, + opts.limit, + opts.page.next, + opts.page.prev, + opts.count, + opts.filter, + opts.sort, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_GET_MEMBERSHIPS; @@ -324,6 +548,18 @@ enum pubnub_res pubnub_set_memberships(pubnub_t* pb, char const* uuid_metadataid, char const* include, char const* set_obj) +{ + struct pubnub_membership_opts opts = pubnub_memberships_defopts(); + opts.uuid = uuid_metadataid; + opts.include = include; + + return pubnub_set_memberships_ex(pb, set_obj, opts); +} + + +enum pubnub_res pubnub_set_memberships_ex(pubnub_t* pb, + char const* channels, + struct pubnub_membership_opts opts) { enum pubnub_res rslt; char obj_buffer[PUBNUB_BUF_MAXLEN]; @@ -341,14 +577,20 @@ enum pubnub_res pubnub_set_memberships(pubnub_t* pb, "pubnub_set_memberships", obj_buffer, "{\"set\":", - set_obj); + channels); pb->method = pubnubUsePATCH; pb->trans = PBTT_SET_MEMBERSHIPS; rslt = pbcc_set_memberships_prep(&pb->core, - uuid_metadataid, - include, - set_obj, + opts.uuid, + opts.include, + channels, + opts.filter, + opts.sort, + opts.limit, + opts.page.next, + opts.page.prev, + opts.count, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_SET_MEMBERSHIPS; @@ -367,9 +609,25 @@ enum pubnub_res pubnub_remove_memberships(pubnub_t* pb, char const* uuid_metadataid, char const* include, char const* remove_obj) +{ + struct pubnub_membership_opts opts = pubnub_memberships_defopts(); + opts.uuid = uuid_metadataid; + opts.include = include; + + return pubnub_remove_memberships_ex(pb, remove_obj, opts); +} + + +enum pubnub_res pubnub_remove_memberships_ex(pubnub_t* pb, + char const* channels, + struct pubnub_membership_opts opts) { enum pubnub_res rslt; char obj_buffer[PUBNUB_BUF_MAXLEN]; + + if (NULL == opts.uuid) { + opts.uuid = pb->core.user_id; + } PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); @@ -384,13 +642,19 @@ enum pubnub_res pubnub_remove_memberships(pubnub_t* pb, "pubnub_remove_memberships", obj_buffer, "{\"delete\":", - remove_obj); + channels); pb->method = pubnubUsePATCH; pb->trans = PBTT_REMOVE_MEMBERSHIPS; rslt = pbcc_set_memberships_prep(&pb->core, - uuid_metadataid, - include, - remove_obj, + opts.uuid, + opts.include, + channels, + opts.filter, + opts.sort, + opts.limit, + opts.page.next, + opts.page.prev, + opts.count, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_REMOVE_MEMBERSHIPS; @@ -405,6 +669,20 @@ enum pubnub_res pubnub_remove_memberships(pubnub_t* pb, } +struct pubnub_members_opts pubnub_members_defopts(void) +{ + struct pubnub_members_opts opts; + opts.include = NULL; + opts.filter = NULL; + opts.sort = NULL; + opts.limit = 100; + opts.page = pubnub_null_page; + opts.count = pbccNotSet; + + return opts; +} + + enum pubnub_res pubnub_get_members(pubnub_t* pb, char const* channel_metadataid, char const* include, @@ -412,6 +690,21 @@ enum pubnub_res pubnub_get_members(pubnub_t* pb, char const* start, char const* end, enum pubnub_tribool count) +{ + struct pubnub_members_opts opts = pubnub_members_defopts(); + opts.include = include; + opts.limit = limit; + opts.page.next = start; + opts.page.prev = end; + opts.count = count; + + return pubnub_get_members_ex(pb, channel_metadataid, opts); +} + + +enum pubnub_res pubnub_get_members_ex(pubnub_t* pb, + char const* channel, + struct pubnub_members_opts opts) { enum pubnub_res rslt; @@ -424,12 +717,14 @@ enum pubnub_res pubnub_get_members(pubnub_t* pb, } pb->trans = PBTT_GET_MEMBERS; rslt = pbcc_get_members_prep(&pb->core, - channel_metadataid, - include, - limit, - start, - end, - count, + channel, + opts.include, + opts.limit, + opts.page.next, + opts.page.prev, + opts.filter, + opts.sort, + opts.count, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_GET_MEMBERS; @@ -450,6 +745,7 @@ enum pubnub_res pubnub_add_members(pubnub_t* pb, { char obj_buffer[PUBNUB_BUF_MAXLEN]; enum pubnub_res rslt; + struct pubnub_members_opts defaults = pubnub_members_defopts(); PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); @@ -470,6 +766,12 @@ enum pubnub_res pubnub_add_members(pubnub_t* pb, channel_metadataid, include, update_obj, + defaults.filter, + defaults.sort, + defaults.limit, + defaults.page.next, + defaults.page.prev, + defaults.count, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_ADD_MEMBERS; @@ -488,6 +790,18 @@ enum pubnub_res pubnub_set_members(pubnub_t* pb, char const* channel_metadataid, char const* include, char const* set_obj) +{ + struct pubnub_members_opts opts = pubnub_members_defopts(); + opts.include = include; + + return pubnub_set_members_ex(pb, channel_metadataid, set_obj, opts); +} + + +enum pubnub_res pubnub_set_members_ex(pubnub_t* pb, + char const* channel, + char const* uuids, + struct pubnub_members_opts opts) { enum pubnub_res rslt; char obj_buffer[PUBNUB_BUF_MAXLEN]; @@ -505,13 +819,19 @@ enum pubnub_res pubnub_set_members(pubnub_t* pb, "pubnub_set_members", obj_buffer, "{\"set\":", - set_obj); + uuids); pb->method = pubnubUsePATCH; pb->trans = PBTT_SET_MEMBERS; rslt = pbcc_set_members_prep(&pb->core, - channel_metadataid, - include, - set_obj, + channel, + opts.include, + uuids, + opts.filter, + opts.sort, + opts.limit, + opts.page.next, + opts.page.prev, + opts.count, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_SET_MEMBERS; @@ -526,10 +846,23 @@ enum pubnub_res pubnub_set_members(pubnub_t* pb, } + enum pubnub_res pubnub_remove_members(pubnub_t* pb, char const* channel_metadataid, char const* include, char const* remove_obj) +{ + struct pubnub_members_opts opts = pubnub_members_defopts(); + opts.include = include; + + return pubnub_remove_members_ex(pb, channel_metadataid, remove_obj, opts); +} + + +enum pubnub_res pubnub_remove_members_ex(pubnub_t* pb, + char const* channel, + char const* uuids, + struct pubnub_members_opts opts) { enum pubnub_res rslt; char obj_buffer[PUBNUB_BUF_MAXLEN]; @@ -547,13 +880,19 @@ enum pubnub_res pubnub_remove_members(pubnub_t* pb, "pubnub_remove_members", obj_buffer, "{\"delete\":", - remove_obj); + uuids); pb->method = pubnubUsePATCH; pb->trans = PBTT_REMOVE_MEMBERS; rslt = pbcc_set_members_prep(&pb->core, - channel_metadataid, - include, - remove_obj, + channel, + opts.include, + uuids, + opts.filter, + opts.sort, + opts.limit, + opts.page.next, + opts.page.prev, + opts.count, pb->trans); if (PNR_STARTED == rslt) { pb->trans = PBTT_REMOVE_MEMBERS; @@ -567,5 +906,6 @@ enum pubnub_res pubnub_remove_members(pubnub_t* pb, return rslt; } + #endif /* PUBNUB_USE_OBJECTS_API */ diff --git a/Source/ThirdParty/sdk/Include/core/pubnub_objects_api.h b/Source/ThirdParty/sdk/Include/core/pubnub_objects_api.h index e487e17..73a61de 100644 --- a/Source/ThirdParty/sdk/Include/core/pubnub_objects_api.h +++ b/Source/ThirdParty/sdk/Include/core/pubnub_objects_api.h @@ -9,7 +9,113 @@ #include "pubnub_api_types.h" #include "lib/pb_extern.h" -#include +/** Data pagination object. This object helps to paginate through the data. + It is more readable form of `start` and `end` parameters in objects API. + */ +struct pubnub_page_object { + /** The URL for the next page of results. If there is no next page, this field is null. */ + char const* next; + + /** The URL for the previous page of results. If there is no previous page, this field is null. */ + char const* prev; +}; + + +/** User data object. This object represents the user data. */ +struct pubnub_user_data { + + /** Name Display name for the user. */ + char const* name; + + /** User's identifier in an external system */ + char const* external_id; + + /** The URL of the user's profile picture */ + char const* profile_url; + + /** The user's email. */ + char const* email; + + /** JSON providing custom data about the user. Values must be scalar only; arrays or objects are not supported. + Filtering App Context data through the custom property is not recommended in SDKs. */ + char const* custom; +}; + + +/** Channel data object. This object represents the channel data. */ +struct pubnub_channel_data { + /** Display name for the channel. */ + char const* name; + + /** The channel's description. */ + char const* description; + + /** JSON providing custom data about the channel. Values must be scalar only; arrays or objects are not supported. + Filtering App Context data through the custom property is not recommended in SDKs. */ + char const* custom; +}; + + +/** The "null" page object, which is used to indicate that there is no next or previous page. + Also it can be used when there is no will to pass page as a parameter + */ +PUBNUB_EXTERN const struct pubnub_page_object pubnub_null_page; + + +/** The "null" user data object, which is used to indicate that there is no user data. + Also it can be used when there is no will to pass user data as a parameter + */ +PUBNUB_EXTERN const struct pubnub_user_data pubnub_null_user_data; + + +/** The "null" channel data object, which is used to indicate that there is no channel data. + Also it can be used when there is no will to pass channel data as a parameter + */ +PUBNUB_EXTERN const struct pubnub_channel_data pubnub_null_channel_data; + + +/** Options for the getall_*metadata functions */ +struct pubnub_getall_metadata_opts { + /** The comma delimited (C) string with additional/complex attributes to include in response. + Use NULL if you don't want to retrieve additional attributes. */ + char const* include; + + /** Expression used to filter the results. Only objects whose properties satisfy the given expression are returned. */ + char const* filter; + + /** Key-value pair of a property to sort by, and a sort direction. Available options are id, name, and updated. + Use asc or desc to specify sort direction, or specify null to take the default sort direction (ascending). + For example: {name: 'asc'} */ + char const* sort; + + /** Number of entities to return in response. Regular values 1 - 100. If you set `0`, + that means “use the default”. At the time of this writing, default was 100. */ + size_t limit; + + /** Pagination object. + @see pubnub_page_object */ + struct pubnub_page_object page; + + /** Request totalCount to be included in paginated response. By default, totalCount is omitted. */ + enum pubnub_tribool count; +}; + + +/** Default options for the set_*metadata functions + Values are set as follows: + - include: NULL + - filter: NULL + - sort: NULL + - limit: 100 + - page: pubnub_null_page + - count: pbccNotSet + + @see pubnub_getall_metadata_opts + @see pubnub_null_page + + @return Default options for the set_*metadata functions + */ +PUBNUB_EXTERN struct pubnub_getall_metadata_opts pubnub_getall_metadata_defopts(); /** Returns a paginated list of metadata objects for users associated with the subscription key of the context @p pbp, @@ -35,6 +141,21 @@ PUBNUB_EXTERN enum pubnub_res pubnub_getall_uuidmetadata(pubnub_t* pb, char const* end, enum pubnub_tribool count); + +/** Returns a paginated list of metadata objects for users associated with the subscription key of the context @p pbp, + optionally including each record's custom data object. + + Use `pubnub_getall_metadata_defopts()` to get the default options. + + @see pubnub_getall_metadata_defopts + + @param pb The pubnub context. Can't be NULL + @param opts The options for the getall_uuidmetadata function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_getall_uuidmetadata_ex(pubnub_t* pb, struct pubnub_getall_metadata_opts opts); + + /** Creates a metadata for a uuid with the attributes specified in @p uuid_metadata_obj. Returns the created metadata uuid object, optionally including the user's custom data object. @note User ID and name are required properties in the @p uuid_metadata_obj @@ -53,6 +174,47 @@ PUBNUB_EXTERN enum pubnub_res pubnub_set_uuidmetadata(pubnub_t* pb, char const* uuid_metadata_obj); +/** Options for the `pubnub_set_uuidmetadata_ex` function */ +struct pubnub_set_uuidmetadata_opts { + /** Uuid of the user. */ + char const* uuid; + + /** The comma delimited (C) string with additional/complex attributes to include in response. + Use NULL if you don't want to retrieve additional attributes. */ + char const* include; + + /** The user data object. */ + struct pubnub_user_data data; +}; + +/** Default options for the set_uuidmetadata functions + Values are set as follows: + - uuid: NULL (`pubnub_set_uuidmetadata_ex` will take the user_id from the context on NULL) + - include: NULL + - data: pubnub_null_user_data + + @see pubnub_null_user_data + + @return Default options for the set_uuidmetadata functions + */ +PUBNUB_EXTERN struct pubnub_set_uuidmetadata_opts pubnub_set_uuidmetadata_defopts(); + + +/** Creates a metadata for a uuid with the attributes specified in @p opts. + Returns the created metadata uuid object, optionally including the user's custom data object. + + Use `pubnub_set_uuidmetadata_defopts()` to get the default options. + + @see pubnub_set_uuidmetadata_defopts + + @param pb The pubnub context. Can't be NULL + @param uuid The UUID to create the metadata for. If NULL, the user_id will be taken from the context. + @param opts The options for the set_uuidmetadata function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_set_uuidmetadata_ex(pubnub_t* pb, struct pubnub_set_uuidmetadata_opts opts); + + /** Returns the uuid metadata object specified with @p user_id, optionally including the user's custom data object. @param pb The pubnub context. Can't be NULL @@ -67,7 +229,6 @@ PUBNUB_EXTERN enum pubnub_res pubnub_get_uuidmetadata(pubnub_t* pb, char const* uuid_metadataid); - /** Deletes the uuid metadata specified with @p uuid_metadataid. @param pb The pubnub context. Can't be NULL @param uuid_metadataid The UUID Metatdata ID. Cannot be NULL. @@ -100,6 +261,20 @@ PUBNUB_EXTERN enum pubnub_res pubnub_getall_channelmetadata(pubnub_t* pb, enum pubnub_tribool count); +/** Returns the spaces associated with the subscriber key of the context @p pbp, optionally + including each space's custom data object. + + Use `pubnub_getall_metadata_defopts()` to get the default options. + + @see pubnub_getall_metadata_defopts + + @param pb The pubnub context. Can't be NULL + @param opts The options for the getall_channelmetadata function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_getall_channelmetadata_ex(pubnub_t* pb, struct pubnub_getall_metadata_opts opts); + + /** Creates a metadata for the specified channel with the attributes specified in @p channel_metadata_obj. Returns the created space object, optionally including its custom data object. @note Channel ID and name are required properties of @p channel_metadata_obj @@ -115,6 +290,44 @@ PUBNUB_EXTERN enum pubnub_res pubnub_set_channelmetadata(pubnub_t* pb, char const* channel_metadata_obj); +/** Options for the `pubnub_set_channelmetadata_ex` function */ +struct pubnub_set_channelmetadata_opts { + /** The comma delimited (C) string with additional/complex attributes to include in response. + Use NULL if you don't want to retrieve additional attributes. */ + char const* include; + + /** The channel data object. */ + struct pubnub_channel_data data; +}; + + +/** Default options for the set_channelmetadata functions. + Values are set as follows: + - include: NULL + - data: pubnub_null_channel_data + + @see pubnub_null_channel_data + + @return Default options for the set_channelmetadata_ex function. + */ +PUBNUB_EXTERN struct pubnub_set_channelmetadata_opts pubnub_set_channelmetadata_defopts(); + + +/** Creates a metadata for the specified channel with the attributes specified in @p opts. + Returns the created space object, optionally including its custom data object. + + Use `pubnub_set_channelmetadata_defopts()` to get the default options. + + @see pubnub_set_channelmetadata_defopts + + @param pb The pubnub context. Can't be NULL + @param channel The channel to create the metadata for. If NULL, the channel will be taken from the context. + @param opts The options for the set_channelmetadata function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_set_channelmetadata_ex(pubnub_t* pb, char const* channel, struct pubnub_set_channelmetadata_opts opts); + + /** Returns the channel metadata object specified with @p channel_metadataid, optionally including its custom data object. @param pb The pubnub context. Can't be NULL @@ -137,6 +350,52 @@ PUBNUB_EXTERN enum pubnub_res pubnub_get_channelmetadata(pubnub_t* pb, PUBNUB_EXTERN enum pubnub_res pubnub_remove_channelmetadata(pubnub_t* pb, char const* channel_metadataid); +/** Options for the pubnub_get_memberships function */ +struct pubnub_membership_opts { + /** The UUID to retrieve the memberships. */ + char const* uuid; + + /** The comma delimited (C) string with additional/complex attributes to include in response. + Use NULL if you don't want to retrieve additional attributes. */ + char const* include; + + /** Expression used to filter the results. Only objects whose properties satisfy the given expression are returned. */ + char const* filter; + + /** Key-value pair of a property to sort by, and a sort direction. Available options are id, name, and updated. + Use asc or desc to specify sort direction, or specify null to take the default sort direction (ascending). + For example: {name: 'asc'} */ + char const* sort; + + /** Number of entities to return in response. Regular values 1 - 100. If you set `0`, + that means “use the default”. At the time of this writing, default was 100. */ + size_t limit; + + /** Pagination object. + @see pubnub_page_object */ + struct pubnub_page_object page; + + /** Request totalCount to be included in paginated response. By default, totalCount is omitted. */ + enum pubnub_tribool count; +}; + + +/** Default options for the pubnub_get_memberships function + Values are set as follows: + - uuid: NULL (`pubnub_*_memberships_ex` will take the user_id from the context on NULL) + - include: NULL + - filter: NULL + - sort: NULL + - limit: 100 + - page: pubnub_null_page + + @see pubnub_null_page + + @return Default options for the get_memberships function + */ +PUBNUB_EXTERN struct pubnub_membership_opts pubnub_memberships_defopts(); + + /** Returns the channel memberships of the user specified by @p uuid_metadataid, optionally including the custom data objects for... @param pb The pubnub context. Can't be NULL @@ -165,6 +424,20 @@ PUBNUB_EXTERN enum pubnub_res pubnub_get_memberships(pubnub_t* pb, enum pubnub_tribool count); +/** Returns the channel memberships of the user specified by @p uuid_metadataid, optionally including + the custom data objects for... + + Use `pubnub_memberships_defopts()` to get the default options. + + @see pubnub_memberships_defopts + + @param pb The pubnub context. Can't be NULL + @param opts The options for the get_memberships function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_get_memberships_ex(pubnub_t* pb, struct pubnub_membership_opts opts); + + /** Add/Update the channel memberships of the UUID specified by @p metadata_uuid. Uses the `set` property to perform those operations on one, or more memberships. An example for @set_obj: @@ -198,6 +471,37 @@ PUBNUB_EXTERN enum pubnub_res pubnub_set_memberships(pubnub_t* pb, char const* set_obj); +/** Add/Update the channel memberships of the UUID specified by @p metadata_uuid. Uses the `set` property + to perform those operations on one, or more memberships. + An example for @channels: + [ + { + "channel":{ "id": "main-channel-id" }, + "custom": { + "starred": true + } + }, + { + "channel":{ "id": "channel-0" }, + "some_key": { + "other_key": "other_value" + } + } + ] + + Use `pubnub_memberships_defopts()` to get the default options. + + @see pubnub_memberships_defopts + + @param pb The pubnub context. Can't be NULL + @param channels The JSON object that defines the add/update to perform. + Cannot be NULL. + @param opts The options for the set_memberships function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_set_memberships_ex(pubnub_t* pb, char const* channels, struct pubnub_membership_opts opts); + + /** Removes the memberships of the user specified by @p uuid_metadataid. Uses the `delete` property to perform those operations on one, or more memberships. An example for @remove_obj: @@ -225,6 +529,75 @@ PUBNUB_EXTERN enum pubnub_res pubnub_remove_memberships(pubnub_t* pb, char const* remove_obj); +/** Removes the memberships of the user specified by @p uuid_metadataid. Uses the `delete` property + to perform those operations on one, or more memberships. + An example for @channels: + [ + { + "channel":{ "id": "main-channel-id" } + }, + { + "channel":{ "id": "channel-0" } + } + ] + + Use `pubnub_memberships_defopts()` to get the default options. + + @see pubnub_memberships_defopts + + @param pb The pubnub context. Can't be null + @param channels The JSON object that defines the remove to perform. + Cannot be NULL. + @param opts The options for the remove_memberships function. + + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_remove_memberships_ex(pubnub_t* pb, char const* channels, struct pubnub_membership_opts opts); + + +/** Options for the pubnub_*_members functions */ +struct pubnub_members_opts { + /** The comma delimited (C) string with additional/complex attributes to include in response. + Use NULL if you don't want to retrieve additional attributes. */ + char const* include; + + /** Expression used to filter the results. Only objects whose properties satisfy the given expression are returned. */ + char const* filter; + + /** Key-value pair of a property to sort by, and a sort direction. Available options are id, name, and updated. + Use asc or desc to specify sort direction, or specify null to take the default sort direction (ascending). + For example: {name: 'asc'} */ + char const* sort; + + /** Number of entities to return in response. Regular values 1 - 100. If you set `0`, + that means “use the default”. At the time of this writing, default was 100. */ + size_t limit; + + /** Pagination object. + @see pubnub_page_object */ + struct pubnub_page_object page; + + /** Request totalCount to be included in paginated response. By default, totalCount is omitted. */ + enum pubnub_tribool count; +}; + + +/** Default options for the pubnub_get_members functions + Values are set as follows: + - include: NULL + - filter: NULL + - sort: NULL + - limit: 100 + - page: pubnub_null_page + - count: pbNotSet + + @see pubnub_null_page + + @return Default options for the get_members function + */ +PUBNUB_EXTERN struct pubnub_members_opts pubnub_members_defopts(); + + /** Returns all users in the channel specified with @p channel_metadataid, optionally including the custom data objects for... @param pb The pubnub context. Can't be NULL @@ -252,6 +625,21 @@ PUBNUB_EXTERN enum pubnub_res pubnub_get_members(pubnub_t* pb, enum pubnub_tribool count); +/** Returns all users in the channel specified with @p channel_metadataid, optionally including + the custom data objects for... + + Use `pubnub_get_members_defopts()` to get the default options. + + @see pubnub_get_members_defopts + + @param pb The pubnub context. Can't be NULL + @param channel The channel to retrieve the members for. + @param opts The options for the get_members function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_get_members_ex(pubnub_t* pb, char const* channel, struct pubnub_members_opts opts); + + /** Adds the list of members of the channel specified with @p channel_metadataid. Uses the `add` property to perform the operation on one or more members. An example for @add_obj: @@ -308,20 +696,47 @@ PUBNUB_EXTERN enum pubnub_res pubnub_set_members(pubnub_t* pb, char const* set_obj); +/** Updates the list of members of the space specified with @p space_id. Uses the `update` + property to perform the operation on one or more members. + An example for @uuids: + [ + { + "id": "some-user-id", + "custom": { + "starred": true + } + }, + { + "id": "user-0-id", + "some_key": { + "other_key": "other_value" + } + } + ] + + @param pb The pubnub context. Can't be NULL + @param channel The channel to add/update the members. + @param uuids The JSON object that defines the add/update to perform. Cannot be NULL. + @param opts The options for the set_members function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_set_members_ex(pubnub_t* pb, + char const* channel, + char const* uuids, + struct pubnub_members_opts opts); + + /** Removes the list of members of the space specified with @p space_id. Uses the `remove` property to perform the operation on one or more members. An example for @update_obj: [ - { - "id": "some-user-id", - "custom": { - "starred": true - } - }, - { - "id": "user-0-id" - } - ] + { + "uuid":{ "id": "main-user-id" } + }, + { + "uuid":{ "id": "user-0" } + } + ] @param pb The pubnub context. Can't be NULL @param channel_metadataid The Channel ID. @@ -336,6 +751,33 @@ PUBNUB_EXTERN enum pubnub_res pubnub_remove_members(pubnub_t* pb, char const* remove_obj); +/** Removes the list of members of the space specified with @p space_id. Uses the `remove` + property to perform the operation on one or more members. + An example for @uuids: + [ + { + "id": "some-user-id", + "custom": { + "starred": true + } + }, + { + "id": "user-0-id" + } + ] + + @param pb The pubnub context. Can't be NULL + @param channel The channel to remove the members. + @param uuids The JSON object that defines the remove to perform. Cannot be NULL. + @param opts The options for the remove_members function. + @return #PNR_STARTED on success, an error otherwise + */ +PUBNUB_EXTERN enum pubnub_res pubnub_remove_members_ex(pubnub_t* pb, + char const* channel, + char const* uuids, + struct pubnub_members_opts opts); + + #endif /* !defined INC_PUBNUB_OBJECTS_API */ #endif /* PUBNUB_USE_OBJECTS_API */ diff --git a/Source/ThirdParty/sdk/Include/core/pubnub_pubsubapi.c b/Source/ThirdParty/sdk/Include/core/pubnub_pubsubapi.c index 972d506..cf68eaa 100644 --- a/Source/ThirdParty/sdk/Include/core/pubnub_pubsubapi.c +++ b/Source/ThirdParty/sdk/Include/core/pubnub_pubsubapi.c @@ -107,7 +107,8 @@ enum pubnub_res pubnub_publish(pubnub_t* pb, const char* channel, const char* me return PNR_IN_PROGRESS; } - rslt = pbcc_publish_prep(&pb->core, channel, message, true, false, NULL, pubnubSendViaGET); + rslt = pbcc_publish_prep( + &pb->core, channel, message, true, false, NULL, SIZE_MAX, pubnubSendViaGET); if (PNR_STARTED == rslt) { pb->trans = PBTT_PUBLISH; pb->core.last_result = PNR_STARTED; diff --git a/Source/ThirdParty/sdk/Include/core/pubnub_url_encode.c b/Source/ThirdParty/sdk/Include/core/pubnub_url_encode.c index 616972d..ec125b7 100644 --- a/Source/ThirdParty/sdk/Include/core/pubnub_url_encode.c +++ b/Source/ThirdParty/sdk/Include/core/pubnub_url_encode.c @@ -32,7 +32,9 @@ int pubnub_url_encode(char* buffer, char const* what, size_t buffer_size, enum p case PBTT_ADD_MEMBERS: case PBTT_SET_MEMBERS: case PBTT_REMOVE_MEMBERS: +#if PUBNUB_USE_ADVANCED_HISTORY case PBTT_MESSAGE_COUNTS: +#endif // PUBNUB_USE_ADVANCED_HISTORY #endif // PUBNUB_USE_OBJECTS_API #if PUBNUB_USE_REVOKE_TOKEN_API case PBTT_REVOKE_TOKEN: diff --git a/Source/ThirdParty/sdk/Include/core/pubnub_version_internal.h b/Source/ThirdParty/sdk/Include/core/pubnub_version_internal.h index e270e16..84b8626 100644 --- a/Source/ThirdParty/sdk/Include/core/pubnub_version_internal.h +++ b/Source/ThirdParty/sdk/Include/core/pubnub_version_internal.h @@ -3,7 +3,7 @@ #define INC_PUBNUB_VERSION_INTERNAL -#define PUBNUB_SDK_VERSION "4.9.0" +#define PUBNUB_SDK_VERSION "4.13.0" #endif /* !defined INC_PUBNUB_VERSION_INTERNAL */ diff --git a/Source/ThirdParty/sdk/Include/core/samples/pubnub_advanced_history_sample.c b/Source/ThirdParty/sdk/Include/core/samples/pubnub_advanced_history_sample.c index b92b1f1..61d238f 100644 --- a/Source/ThirdParty/sdk/Include/core/samples/pubnub_advanced_history_sample.c +++ b/Source/ThirdParty/sdk/Include/core/samples/pubnub_advanced_history_sample.c @@ -328,6 +328,35 @@ static void get_message_counts_for_the_list_of_timetokens(pubnub_t* pbp, internal_msg_counts); } +static int get_message_counts_for_the_channel(pubnub_t* pbp, char* channel, char* timetoken) +{ + enum pubnub_res count_res = pubnub_message_counts(pbp, channel, timetoken); + if (count_res == PNR_STARTED) { + count_res = pubnub_await(pbp); + } + if (PNR_OK != count_res) { + return -1; + } + + int count = 0; + pubnub_get_message_counts(pbp, channel, &count); + + return count; +} + +static enum pubnub_res delete_channel_messages(pubnub_t* pbp, char* channel, char* start, char* end) +{ + struct pubnub_delete_messages_options options = pubnub_delete_messages_defopts(); + if (NULL != start) { options.start = start; } + if (NULL != end) { options.end = end; } + + enum pubnub_res delete_res = pubnub_delete_messages(pbp, channel, options); + if (delete_res == PNR_STARTED) { + delete_res = pubnub_await(pbp); + } + + return delete_res; +} int main(int argc, char* argv[]) { @@ -368,11 +397,43 @@ int main(int argc, char* argv[]) get_message_counts_for_a_single_timetoken(pbp_2, string_channels, sizeof m_timetokens/sizeof m_timetokens[0]); - - sync_sample_free(pbp_2); - sync_sample_free(pbp); + puts("Pubnub message_counts demo over."); + puts("Pubnub delete_message demo start."); + enum pubnub_res delete_res = delete_channel_messages(pbp, m_channel[4], m_timetokens[1], m_timetokens[3]); + if (PNR_OK != delete_res) { + printf("Delete messages failed with code: %d('%s')\n", delete_res, pubnub_res_2_string(delete_res)); + sync_sample_free(pbp_2); + sync_sample_free(pbp); + return -1; + } + + int count = get_message_counts_for_the_channel(pbp, m_channel[4], m_timetokens[0]); + if (count != 3) { + printf("It is expected that 2 of 5 messages to be removed. There is %d messages in %s\n", count, m_channel[4]); + return -1; + } + + delete_res = delete_channel_messages(pbp, m_channel[3], NULL, NULL); + if (PNR_OK != delete_res) { + printf("Delete messages failed with code: %d('%s')\n", delete_res, pubnub_res_2_string(delete_res)); + sync_sample_free(pbp_2); + sync_sample_free(pbp); + return -1; + } + + count = get_message_counts_for_the_channel(pbp, m_channel[3], m_timetokens[0]); + if (count != 0) { + printf("It is expected that 4 of 4 messages to be removed. There is %d messages in %s\n", count, m_channel[3]); + return -1; + } + + puts("Pubnub delete_message demo is over."); + + sync_sample_free(pbp_2); + sync_sample_free(pbp); + return 0; } diff --git a/Source/ThirdParty/sdk/Include/core/samples/pubnub_fetch_history_sample.c b/Source/ThirdParty/sdk/Include/core/samples/pubnub_fetch_history_sample.c index 906883c..03e19fd 100644 --- a/Source/ThirdParty/sdk/Include/core/samples/pubnub_fetch_history_sample.c +++ b/Source/ThirdParty/sdk/Include/core/samples/pubnub_fetch_history_sample.c @@ -147,8 +147,21 @@ int main(int argc, char* argv[]) res = pubnub_await(pbp); } if (PNR_OK == res) { + pubnub_chamebl_t response = pubnub_get_fetch_history(pbp); printf("Got response for Fetch History! Response from Pubnub: %s\n", - pubnub_get_fetch_history(pbp).ptr); + response.ptr); + if (NULL == strstr(response.ptr, "\"message_type\"")) { + printf("\"message_type\" is missing in response."); + return 1; + } + if (NULL == strstr(response.ptr, "\"uuid\"")) { + printf("\"uuid\" is missing in response."); + return 1; + } + if (NULL == strstr(response.ptr, "\"meta\"")) { + printf("\"meta\" is missing in response."); + return 1; + } } else{ printf("pubnub_fetch_history() failed with code: %d('%s')\n", diff --git a/Source/ThirdParty/sdk/Include/core/samples/pubnub_objects_api_sample.c b/Source/ThirdParty/sdk/Include/core/samples/pubnub_objects_api_sample.c new file mode 100644 index 0000000..7c84d1a --- /dev/null +++ b/Source/ThirdParty/sdk/Include/core/samples/pubnub_objects_api_sample.c @@ -0,0 +1,473 @@ +#include "pubnub_api_types.h" +#include "pubnub_blocking_io.h" +#include "pubnub_pubsubapi.h" +#include "core/pubnub_helper.h" +#include "core/pubnub_alloc.h" +#include "core/pubnub_ntf_sync.h" +#include "core/pubnub_objects_api.h" +#include +#include + +// This sample demo is split into 4 sections: +// 1. UUID metadata section +// 2. Channels metadata section +// 3. Memberships section +// 4. Members section +// +// You can navigate to each section by searching for the section name. +// +// Each section shows basic usage of the Pubnub Objects API. +// There are more options available for each API call, +// which can be found in the Pubnub Objects API documentation. + +static void sync_sample_free(pubnub_t* p); + +int main(void) { + // No demo keysets as app context is not applicable to it + char* publish_key = getenv("PUBNUB_PUBLISH_KEY"); + char* subscribe_key = getenv("PUBNUB_SUBSCRIBE_KEY"); + + enum pubnub_res result; + + pubnub_t* pb = pubnub_alloc(); + if (NULL == pb) { + printf("Failed to allocate Pubnub context!\n"); + return -1; + } + + pubnub_init(pb, publish_key, subscribe_key); + pubnub_set_user_id(pb, "my_user"); + + // Depending on requirements, you can use non-blocking I/O + pubnub_set_blocking_io(pb); + + printf("~~~~~~~~~~~~~~~~~~uuid metadata section~~~~~~~~~~~~~~~~~~\n"); + + printf("Set users' metadata\n"); + struct pubnub_set_uuidmetadata_opts set_opts = pubnub_set_uuidmetadata_defopts(); + set_opts.data.name = "my_name"; + set_opts.data.external_id = "my_external_id"; + set_opts.data.profile_url = "my_profile_url"; + set_opts.data.email = "my_email"; + set_opts.data.custom = "{\"key\":\"value\"}"; + set_opts.include = "custom"; + + // we didn't set the UUID, so it will be the one from the context + result = pubnub_set_uuidmetadata_ex(pb, set_opts); + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Set UUID metadata successful!\n"); + } else { + printf("Set UUID metadata failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + struct pubnub_set_uuidmetadata_opts set_opts2 = pubnub_set_uuidmetadata_defopts(); + set_opts2.data.custom = "{\"key\":\"totally different value\"}"; + set_opts2.uuid = "some_user"; + + result = pubnub_set_uuidmetadata_ex(pb, set_opts2); + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Set UUID metadata successful!\n"); + } else { + printf("Set UUID metadata failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + printf("Get users' metadata\n"); + struct pubnub_getall_metadata_opts getall_opts = pubnub_getall_metadata_defopts(); + // getall_opts.page.next = you can retrieve the next page in the response when the response is paginated + // getall_opts.page.prev = as above + getall_opts.limit = 1; + getall_opts.include = "custom"; + getall_opts.filter = "name=='my_name'"; + getall_opts.count = pbccTrue; + getall_opts.sort = "name:desc"; + + result = pubnub_getall_uuidmetadata_ex(pb, getall_opts); + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Get UUID metadata successful!\n"); + + for (const char* response = pubnub_get(pb); response != NULL; response = pubnub_get(pb)) { + printf("Response: %s\n", response); + } + } else { + printf("Get UUID metadata failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Get users' metadata by UUID\n"); + result = pubnub_get_uuidmetadata(pb, "custom", "my_user"); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Get UUID metadata by UUID successful!\n"); + + const char* response = pubnub_get(pb); + printf("Response: %s\n", response); + } else { + printf("Get UUID metadata by UUID failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Remove users' metadata by UUID\n"); + + result = pubnub_remove_uuidmetadata(pb, "my_user"); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Remove UUID metadata successful!\n"); + } else { + printf("Remove UUID metadata failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + result = pubnub_remove_uuidmetadata(pb, "some_user"); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Remove UUID metadata successful!\n"); + } else { + printf("Remove UUID metadata failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + printf("~~~~~~~~~~~~~~~~channels metadata section~~~~~~~~~~~~~~~~\n"); + + printf("Set channels' metadata\n"); + struct pubnub_set_channelmetadata_opts set_channel_opts = pubnub_set_channelmetadata_defopts(); + set_channel_opts.data.name = "my_channel_name"; + set_channel_opts.data.description = "my_channel_description"; + set_channel_opts.data.custom = "{\"key\":\"value\"}"; + set_channel_opts.include = "custom"; + + result = pubnub_set_channelmetadata_ex(pb, "channel_id", set_channel_opts); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Set channel metadata successful!\n"); + } else { + printf("Set channel metadata failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Get channels' metadata\n"); + + struct pubnub_getall_metadata_opts getall_channel_opts = pubnub_getall_metadata_defopts(); + getall_channel_opts.limit = 1; + getall_channel_opts.include = "custom"; + getall_channel_opts.filter = "custom.key=='value'"; + getall_channel_opts.count = pbccTrue; + getall_channel_opts.sort = "name:desc"; + + result = pubnub_getall_channelmetadata_ex(pb, getall_channel_opts); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Get channel metadata successful!\n"); + + for (const char* response = pubnub_get(pb); response != NULL; response = pubnub_get(pb)) { + printf("Response: %s\n", response); + } + } else { + printf("Get channel metadata failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Get channels' metadata by channel ID\n"); + + result = pubnub_get_channelmetadata(pb, "custom", "channel_id"); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Get channel metadata by channel ID successful!\n"); + + const char* response = pubnub_get(pb); + printf("Response: %s\n", response); + } else { + printf("Get channel metadata by channel ID failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Remove channels' metadata by channel ID\n"); + result = pubnub_remove_channelmetadata(pb, "channel_id"); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Remove channel metadata successful!\n"); + } else { + printf("Remove channel metadata failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + printf("~~~~~~~~~~~~~~~~~~~memberships section~~~~~~~~~~~~~~~~~~~\n"); + + printf("Set users' memberships\n"); + struct pubnub_membership_opts set_memberships_opts = pubnub_memberships_defopts(); + set_memberships_opts.include = "custom"; + set_memberships_opts.limit = 1; + set_memberships_opts.sort = "channel.name:desc"; + set_memberships_opts.filter = "custom.key=='value'"; + set_memberships_opts.count = pbccTrue; + + const char* channels_meta = "[" + "{" + "\"channel\":{ \"id\": \"main-channel-id\" }," + "\"custom\": {" + "\"starred\": true" + "}" + "}," + "{" + "\"channel\":{ \"id\": \"channel-0\" }," + "\"some_key\": {" + "\"other_key\": \"other_value\"" + "}" + "}" + "]"; + + result = pubnub_set_memberships_ex(pb, channels_meta, set_memberships_opts); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Set memberships successful!\n"); + } else { + printf("Set memberships failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Get users' memberships by UUID\n"); + + struct pubnub_membership_opts get_memberships_opts = pubnub_memberships_defopts(); + get_memberships_opts.limit = 1; + get_memberships_opts.include = "custom"; + get_memberships_opts.filter = "custom.starred==true"; + get_memberships_opts.count = pbccTrue; + get_memberships_opts.sort = "channel.id:desc"; + + result = pubnub_get_memberships_ex(pb, get_memberships_opts); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Get memberships by UUID successful!\n"); + + const char* response = pubnub_get(pb); + printf("Response: %s\n", response); + } else { + printf("Get memberships by UUID failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Remove users' memberships by UUID\n"); + + struct pubnub_membership_opts remove_memberships_opts = pubnub_memberships_defopts(); + remove_memberships_opts.include = "custom"; + remove_memberships_opts.limit = 1; + remove_memberships_opts.sort = "channel.id:desc"; + remove_memberships_opts.filter = "custom.starred==true"; + remove_memberships_opts.count = pbccTrue; + + const char* channels_meta_remove = "[" + "{" + "\"channel\":{ \"id\": \"main-channel-id\" }" + "}," + "{" + "\"channel\":{ \"id\": \"channel-0\" }" + "}" + "]"; + + + result = pubnub_remove_memberships_ex(pb, channels_meta_remove, remove_memberships_opts); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Remove memberships successful!\n"); + } else { + printf("Remove memberships failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + printf("~~~~~~~~~~~~~~~~~~~~~members section~~~~~~~~~~~~~~~~~~~~~\n"); + + printf("Set channels' members\n"); + + struct pubnub_members_opts set_members_opts = pubnub_members_defopts(); + set_members_opts.include = "custom"; + set_members_opts.limit = 1; + set_members_opts.sort = "uuid.id:desc"; + set_members_opts.filter = "custom.starred==true"; + set_members_opts.count = pbccTrue; + + const char* members_meta = "[" + "{" + "\"uuid\":{ \"id\": \"main-user-id\" }," + "\"custom\": {" + "\"starred\": true" + "}" + "}," + "{" + "\"uuid\":{ \"id\": \"user-0\" }," + "\"some_key\": {" + "\"other_key\": \"other_value\"" + "}" + "}" + "]"; + + result = pubnub_set_members_ex(pb, "channel_id", members_meta, set_members_opts); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Set members successful!\n"); + } else { + printf("Set members failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Get channels' members\n"); + + struct pubnub_members_opts get_members_opts = pubnub_members_defopts(); + get_members_opts.limit = 1; + get_members_opts.include = "custom"; + get_members_opts.filter = "custom.starred==true"; + get_members_opts.count = pbccTrue; + get_members_opts.sort = "uuid.id:desc"; + + result = pubnub_get_members_ex(pb, "channel_id", get_members_opts); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Get members successful!\n"); + + for (const char* response = pubnub_get(pb); response != NULL; response = pubnub_get(pb)) { + printf("Response: %s\n", response); + } + } else { + printf("Get members failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + sleep(1); + printf("Remove channels' members by UUID\n"); + + struct pubnub_members_opts remove_members_opts = pubnub_members_defopts(); + remove_members_opts.include = "custom"; + remove_members_opts.limit = 1; + remove_members_opts.sort = "uuid.id:desc"; + remove_members_opts.filter = "custom.starred==true"; + remove_members_opts.count = pbccTrue; + + const char* members_meta_remove = "[" + "{" + "\"uuid\":{ \"id\": \"main-user-id\" }" + "}," + "{" + "\"uuid\":{ \"id\": \"user-0\" }" + "}" + "]"; + + result = pubnub_remove_members_ex(pb, "channel_id", members_meta_remove, remove_members_opts); + + if (PNR_STARTED == result) { + result = pubnub_await(pb); + } + + if (PNR_OK == result) { + printf("Remove members successful!\n"); + } else { + printf("Remove members failed with code: %d('%s')\n", + result, + pubnub_res_2_string(result)); + } + + // ~~~~END OF SAMPLE~~~~ + + sync_sample_free(pb); + + return 0; +} + +static void sync_sample_free(pubnub_t* p) +{ + if (PN_CANCEL_STARTED == pubnub_cancel(p)) { + enum pubnub_res pnru = pubnub_await(p); + if (pnru != PNR_OK) { + printf("Awaiting cancel failed: %d('%s')\n", + pnru, + pubnub_res_2_string(pnru)); + } + } + if (pubnub_free(p) != 0) { + printf("Failed to free the Pubnub context\n"); + } +} + + diff --git a/Source/ThirdParty/sdk/Include/core/samples/pubnub_publish_via_post_sample.c b/Source/ThirdParty/sdk/Include/core/samples/pubnub_publish_via_post_sample.c index 85917a6..4c60bd3 100644 --- a/Source/ThirdParty/sdk/Include/core/samples/pubnub_publish_via_post_sample.c +++ b/Source/ThirdParty/sdk/Include/core/samples/pubnub_publish_via_post_sample.c @@ -136,6 +136,33 @@ int main() pubnub_res_2_string(res)); } + puts("========================================="); + puts("Publishing(via post with ttl)..."); + time(&t0); + struct pubnub_publish_options options = publish_opts_method(pubnubSendViaPOSTwithGZIP); + options.ttl = 16; + res = pubnub_publish_ex(pbp, + chan, + "\"Hello world!\"", + options); + if (PNR_STARTED == res) { + res = pubnub_await(pbp); + } + printf("Publish 'via post with ttl' lasted %lf seconds.\n", difftime(time(NULL), t0)); + if (PNR_OK == res) { + printf("Published! Response from Pubnub: %s\n", + pubnub_last_publish_result(pbp)); + } + else if (PNR_PUBLISH_FAILED == res) { + printf("Publishing failed on Pubnub, description: %s\n", + pubnub_last_publish_result(pbp)); + } + else { + printf("Publishing failed with code: %d('%s')\n", + res, + pubnub_res_2_string(res)); + } + puts("========================================="); /* Publishing via post with gzip */ puts("Publishing(via post with gzip)..."); diff --git a/Source/ThirdParty/sdk/Include/freertos/README.md b/Source/ThirdParty/sdk/Include/freertos/README.md index 8c8de34..0043ea5 100644 --- a/Source/ThirdParty/sdk/Include/freertos/README.md +++ b/Source/ThirdParty/sdk/Include/freertos/README.md @@ -46,4 +46,38 @@ projects/makefiles for others at this time. Pubnub may provide support for other TCP/IP stacks on FreeRTOS in the future -There is yet no support for a SSL/TLS library. +There is yet no support for a SSL/TLS library (excluding ESP32 platform). + +## ESP32 support + +You can build the FreeRTOS+TCP Pubnub C-core for the ESP32 platform +using the ESP-IDF build system. The ESP-IDF build system is based on +CMake and we provide a CMakeLists.txt file for building the Pubnub +C-core for the ESP32 platform as idf_component. + +Additionally, we support SSL/TLS on the ESP32 platform using the +mbedTLS library. +All you have to do is to set the `MBEDTLS` option to `ON` +when configuring the build system. + +To use the Pubnub C-core in your ESP-IDF project you can select the +one of the following options: + +### ESP-IDF registry + +> :warning: **Note**: This option is not available yet. :warning: + +### clone the repository + +You can clone the repository and add it as a component to your project. +All you have to do is to ensure that your project is capable of building +external components. You can find more information about this in the +[ESP-IDF documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html#external-components). + +```sh +# in root directory of your project +git clone https://github.com/pubnub/c-core.git components/c-core +``` + +Then calling the `idf.py build` command should look into the components +directory, find the Pubnub C-core and build it as a part of your project. diff --git a/Source/ThirdParty/sdk/Include/freertos/msstopwatch_esp32.c b/Source/ThirdParty/sdk/Include/freertos/msstopwatch_esp32.c new file mode 100644 index 0000000..17017e1 --- /dev/null +++ b/Source/ThirdParty/sdk/Include/freertos/msstopwatch_esp32.c @@ -0,0 +1,44 @@ +/* -*- c-file-style:"stroustrup"; indent-tabs-mode: nil -*- */ + +#include "lib/msstopwatch/msstopwatch.h" +#include "freertos/pbtimespec_elapsed_ms_esp32.h" +#include "pubnub_assert.h" +#include + +/** This uses our helper module that provides a monotonic + clock like POSIX clock_gettime(CLOCK_MONOTONIC,...); +*/ + +static struct timespec msclock(void) +{ + struct timespec ts; + gettimeofday((struct timeval*)&ts, NULL); + + return ts; +} + + +pbmsref_t pbms_start(void) +{ + pbmsref_t result = { msclock() }; + return result; +} + + +void pbms_stop(pbmsref_t* psw) +{ + psw->t_ref.tv_nsec = -1; +} + + +bool pbms_active(pbmsref_t stopwatch) +{ + return stopwatch.t_ref.tv_nsec > -1; +} + + +pbms_t pbms_elapsed(pbmsref_t since) +{ + PUBNUB_ASSERT(pbms_active(since)); + return pbtimespec_elapsed_ms(since.t_ref, msclock()); +} diff --git a/Source/ThirdParty/sdk/Include/freertos/msstopwatch_pal.h b/Source/ThirdParty/sdk/Include/freertos/msstopwatch_pal.h new file mode 100644 index 0000000..45533fc --- /dev/null +++ b/Source/ThirdParty/sdk/Include/freertos/msstopwatch_pal.h @@ -0,0 +1,12 @@ +// TODO: find the proper way of handling time/ticks + +/* -*- c-file-style:"stroustrup"; indent-tabs-mode: nil -*- */ +#if !defined(INC_MSSTOPWATCH_PAL) +#define INC_MSSTOPWATCH_PAL + +#include + +typedef struct { struct timespec t_ref; } pbmsref_t; + + +#endif /* !defined(INC_MSSTOPWATCH_PAL) */ diff --git a/Source/ThirdParty/sdk/Include/freertos/pbpal_freertos_blocking_io.c b/Source/ThirdParty/sdk/Include/freertos/pbpal_freertos_blocking_io.c index 04ef581..b1da72a 100644 --- a/Source/ThirdParty/sdk/Include/freertos/pbpal_freertos_blocking_io.c +++ b/Source/ThirdParty/sdk/Include/freertos/pbpal_freertos_blocking_io.c @@ -2,11 +2,13 @@ #include "pbpal.h" #include "pubnub_internal.h" +#include "pubnub_log.h" #include int pbpal_set_blocking_io(pubnub_t *pb) { - return pb != pb; + PUBNUB_LOG_WARNING("pbpal_set_blocking_io() - Unsupported\n"); + return -1; } diff --git a/Source/ThirdParty/sdk/Include/freertos/pbpal_mutex.h b/Source/ThirdParty/sdk/Include/freertos/pbpal_mutex.h index 5089398..88b2fc8 100644 --- a/Source/ThirdParty/sdk/Include/freertos/pbpal_mutex.h +++ b/Source/ThirdParty/sdk/Include/freertos/pbpal_mutex.h @@ -16,14 +16,26 @@ typedef SemaphoreHandle_t pbpal_mutex_t; #define pbpal_mutex_destroy(m) vSemaphoreDelete(m) #define pbpal_mutex_decl_and_init(m) SemaphoreHandle_t m = xSemaphoreCreateMutex() #define pbpal_mutex_static_decl_and_init(m) static SemaphoreHandle_t m; static int m_init_##m + +// TODO: CRITICAL SECTION???? +#if ESP_PLATFORM +#define pbpal_mutex_init_static(m) do { \ + if (0 == m_init_##m) { \ + m = xSemaphoreCreateMutex(); \ + m_init_##m = 1; \ + } \ +} while(0) +#else #define pbpal_mutex_init_static(m) do { \ - taskENTER_CRITICAL(); \ + taskENTER_CRITICAL(m); \ if (0 == m_init_##m) { \ m = xSemaphoreCreateMutex(); \ m_init_##m = 1; \ } \ - taskEXIT_CRITICAL(); \ + taskEXIT_CRITICAL(m); \ } while(0) +#endif /*ESP_PLATFORM*/ + #endif /*!defined INC_PBPAL_MUTEX*/ diff --git a/Source/ThirdParty/sdk/Include/freertos/pbpal_resolv_and_connect_freertos_tcp.c b/Source/ThirdParty/sdk/Include/freertos/pbpal_resolv_and_connect_freertos_tcp.c index ec198a4..edd77c1 100644 --- a/Source/ThirdParty/sdk/Include/freertos/pbpal_resolv_and_connect_freertos_tcp.c +++ b/Source/ThirdParty/sdk/Include/freertos/pbpal_resolv_and_connect_freertos_tcp.c @@ -1,8 +1,14 @@ /* -*- c-file-style:"stroustrup"; indent-tabs-mode: nil -*- */ +#include "lwip/dns.h" +#include "lwip/inet.h" +#include "lwip/ip_addr.h" +#include "lwip/netdb.h" #include "pbpal.h" #include "pubnub_internal.h" #include "pubnub_assert.h" +#include "pubnub_log.h" +#include #define HTTP_PORT 80 @@ -10,30 +16,49 @@ enum pbpal_resolv_n_connect_result pbpal_resolv_and_connect(pubnub_t *pb) { - struct freertos_sockaddr addr; + struct sockaddr addr; PUBNUB_ASSERT(pb_valid_ctx_ptr(pb)); PUBNUB_ASSERT_OPT((pb->state == PBS_READY) || (pb->state == PBS_WAIT_DNS_SEND) || (pb->state == PBS_WAIT_DNS_RCV)); - addr.sin_port = FreeRTOS_htons(HTTP_PORT); - addr.sin_addr = FreeRTOS_gethostbyname(PUBNUB_ORIGIN_SETTABLE ? pb->origin : PUBNUB_ORIGIN); + addr.sin_port = htons(HTTP_PORT); + +#if ESP_PLATFORM + PUBNUB_LOG_TRACE("pbpal_resolv_and_connect: gethostbyname(%s)\n", + PUBNUB_ORIGIN_SETTABLE ? pb->origin : PUBNUB_ORIGIN); + + struct hostent *host = gethostbyname(PUBNUB_ORIGIN_SETTABLE ? pb->origin : PUBNUB_ORIGIN); + if (host == NULL) { + PUBNUB_LOG_ERROR("pbpal_resolv_and_connect: getting host failed!\n"); + return pbpal_resolv_failed_processing; + } + addr.sin_addr = *((struct in_addr *)host->h_addr_list[0]); + addr.sin_family = AF_INET; + memcpy(&addr.sin_addr, host->h_addr_list[0], host->h_length); + if (addr.sin_addr.s_addr == 0) { + PUBNUB_LOG_ERROR("pbpal_resolv_and_connect: no address found!\n"); + return pbpal_resolv_failed_processing; + } +#else + addr.sin_addr = gethostbyname(PUBNUB_ORIGIN_SETTABLE ? pb->origin : PUBNUB_ORIGIN); if (addr.sin_addr == 0) { return pbpal_resolv_failed_processing; } +#endif - pb->pal.socket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP); + pb->pal.socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (pb->pal.socket == SOCKET_INVALID) { return pbpal_connect_resource_failure; } - if (FreeRTOS_connect(pb->pal.socket, &addr, sizeof addr) != 0) { - FreeRTOS_closesocket(pb->pal.socket); + if (connect(pb->pal.socket, &addr, sizeof addr) != 0) { + closesocket(pb->pal.socket); pb->pal.socket = SOCKET_INVALID; return pbpal_connect_failed; } { TickType_t tmval = pdMS_TO_TICKS(pb->transaction_timeout_ms); - FreeRTOS_setsockopt(pb->pal.socket, 0, FREERTOS_SO_RCVTIMEO, &tmval, sizeof tmval); + setsockopt(pb->pal.socket, 0, SO_RCVTIMEO, &tmval, sizeof tmval); } return pbpal_connect_success; @@ -63,4 +88,4 @@ int pbpal_dns_rotate_server(pubnub_t *pb) return (pbp->flags.sent_queries < PUBNUB_MAX_DNS_QUERIES ? 0 : 1) } #endif /* PUBNUB_CHANGE_DNS_SERVERS */ -#endif /* defined(PUBNUB_CALLBACK_API) */ \ No newline at end of file +#endif /* defined(PUBNUB_CALLBACK_API) */ diff --git a/Source/ThirdParty/sdk/Include/freertos/pbtimespec_elapsed_ms_esp32.c b/Source/ThirdParty/sdk/Include/freertos/pbtimespec_elapsed_ms_esp32.c new file mode 100644 index 0000000..c2a4afc --- /dev/null +++ b/Source/ThirdParty/sdk/Include/freertos/pbtimespec_elapsed_ms_esp32.c @@ -0,0 +1,13 @@ +/* -*- c-file-style:"stroustrup"; indent-tabs-mode: nil -*- */ + +#include + +#define MILLI_IN_NANO 1000000 +#define UNIT_IN_MILLI 1000 + +int pbtimespec_elapsed_ms(struct timespec prev_timspec, struct timespec timspec) +{ + int s_diff = timspec.tv_sec - prev_timspec.tv_sec; + int m_s_diff = (timspec.tv_nsec - prev_timspec.tv_nsec) / MILLI_IN_NANO; + return (s_diff * UNIT_IN_MILLI) + m_s_diff; +} diff --git a/Source/ThirdParty/sdk/Include/freertos/pbtimespec_elapsed_ms_esp32.h b/Source/ThirdParty/sdk/Include/freertos/pbtimespec_elapsed_ms_esp32.h new file mode 100644 index 0000000..cbe11c5 --- /dev/null +++ b/Source/ThirdParty/sdk/Include/freertos/pbtimespec_elapsed_ms_esp32.h @@ -0,0 +1,9 @@ +/* -*- c-file-style:"stroustrup"; indent-tabs-mode: nil -*- */ +#if !defined(INC_PBMC_ELAPSED_MS) +#define INC_PBMC_ELAPSED_MS + +#include + +int pbtimespec_elapsed_ms(struct timespec prev_timspec, struct timespec timspec); + +#endif /* !defined(INC_PBMC_ELAPSED_MS) */ diff --git a/Source/ThirdParty/sdk/Include/freertos/pubnub_assert_freertos.c b/Source/ThirdParty/sdk/Include/freertos/pubnub_assert_freertos.c index c7bca9c..2f94290 100644 --- a/Source/ThirdParty/sdk/Include/freertos/pubnub_assert_freertos.c +++ b/Source/ThirdParty/sdk/Include/freertos/pubnub_assert_freertos.c @@ -4,8 +4,11 @@ //#include //#include #include +#include "pubnub_log.h" #include "task.h" +#ifndef ESP_PLATFORM #include "FreeRTOS_IP.h" +#endif static pubnub_assert_handler_t m_handler; @@ -31,7 +34,11 @@ void pubnub_assert_failed(char const *s, char const *file, long line) static void report(char const *s, char const *file, long line) { +#ifndef ESP_PLATFORM FreeRTOS_printf(("Pubnub assert failed '%s', file '%s', line %ld\n", s, file, line)); +#else + PUBNUB_LOG_ERROR("Pubnub assert failed '%s', file '%s', line %ld\n", s, file, line); +#endif } diff --git a/Source/ThirdParty/sdk/Include/freertos/pubnub_config.h b/Source/ThirdParty/sdk/Include/freertos/pubnub_config.h index 5fa924e..ef5edc5 100644 --- a/Source/ThirdParty/sdk/Include/freertos/pubnub_config.h +++ b/Source/ThirdParty/sdk/Include/freertos/pubnub_config.h @@ -84,6 +84,11 @@ #define PUBNUB_PROXY_API 1 #endif +#if PUBNUB_USE_GZIP_COMPRESSION +/* Maximum compressed message length allowed. Could be shortened by the user */ +#define PUBNUB_COMPRESSED_MAXLEN 1024 +#endif + /** The maximum length (in characters) of the host name of the proxy that will be saved in the Pubnub context. */ @@ -104,5 +109,64 @@ #define PUBNUB_ONLY_PUBSUB_API 0 #endif +#if !defined(PUBNUB_USE_SUBSCRIBE_V2) +/** If true (!=0) will enable using the subscribe v2 API, which + provides filter expressions and more data about messages. */ +#define PUBNUB_USE_SUBSCRIBE_V2 1 +#endif + +#if !defined(PUBNUB_USE_ADVANCED_HISTORY) +/** If true (!=0) will enable using the advanced history API, which + provides more data about (unread) messages. */ +#define PUBNUB_USE_ADVANCED_HISTORY 1 +#endif + +#if !defined(PUBNUB_USE_FETCH_HISTORY) +/** If true (!=0) will enable using the fetch history API, which + provides more data about single/multip channel messages. */ +#define PUBNUB_USE_FETCH_HISTORY 1 +#endif + +#if !defined(PUBNUB_USE_OBJECTS_API) +/** If true (!=0) will enable using the objects API, which is a + collection of Rest API features that enables "CRUD"(Create, Read, Update and Delete) + on two new pubnub objects: User and Space, as well as manipulating connections + between them. */ +#define PUBNUB_USE_OBJECTS_API 1 +#endif + +#if !defined(PUBNUB_USE_ACTIONS_API) +/** If true (!=0) will enable using the Actions API, which is a collection + of Rest API features that enables adding on, reading and removing actions + from published messages */ +#define PUBNUB_USE_ACTIONS_API 1 +#endif + +#if !defined(PUBNUB_USE_GRANT_TOKEN_API) +/** If true (!=0) will enable using the Grant Token API */ +#define PUBNUB_USE_GRANT_TOKEN_API 1 +#endif + +#if !defined(PUBNUB_USE_REVOKE_TOKEN_API) +/** If true (!=0) will enable using the Revoke Token API */ +#define PUBNUB_USE_REVOKE_TOKEN_API 1 +#endif + +#if !defined(PUBNUB_USE_AUTO_HEARTBEAT) +/** If true (!=0) will enable using the Auto Heartbeat Thumps(beats), which is a feature + that enables keeping presence of the given uuids on channels and channel groups during + longer periods without subscription. + This gives more freedom to the user while coding whom, othrewise, should take care of + these things all by himself using pubnub_heartbeat() transaction */ +#define PUBNUB_USE_AUTO_HEARTBEAT 1 +#endif + +#ifndef PUBNUB_USE_SSL +/** If true (!=0), will enable SSL/TLS support. If false (==0), will + disable SSL/TLS support. If not defined, will enable SSL/TLS + support. */ +#define PUBNUB_USE_SSL 1 +#endif + #endif /* !defined INC_PUBNUB_CONFIG */ diff --git a/Source/ThirdParty/sdk/Include/freertos/pubnub_generate_uuid_freertos.c b/Source/ThirdParty/sdk/Include/freertos/pubnub_generate_uuid_freertos.c index 496c083..58c7a38 100644 --- a/Source/ThirdParty/sdk/Include/freertos/pubnub_generate_uuid_freertos.c +++ b/Source/ThirdParty/sdk/Include/freertos/pubnub_generate_uuid_freertos.c @@ -3,7 +3,11 @@ #include #include "task.h" +#ifndef ESP_PLATFORM #include "FreeRTOS_IP.h" +#else +#define ipconfigRAND32() rand() +#endif int pubnub_generate_uuid_v4_random(struct Pubnub_UUID *uuid) diff --git a/Source/ThirdParty/sdk/Include/freertos/pubnub_internal.h b/Source/ThirdParty/sdk/Include/freertos/pubnub_internal.h index d3ea779..0cac9f1 100644 --- a/Source/ThirdParty/sdk/Include/freertos/pubnub_internal.h +++ b/Source/ThirdParty/sdk/Include/freertos/pubnub_internal.h @@ -7,13 +7,52 @@ #include "task.h" +#ifndef ESP_PLATFORM + #include "FreeRTOS_IP.h" #include "FreeRTOS_Sockets.h" - #define socket_close(socket) FreeRTOS_closesocket(socket) #define socket_send(socket, buf, len) FreeRTOS_send((socket), (buf), (len), 0) #define socket_recv(socket, buf, len, flags) FreeRTOS_recv((socket), (buf), (len), (flags)) +#define htons(port) FreeRTOS_htons(port) +#define gethostbyname(name) FreeRTOS_gethostbyname(name) +#define getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags) FreeRTOS_getnameinfo((addr), (addrlen), (host), (hostlen), (serv), (servlen), (flags)) +#define socket(family, type, protocol) FreeRTOS_socket((family), (type), (protocol)) +#define socket_connect(socket, addr, addrlen) FreeRTOS_connect((socket), (addr), (addrlen)) +#define socket_setsockopt(socket, level, optname, optval, optlen) FreeRTOS_setsockopt((socket), (level), (optname), (optval), (optlen)) +#define AF_INET FREERTOS_AF_INET +#define SOCK_STREAM FREERTOS_SOCK_STREAM +#define IPPROTO_TCP FREERTOS_IPPROTO_TCP +#define SO_RCVTIMEO FREERTOS_SO_RCVTIMEO +#define sockaddr freertos_sockaddr + +typedef Socket_t pb_socket_t; + +#define SOCKET_INVALID FREERTOS_INVALID_SOCKET + +#else + +#include "lwip/netdb.h" +#include "lwip/inet.h" +#include "lwip/ip_addr.h" + +#define socket_close(socket) closesocket(socket) +#define socket_send(socket, buf, len) send((socket), (buf), (len), 0) +#define socket_recv(socket, buf, len, flags) recv((socket), (buf), (len), (flags)) +#define gethostbyname(name) lwip_gethostbyname(name) +#define getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags) lwip_getnameinfo((addr), (addrlen), (host), (hostlen), (serv), (servlen), (flags)) +#define socket(family, type, protocol) lwip_socket((family), (type), (protocol)) +#define socket_connect(socket, addr, addrlen) lwip_connect((socket), (addr), (addrlen)) +#define socket_setsockopt(socket, level, optname, optval, optlen) lwip_setsockopt((socket), (level), (optname), (optval), (optlen)) +#define sockaddr sockaddr_in + +typedef int pb_socket_t; + +#define SOCKET_INVALID ENETDOWN + +#endif + /** FreeRTOS+TCP always blocks, so checking "if it would block" doesn't make sense */ @@ -34,19 +73,29 @@ #define socket_is_connected(socket) (pdTRUE == FreeRTOS_issocketconnected(socket)) -#define SOCKET_INVALID FREERTOS_INVALID_SOCKET /* FreeRTOS+TCP never raises SIGPIPE, so, we're good. */ #define socket_disable_SIGPIPE(socket) -typedef Socket_t pb_socket_t; +#ifndef PUBNUB_MBEDTLS +/** Flag to indicate that we are using MBEDTLS library support */ +#define PUBNUB_MBEDTLS 1 +#endif +// TODO: move pubnub_pal to other header to avoid multiple definitions +// of the same struct +// Maybe modularization of the Pubnub library is needed sooner than +// later in this SDK +#if !PUBNUB_MBEDTLS /** The Pubnub FreeRTOS context */ struct pubnub_pal { pb_socket_t socket; }; +#else +#include "mbedtls/pubnub_pal.h" +#endif /** The sockets interface of FreeRTOS+TCP, doesn't provide a non-blocking blocking I/O. Another implementation may be @@ -58,9 +107,23 @@ struct pubnub_pal { #define PUBNUB_TIMERS_API 1 +#if !defined(PUBNUB_MAX_URL_PARAMS) +/** The maximum number of URL parameters that can be saved in the Pubnub + context. +*/ +#define PUBNUB_MAX_URL_PARAMS 10 +#endif -#include "pubnub_internal_common.h" +#if !defined(PUBNUB_MIN_WAIT_CONNECT_TIMER) +/** The minimum duration of the wait connect timer, in milliseconds. */ +#define PUBNUB_MIN_WAIT_CONNECT_TIMER 5000 +#endif +#if !defined(PUBNUB_DEFAULT_WAIT_CONNECT_TIMER) +/** The default duration of the wait connect timer, in milliseconds. */ +#define PUBNUB_DEFAULT_WAIT_CONNECT_TIMER 10000 +#endif +#include "pubnub_internal_common.h" #endif /* !defined INC_PUBNUB_INTERNAL */ diff --git a/Source/ThirdParty/sdk/Include/freertos/pubnub_version_freertos.c b/Source/ThirdParty/sdk/Include/freertos/pubnub_version_freertos.c index cb31a1f..c434666 100644 --- a/Source/ThirdParty/sdk/Include/freertos/pubnub_version_freertos.c +++ b/Source/ThirdParty/sdk/Include/freertos/pubnub_version_freertos.c @@ -24,3 +24,8 @@ char const *pubnub_uname(void) return PUBNUB_SDK_NAME "/" PUBNUB_SDK_VERSION; } +char const *pubnub_uagent(void) +{ + return PUBNUB_SDK_NAME "-PubNub-C-core/" PUBNUB_SDK_VERSION; +} + diff --git a/Source/ThirdParty/sdk/Include/lib/md5/md5.c b/Source/ThirdParty/sdk/Include/lib/md5/md5.c index 4cb971c..5805298 100644 --- a/Source/ThirdParty/sdk/Include/lib/md5/md5.c +++ b/Source/ThirdParty/sdk/Include/lib/md5/md5.c @@ -194,7 +194,7 @@ static void const* body(MD5_CTX *ctx, void const* data, unsigned long size) return ptr; } -void MD5_InitPN(MD5_CTX *ctx) +void MD5_Init(MD5_CTX *ctx) { ctx->a = 0x67452301; ctx->b = 0xefcdab89; @@ -205,7 +205,7 @@ void MD5_InitPN(MD5_CTX *ctx) ctx->hi = 0; } -void MD5_UpdatePN(MD5_CTX *ctx, void const *data, unsigned long size) +void MD5_Update(MD5_CTX *ctx, void const *data, unsigned long size) { MD5_u32plus saved_lo; unsigned long used, free; @@ -239,7 +239,7 @@ void MD5_UpdatePN(MD5_CTX *ctx, void const *data, unsigned long size) memcpy(ctx->buffer, data, size); } -void MD5_FinalPN(unsigned char *result, MD5_CTX *ctx) +void MD5_Final(unsigned char *result, MD5_CTX *ctx) { unsigned long used, free; diff --git a/Source/ThirdParty/sdk/Include/lib/md5/md5.h b/Source/ThirdParty/sdk/Include/lib/md5/md5.h index d792f68..69aca4a 100644 --- a/Source/ThirdParty/sdk/Include/lib/md5/md5.h +++ b/Source/ThirdParty/sdk/Include/lib/md5/md5.h @@ -36,8 +36,8 @@ typedef struct { MD5_u32plus block[16]; } MD5_CTX; -extern void MD5_InitPN(MD5_CTX *ctx); -extern void MD5_UpdatePN(MD5_CTX *ctx, void const *data, unsigned long size); -extern void MD5_FinalPN(unsigned char *result, MD5_CTX *ctx); +extern void MD5_Init(MD5_CTX *ctx); +extern void MD5_Update(MD5_CTX *ctx, void const *data, unsigned long size); +extern void MD5_Final(unsigned char *result, MD5_CTX *ctx); #endif diff --git a/Source/ThirdParty/sdk/Include/lib/md5/pbmd5.h b/Source/ThirdParty/sdk/Include/lib/md5/pbmd5.h index 48cbd1e..76d9267 100644 --- a/Source/ThirdParty/sdk/Include/lib/md5/pbmd5.h +++ b/Source/ThirdParty/sdk/Include/lib/md5/pbmd5.h @@ -32,14 +32,14 @@ /** Initializes the MD5 context for a new calculation. @param x Pointer to a MD5 context */ -#define pbmd5_init(x) MD5_InitPN(x) +#define pbmd5_init(x) MD5_Init(x) /** Update the MD5 context with the "next part of the message". @param x Pointer to a MD5 context @param m Pointer to the start of the "next part of the message" @param l Length (in bytes) of the "next part of the message" */ -#define pbmd5_update(x, m, l) MD5_UpdatePN((x), (m), (l)) +#define pbmd5_update(x, m, l) MD5_Update((x), (m), (l)) /** Update the MD5 context with the "next part of the message". Assumes it is an ASCIIZ string. @@ -47,22 +47,22 @@ @param x Pointer to a MD5 context @param str String being the "next part of the message" */ -#define pbmd5_update_str(x, str) MD5_UpdatePN((x), (str), strlen(str)) +#define pbmd5_update_str(x, str) MD5_Update((x), (str), strlen(str)) /** Does the final calculations of the MD5 on context @p x and stores the digest to @p d. @param x Pointer to a MD5 context @param d Pointer to an array of (at least) 16 bytes */ -#define pbmd5_final(x, d) MD5_FinalPN((d), (x)) +#define pbmd5_final(x, d) MD5_Final((d), (x)) /** This helper macro will calculate the MD5 on the message in @p m, having the length @p l and store it in @p d. */ #define pbmd5_digest(m, l, d) do { MD5_CTX M_ctx_; \ - MD5_InitPN(&M_ctx_); \ - MD5_UpdatePN(&M_ctx_, (m), (l)); \ - MD5_FinalPN((d), &M_ctx); \ + MD5_Init(&M_ctx_); \ + MD5_Update(&M_ctx_, (m), (l)); \ + MD5_Final((d), &M_ctx); \ } while (0) /** This helper macro will calculate the MD5 on the message in @p str, @@ -70,9 +70,9 @@ @warning This macro uses @p str twice! */ #define pbmd5_digest_str(str, d) do { MD5_CTX M_ctx_; \ - MD5_InitPN(&M_ctx_); \ - MD5_UpdatePN(&M_ctx_, (str), strlen(str)); \ - MD5_FinalPN((d), &M_ctx); \ + MD5_Init(&M_ctx_); \ + MD5_Update(&M_ctx_, (str), strlen(str)); \ + MD5_Final((d), &M_ctx); \ } while (0) #endif /* !defined INC_PBMD5 */ diff --git a/Source/ThirdParty/sdk/Include/lib/pubnub_dns_codec.c b/Source/ThirdParty/sdk/Include/lib/pubnub_dns_codec.c index 995d86e..a4bfebe 100644 --- a/Source/ThirdParty/sdk/Include/lib/pubnub_dns_codec.c +++ b/Source/ThirdParty/sdk/Include/lib/pubnub_dns_codec.c @@ -456,12 +456,21 @@ static int skip_questions(uint8_t const** o_reader, size_t to_skip; if (reader + QUESTION_DATA_SIZE > end) { +#ifndef ESP_PLATFORM PUBNUB_LOG_ERROR("Error: DNS response erroneous, or incomplete:\n" "reader=%p + QUESTION_DATA_SIZE=%d > buf=%p + msg_size=%ld\n", reader, QUESTION_DATA_SIZE, buf, end - buf + 1); +#else + PUBNUB_LOG_ERROR("Error: DNS response erroneous, or incomplete:\n" + "reader=%p + QUESTION_DATA_SIZE=%d > buf=%p + msg_size=%d\n", + reader, + QUESTION_DATA_SIZE, + buf, + end - buf + 1); +#endif return -1; } /* Even if label decoding reports an error(having offsets messed up, maybe, or buffer too @@ -627,6 +636,7 @@ static int find_the_answer(uint8_t const* reader, } reader += to_skip + RESOURCE_DATA_SIZE; if (reader > end) { +#ifndef ESP_PLATFORM PUBNUB_LOG_ERROR("Error: DNS response erroneous, or incomplete:\n" "reader=%p > buf=%p + msg_size=%ld :\n" "to_skip=%zu, RESOURCE_DATA_SIZE=%d\n", @@ -635,6 +645,16 @@ static int find_the_answer(uint8_t const* reader, end - buf + 1, to_skip, RESOURCE_DATA_SIZE); +#else + PUBNUB_LOG_ERROR("Error: DNS response erroneous, or incomplete:\n" + "reader=%p > buf=%p + msg_size=%d :\n" + "to_skip=%zu, RESOURCE_DATA_SIZE=%d\n", + reader, + buf, + end - buf + 1, + to_skip, + RESOURCE_DATA_SIZE); +#endif return -1; } /* Resource record data offsets are negative. @@ -643,12 +663,21 @@ static int find_the_answer(uint8_t const* reader, r_data_len = reader[RESOURCE_DATA_DATA_LEN_OFFSET] * 256 + reader[RESOURCE_DATA_DATA_LEN_OFFSET + 1]; if ((reader + r_data_len) > end) { +#ifndef ESP_PLATFORM PUBNUB_LOG_ERROR("Error: DNS response erroneous, or incomplete:\n" "reader=%p + r_data_len=%zu > buf=%p + msg_size=%ld\n", reader, r_data_len, buf, end - buf + 1); +#else + PUBNUB_LOG_ERROR("Error: DNS response erroneous, or incomplete:\n" + "reader=%p + r_data_len=%zu > buf=%p + msg_size=%d\n", + reader, + r_data_len, + buf, + end - buf + 1); +#endif return -1; } r_data_type = reader[RESOURCE_DATA_TYPE_OFFSET] * 256 diff --git a/Source/ThirdParty/sdk/Include/lib/sockets/pbpal_handle_socket_error.c b/Source/ThirdParty/sdk/Include/lib/sockets/pbpal_handle_socket_error.c index 350ad1c..e3ed739 100644 --- a/Source/ThirdParty/sdk/Include/lib/sockets/pbpal_handle_socket_error.c +++ b/Source/ThirdParty/sdk/Include/lib/sockets/pbpal_handle_socket_error.c @@ -31,7 +31,11 @@ void pbpal_report_error_from_environment(pubnub_t* pb, char const* file, int lin errno, err_str); if (pb != NULL) { +#if PUBNUB_BLOCKING_IO_SETTABLE PUBNUB_LOG_DEBUG(" use_blocking_io=%d\n", (int)pb->options.use_blocking_io); +#else + PUBNUB_LOG_DEBUG("\n"); +#endif // PUBNUB_BLOCKING_IO_SETTABLE } else { PUBNUB_LOG_DEBUG("\n"); @@ -59,10 +63,12 @@ enum pubnub_res pbpal_handle_socket_error(int socket_result, PUBNUB_ASSERT_INT_OPT(socket_result, <=, 0); if (socket_result < 0) { if (socket_would_block()) { - if (PUBNUB_BLOCKING_IO_SETTABLE && pb->options.use_blocking_io) { +#if PUBNUB_BLOCKING_IO_SETTABLE + if (pb->options.use_blocking_io) { pb->sock_state = STATE_NONE; return PNR_TIMEOUT; } +#endif return PNR_IN_PROGRESS; } else { diff --git a/Source/ThirdParty/sdk/Include/posix/pubnub_version_posix.c b/Source/ThirdParty/sdk/Include/posix/pubnub_version_posix.c index de1323c..ffaa6ec 100644 --- a/Source/ThirdParty/sdk/Include/posix/pubnub_version_posix.c +++ b/Source/ThirdParty/sdk/Include/posix/pubnub_version_posix.c @@ -6,6 +6,10 @@ #define PUBNUB_SDK_NAME "POSIX" +#ifndef PUBNUB_SDK_VERSION_SUFFIX +#define PUBNUB_SDK_VERSION_SUFFIX +#endif + char const *pubnub_sdk_name(void) { @@ -21,12 +25,12 @@ char const *pubnub_version(void) char const *pubnub_uname(void) { - return PUBNUB_SDK_NAME "-PubNub-C-core/" PUBNUB_SDK_VERSION; + return PUBNUB_SDK_NAME "-PubNub-C-core/" PUBNUB_SDK_VERSION PUBNUB_SDK_VERSION_SUFFIX; } char const *pubnub_uagent(void) { - return PUBNUB_SDK_NAME "-PubNub-C-core/" PUBNUB_SDK_VERSION; + return PUBNUB_SDK_NAME "-PubNub-C-core/" PUBNUB_SDK_VERSION PUBNUB_SDK_VERSION_SUFFIX; } diff --git a/Source/ThirdParty/sdk/Include/windows/pubnub_version_windows.c b/Source/ThirdParty/sdk/Include/windows/pubnub_version_windows.c index 8ba0b19..684c874 100644 --- a/Source/ThirdParty/sdk/Include/windows/pubnub_version_windows.c +++ b/Source/ThirdParty/sdk/Include/windows/pubnub_version_windows.c @@ -6,6 +6,10 @@ #define PUBNUB_SDK_NAME "Windows" +#ifndef PUBNUB_SDK_VERSION_SUFFIX +#define PUBNUB_SDK_VERSION_SUFFIX +#endif + char const *pubnub_sdk_name(void) { @@ -21,11 +25,11 @@ char const *pubnub_version(void) char const *pubnub_uname(void) { - return PUBNUB_SDK_NAME "-PubNub-C-core/" PUBNUB_SDK_VERSION; + return PUBNUB_SDK_NAME "-PubNub-C-core/" PUBNUB_SDK_VERSION PUBNUB_SDK_VERSION_SUFFIX; } char const *pubnub_uagent(void) { - return PUBNUB_SDK_NAME "-PubNub-C-core/" PUBNUB_SDK_VERSION; + return PUBNUB_SDK_NAME "-PubNub-C-core/" PUBNUB_SDK_VERSION PUBNUB_SDK_VERSION_SUFFIX; } diff --git a/Source/ThirdParty/sdk/PubNubModule/PubNubModule.Build.cs b/Source/ThirdParty/sdk/PubNubModule/PubNubModule.Build.cs index f389cfc..3c5ff95 100644 --- a/Source/ThirdParty/sdk/PubNubModule/PubNubModule.Build.cs +++ b/Source/ThirdParty/sdk/PubNubModule/PubNubModule.Build.cs @@ -13,39 +13,29 @@ public PubNubModule(ReadOnlyTargetRules Target) : base(Target) { Type = ModuleType.External; - string extention = null; - string PlatformLib = null; - string binary = null; - string buildLocation = null; - if(Target.Platform == UnrealTargetPlatform.Win64) - { - extention = StaticLink ? "lib" : "dll"; - PlatformLib = OpenSsl ? "openssl" : "windows"; - binary = $"pubnub.{extention}"; - buildLocation = "Lib/win64"; - } - else if(Target.Platform == UnrealTargetPlatform.Mac) - { - extention = StaticLink ? "a" : "dylib"; - PlatformLib = OpenSsl ? "openssl" : "posix"; - binary = $"libpubnub.{extention}"; - buildLocation = "Lib/MacOS"; - } - else - { - extention = StaticLink ? "a" : "so"; - PlatformLib = OpenSsl ? "openssl" : "posix"; - binary = $"libpubnub.{extention}"; - buildLocation = "Lib/Linux"; - } - - if (OpenSsl) { + if (OpenSsl) { PublicDependencyModuleNames.AddRange(new string[] { "OpenSSL" }); } var SDKPath = Path.Combine(new string[] { ModuleDirectory, ".." }); + + + + if (Target.Platform == UnrealTargetPlatform.Win64) + { + string BuildLocation = "Lib/win64"; + PublicAdditionalLibraries.Add(Path.Combine(SDKPath, BuildLocation, "pubnub.lib")); + + } + else if(Target.Platform == UnrealTargetPlatform.Mac) + { + PublicDelayLoadDLLs.Add(Path.Combine(SDKPath, "lib", "macos", "libpubnub.dylib")); + RuntimeDependencies.Add("$(PluginDir)/Source/ThirdParty/sdk/lib/macos/libpubnub.dylib"); + } + + string PlatformLib = "openssl"; + - PublicAdditionalLibraries.Add(Path.Combine(SDKPath, buildLocation, binary)); PublicIncludePaths.AddRange( new string[] { SDKPath, diff --git a/Source/ThirdParty/sdk/lib/MacOS/libpubnub.a b/Source/ThirdParty/sdk/lib/MacOS/libpubnub.a index 080b739..432996c 100644 Binary files a/Source/ThirdParty/sdk/lib/MacOS/libpubnub.a and b/Source/ThirdParty/sdk/lib/MacOS/libpubnub.a differ diff --git a/Source/ThirdParty/sdk/lib/win64/pubnub.lib b/Source/ThirdParty/sdk/lib/win64/pubnub.lib index d83d4cf..117923c 100644 Binary files a/Source/ThirdParty/sdk/lib/win64/pubnub.lib and b/Source/ThirdParty/sdk/lib/win64/pubnub.lib differ