From 00c1be07dcc1ac25555abf6c1007afcab8207581 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Mon, 11 Nov 2019 13:08:36 +0900 Subject: [PATCH] Replace c_impl, remove rust_binding, with cpp_impl --- cpp_impl/.gitignore => .gitignore | 0 cpp_impl/CMakeLists.txt => CMakeLists.txt | 0 c_impl/.gitignore | 2 - c_impl/CMakeLists.txt | 49 - c_impl/src/UDPC_Defines.h | 65 - c_impl/src/UDPC_Deque.c | 511 ------ c_impl/src/UDPC_Deque.h | 168 -- c_impl/src/UDPC_HashMap.c | 315 ---- c_impl/src/UDPC_HashMap.h | 111 -- c_impl/src/UDPConnection.c | 1517 ----------------- c_impl/src/UDPConnection.h | 325 ---- c_impl/src/test/UDPC_NetworkTest.c | 163 -- c_impl/src/test/UDPC_UnitTest.c | 419 ----- c_impl/src/test/UDPC_UnitTest.h | 61 - rust_binding/.gitignore | 2 - rust_binding/Cargo.toml | 11 - rust_binding/build.rs | 56 - rust_binding/src/lib.rs | 5 - rust_binding/wrapper.h | 1 - {cpp_impl/src => src}/TSLQueue.hpp | 0 {cpp_impl/src => src}/UDPC_Defines.hpp | 0 {cpp_impl/src => src}/UDPConnection.cpp | 0 {cpp_impl/src => src}/UDPConnection.h | 0 {cpp_impl/src => src}/test/TestTSLQueue.cpp | 0 {cpp_impl/src => src}/test/TestUDPC.cpp | 0 .../src => src}/test/UDPC_NetworkTest.cpp | 0 {cpp_impl/src => src}/test/UDPC_UnitTest.cpp | 0 27 files changed, 3781 deletions(-) rename cpp_impl/.gitignore => .gitignore (100%) rename cpp_impl/CMakeLists.txt => CMakeLists.txt (100%) delete mode 100644 c_impl/.gitignore delete mode 100644 c_impl/CMakeLists.txt delete mode 100644 c_impl/src/UDPC_Defines.h delete mode 100644 c_impl/src/UDPC_Deque.c delete mode 100644 c_impl/src/UDPC_Deque.h delete mode 100644 c_impl/src/UDPC_HashMap.c delete mode 100644 c_impl/src/UDPC_HashMap.h delete mode 100644 c_impl/src/UDPConnection.c delete mode 100644 c_impl/src/UDPConnection.h delete mode 100644 c_impl/src/test/UDPC_NetworkTest.c delete mode 100644 c_impl/src/test/UDPC_UnitTest.c delete mode 100644 c_impl/src/test/UDPC_UnitTest.h delete mode 100644 rust_binding/.gitignore delete mode 100644 rust_binding/Cargo.toml delete mode 100644 rust_binding/build.rs delete mode 100644 rust_binding/src/lib.rs delete mode 100644 rust_binding/wrapper.h rename {cpp_impl/src => src}/TSLQueue.hpp (100%) rename {cpp_impl/src => src}/UDPC_Defines.hpp (100%) rename {cpp_impl/src => src}/UDPConnection.cpp (100%) rename {cpp_impl/src => src}/UDPConnection.h (100%) rename {cpp_impl/src => src}/test/TestTSLQueue.cpp (100%) rename {cpp_impl/src => src}/test/TestUDPC.cpp (100%) rename {cpp_impl/src => src}/test/UDPC_NetworkTest.cpp (100%) rename {cpp_impl/src => src}/test/UDPC_UnitTest.cpp (100%) diff --git a/cpp_impl/.gitignore b/.gitignore similarity index 100% rename from cpp_impl/.gitignore rename to .gitignore diff --git a/cpp_impl/CMakeLists.txt b/CMakeLists.txt similarity index 100% rename from cpp_impl/CMakeLists.txt rename to CMakeLists.txt diff --git a/c_impl/.gitignore b/c_impl/.gitignore deleted file mode 100644 index 19cc2c4..0000000 --- a/c_impl/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build*/ -compile_commands.json diff --git a/c_impl/CMakeLists.txt b/c_impl/CMakeLists.txt deleted file mode 100644 index 4f5b6e8..0000000 --- a/c_impl/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -cmake_minimum_required(VERSION 3.7) -project(UDPConnection) - -set(UDPConnection_VERSION 1.0) - -set(UDPConnection_SOURCES - src/UDPConnection.c - src/UDPC_Deque.c - src/UDPC_HashMap.c -) - -set(CMAKE_C_FLAGS "-Wall -Wno-missing-braces") -set(CMAKE_C_FLAGS_DEBUG "-O0 -g") -set(CMAKE_C_FLAGS_RELEASE "-O3 -D NDEBUG") - -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - message(STATUS "Setting build type to 'Debug', none was specified.") - set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE) - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release") -endif() - -add_library(UDPConnection ${UDPConnection_SOURCES}) - -set_target_properties(UDPConnection PROPERTIES VERSION ${UDPConnection_VERSION}) - -target_compile_features(UDPConnection PUBLIC c_std_11) -target_link_libraries(UDPConnection PUBLIC pthread) - -if(CMAKE_BUILD_TYPE MATCHES "Debug") - set(UDPC_UnitTest_SOURCES - src/test/UDPC_UnitTest.c) - add_executable(UnitTest ${UDPC_UnitTest_SOURCES}) - target_link_libraries(UnitTest PUBLIC UDPConnection) - target_include_directories(UnitTest PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) - - set(UDPC_NetworkTest_SOURCES - src/test/UDPC_NetworkTest.c) - add_executable(NetworkTest ${UDPC_NetworkTest_SOURCES}) - target_link_libraries(NetworkTest PUBLIC UDPConnection) - target_include_directories(NetworkTest PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) -endif() - -install(TARGETS UDPConnection DESTINATION lib) -install(FILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/UDPConnection.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/UDPC_Defines.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/UDPC_Deque.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/UDPC_HashMap.h - DESTINATION include) diff --git a/c_impl/src/UDPC_Defines.h b/c_impl/src/UDPC_Defines.h deleted file mode 100644 index 5032e36..0000000 --- a/c_impl/src/UDPC_Defines.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef UDPC_DEFINES_H -#define UDPC_DEFINES_H - -#define UDPC_PLATFORM_WINDOWS 1 -#define UDPC_PLATFORM_MAC 2 -#define UDPC_PLATFORM_LINUX 3 -#define UDPC_PLATFORM_UNKNOWN 0 - -#if defined _WIN32 - #define UDPC_PLATFORM UDPC_PLATFORM_WINDOWS -#elif defined __APPLE__ - #define UDPC_PLATFORM UDPC_PLATFORM_MAC -#elif defined __linux__ - #define UDPC_PLATFORM UDPC_PLATFORM_LINUX -#else - #define UDPC_PLATFORM UDPC_PLATFORM_UNKNOWN -#endif - -#define UDPC_SUCCESS 0 -#define UDPC_ERR_SOCKETFAIL 1 // failed to create socket -#define UDPC_ERR_SOCKETBINDF 2 // failed to bind socket -#define UDPC_ERR_SOCKETNONBF 3 // failed to set non-blocking on socket -#define UDPC_ERR_MTXFAIL 4 // failed to create mutex -#define UDPC_ERR_CVFAIL 5 // failed to create condition variable -#define UDPC_ERR_THREADFAIL 6 // failed to create thread - -// Error strings are defined in UDPConnection.c -extern const char *UDPC_ERR_SOCKETFAIL_STR; -extern const char *UDPC_ERR_SOCKETBINDF_STR; -extern const char *UDPC_ERR_SOCKETNONBF_STR; -extern const char *UDPC_ERR_MTXFAIL_STR; -extern const char *UDPC_ERR_CVFAIL_STR; -extern const char *UDPC_ERR_THREADFAIL_STR; - -#define UDPC_CD_AMOUNT 32 - -#define UDPC_GOOD_MODE_SEND_INTERVAL (1.0f/30.0f) -#define UDPC_BAD_MODE_SEND_INTERVAL (1.0f/10.0f) -#define UDPC_TIMEOUT_SECONDS 10.0f -#define UDPC_HEARTBEAT_PKT_INTERVAL (15.0f/100.0f) -#define UDPC_INIT_PKT_INTERVAL 5 -#define UDPC_INIT_PKT_INTERVAL_F ((float)UDPC_INIT_PKT_INTERVAL) -#define UDPC_PKT_DEFAULT_PROTOCOL_ID 1357924680 - -#define UDPC_ID_CONNECT 0x80000000 -#define UDPC_ID_PING 0x40000000 -#define UDPC_ID_NO_REC_CHK 0x20000000 -#define UDPC_ID_RESENDING 0x10000000 - -#define UDPC_SENT_PKTS_MAX_SIZE 34 -#define UDPC_SENT_PKTS_ALLOC_SIZE 35 -#define UDPC_SEND_PKTS_ALLOC_SIZE 40 -#define UDPC_RESEND_PKTS_ALLOC_SIZE 40 - -#define UDPC_PACKET_MAX_SIZE 8192 - -#define UDPC_PACKET_TIMEOUT_SEC 1.0f -#define UDPC_GOOD_RTT_LIMIT_SEC 0.25f - -#define UDPC_REC_PKTS_ALLOC_SIZE 128 - -#define UDPC_CONNECTED_EVENT_SIZE 64 -#define UDPC_DISCONNECTED_EVENT_SIZE 64 - -#endif diff --git a/c_impl/src/UDPC_Deque.c b/c_impl/src/UDPC_Deque.c deleted file mode 100644 index c49ba11..0000000 --- a/c_impl/src/UDPC_Deque.c +++ /dev/null @@ -1,511 +0,0 @@ -#include "UDPC_Deque.h" - -#include -#include - -UDPC_Deque* UDPC_Deque_init(uint32_t alloc_size) -{ - UDPC_Deque *deque = malloc(sizeof(UDPC_Deque)); - if(!deque) - { - return NULL; - } - UDPC_Deque_clear(deque); - deque->alloc_size = alloc_size; - deque->buf = malloc(alloc_size); - if(deque->buf) - { - return deque; - } - else - { - free(deque); - return NULL; - } -} - -void UDPC_Deque_destroy(UDPC_Deque *deque) -{ - free(deque->buf); - free(deque); -} - -int UDPC_Deque_realloc(UDPC_Deque *deque, uint32_t new_size) -{ - if(new_size < deque->size) - { - return 0; - } - else if(deque->size != 0 && deque->tail <= deque->head) - { - char *buf = malloc(new_size); - memcpy(buf, &deque->buf[deque->head], deque->alloc_size - deque->head); - if(deque->tail != 0) - { - memcpy(&buf[deque->alloc_size - deque->head], deque->buf, deque->tail); - } - free(deque->buf); - deque->buf = buf; - deque->alloc_size = new_size; - deque->head = 0; - deque->tail = deque->size; - if(deque->tail == deque->alloc_size) - { - deque->tail = 0; - } - return 1; - } - else - { - void *buf = realloc(deque->buf, new_size); - if(buf) - { - deque->buf = buf; - deque->alloc_size = new_size; - return 1; - } - else - { - return 0; - } - } -} - -int UDPC_Deque_push_back(UDPC_Deque *deque, const void *data, uint32_t size) -{ - if(deque->size + size > deque->alloc_size) - { - return 0; - } - else if(deque->tail + size <= deque->alloc_size) - { - memcpy(&deque->buf[deque->tail], data, size); - deque->tail += size; - if(deque->tail == deque->alloc_size) - { - deque->tail = 0; - } - deque->size += size; - - return 1; - } - - uint32_t temp; - - if(deque->tail < deque->alloc_size) - { - memcpy(&deque->buf[deque->tail], data, deque->alloc_size - deque->tail); - temp = deque->alloc_size - deque->tail; - deque->size += temp; - size -= temp; - deque->tail = 0; - } - if(size > 0) - { - memcpy(&deque->buf[deque->tail], &((const char*)data)[temp], size); - deque->tail += size; - deque->size += size; - } - return 1; -} - -int UDPC_Deque_push_front(UDPC_Deque *deque, const void *data, uint32_t size) -{ - if(deque->size + size > deque->alloc_size) - { - return 0; - } - else if(size <= deque->head) - { - memcpy(&deque->buf[deque->head - size], data, size); - deque->head -= size; - deque->size += size; - - return 1; - } - - if(deque->head > 0) - { - memcpy(deque->buf, &((const char*)data)[size - deque->head], deque->head); - deque->size += deque->head; - size -= deque->head; - deque->head = 0; - } - if(size > 0) - { - memcpy(&deque->buf[deque->alloc_size - size], data, size); - deque->head = deque->alloc_size - size; - deque->size += size; - } - return 1; -} - -int UDPC_Deque_push_back_realloc(UDPC_Deque *deque, const void *data, uint32_t size) -{ - if(UDPC_Deque_push_back(deque, data, size) == 0) - { - if(UDPC_Deque_realloc(deque, deque->alloc_size * 2) != 0) - { - return UDPC_Deque_push_back(deque, data, size); - } - } - return 0; -} - -int UDPC_Deque_push_front_realloc(UDPC_Deque *deque, const void *data, uint32_t size) -{ - if(UDPC_Deque_push_front(deque, data, size) == 0) - { - if(UDPC_Deque_realloc(deque, deque->alloc_size * 2) != 0) - { - return UDPC_Deque_push_front(deque, data, size); - } - } - return 0; -} - -uint32_t UDPC_Deque_get_available(UDPC_Deque *deque) -{ - return deque->alloc_size - deque->size; -} - -uint32_t UDPC_Deque_get_used(UDPC_Deque *deque) -{ - return deque->size; -} - -int UDPC_Deque_get_back(UDPC_Deque *deque, void **data, uint32_t *size) -{ - int returnValue = 1; - if(deque->size == 0) - { - *size = 0; - *data = NULL; - return 0; - } - else if(*size > deque->size) - { - *size = deque->size; - returnValue = 0; - } - - *data = malloc(*size); - - if(deque->tail == 0) - { - memcpy(*data, &deque->buf[deque->alloc_size - *size], *size); - return returnValue; - } - else if(deque->tail < *size) - { - memcpy(data[*size - deque->tail], deque->buf, deque->tail); - memcpy( - *data, - &deque->buf[deque->alloc_size - (*size - deque->tail)], - *size - deque->tail); - return returnValue; - } - else - { - memcpy(*data, &deque->buf[deque->tail - *size], *size); - return returnValue; - } -} - -void* UDPC_Deque_get_back_ptr(UDPC_Deque *deque, uint32_t unitSize) -{ - if(deque->size < unitSize) - { - return NULL; - } - - if(deque->tail == 0 && deque->size >= unitSize) - { - return &deque->buf[deque->alloc_size - unitSize]; - } - else if(deque->tail < unitSize) - { - return NULL; - } - else - { - return &deque->buf[deque->tail - unitSize]; - } -} - -int UDPC_Deque_get_front(UDPC_Deque *deque, void **data, uint32_t *size) -{ - int returnValue = 1; - if(deque->size == 0) - { - *size = 0; - *data = NULL; - return 0; - } - else if(*size > deque->size) - { - *size = deque->size; - returnValue = 0; - } - - *data = malloc(*size); - - if(deque->head + *size > deque->alloc_size) - { - memcpy(*data, &deque->buf[deque->head], deque->alloc_size - deque->head); - memcpy( - data[deque->alloc_size - deque->head], - deque->buf, - *size - (deque->alloc_size - deque->head)); - return returnValue; - } - else - { - memcpy(*data, &deque->buf[deque->head], *size); - return returnValue; - } -} - -void* UDPC_Deque_get_front_ptr(UDPC_Deque *deque, uint32_t unitSize) -{ - if(deque->size < unitSize || deque->head + unitSize > deque->alloc_size) - { - return NULL; - } - - return &deque->buf[deque->head]; -} - -void UDPC_Deque_pop_back(UDPC_Deque *deque, uint32_t size) -{ - if(deque->size == 0) - { - return; - } - else if(deque->size <= size) - { - UDPC_Deque_clear(deque); - return; - } - - deque->size -= size; - - if(deque->tail < size) - { - deque->tail = deque->alloc_size - (size - deque->tail); - } - else - { - deque->tail -= size; - } -} - -void UDPC_Deque_pop_front(UDPC_Deque *deque, uint32_t size) -{ - if(deque->size == 0) - { - return; - } - else if(deque->size <= size) - { - UDPC_Deque_clear(deque); - return; - } - - deque->size -= size; - - if(deque->head + size > deque->alloc_size) - { - deque->head = deque->head + size - deque->alloc_size; - } - else - { - deque->head += size; - if(deque->head == deque->alloc_size) - { - deque->head = 0; - } - } -} - -int UDPC_Deque_index(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, void **out) -{ - uint32_t pos = unitSize * index; - uint32_t abspos; - if(pos >= deque->size) - { - *out = NULL; - return 0; - } - - *out = malloc(unitSize); - - if(pos + deque->head >= deque->alloc_size) - { - abspos = pos + deque->head - deque->alloc_size; - } - else - { - abspos = pos + deque->head; - } - - if(abspos + unitSize >= deque->alloc_size) - { - memcpy(*out, &deque->buf[abspos], deque->alloc_size - abspos); - memcpy(*out, deque->buf, unitSize - (deque->alloc_size - abspos)); - } - else - { - memcpy(*out, &deque->buf[abspos], unitSize); - } - - return 1; -} - -void* UDPC_Deque_index_ptr(UDPC_Deque *deque, uint32_t unitSize, uint32_t index) -{ - uint32_t pos = unitSize * index; - uint32_t abspos; - if(pos >= deque->size) - { - return NULL; - } - - if(pos + deque->head >= deque->alloc_size) - { - abspos = pos + deque->head - deque->alloc_size; - } - else - { - abspos = pos + deque->head; - } - - if(abspos + unitSize > deque->alloc_size) - { - return NULL; - } - - return &deque->buf[abspos]; -} - -int UDPC_Deque_index_rev(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, void **out) -{ - uint32_t pos = unitSize * (index + 1); - uint32_t abspos; - if(pos >= deque->size + unitSize) - { - *out = NULL; - return 0; - } - - *out = malloc(unitSize); - - if(pos > deque->tail) - { - abspos = deque->alloc_size - (pos - deque->tail); - } - else - { - abspos = deque->tail - pos; - } - - if(abspos + unitSize >= deque->alloc_size) - { - memcpy(*out, &deque->buf[abspos], deque->alloc_size - abspos); - memcpy(*out, deque->buf, unitSize - (deque->alloc_size - abspos)); - } - else - { - memcpy(*out, &deque->buf[abspos], unitSize); - } - - return 1; -} - -void* UDPC_Deque_index_rev_ptr(UDPC_Deque *deque, uint32_t unitSize, uint32_t index) -{ - uint32_t pos = unitSize * (index + 1); - uint32_t abspos; - if(pos >= deque->size + unitSize) - { - return NULL; - } - - if(pos > deque->tail) - { - abspos = deque->alloc_size - (pos - deque->tail); - } - else - { - abspos = deque->tail - pos; - } - - if(abspos + unitSize > deque->alloc_size) - { - return NULL; - } - - return &deque->buf[abspos]; -} - -int UDPC_Deque_remove(UDPC_Deque *deque, uint32_t unitSize, uint32_t index) -{ - uint32_t pos = unitSize * index; - uint32_t abspos; - uint32_t lastpos; - if(deque->size == 0 || pos >= deque->size) - { - return 0; - } - else if(deque->size <= unitSize) - { - UDPC_Deque_clear(deque); - return 1; - } - - if(pos + deque->head >= deque->alloc_size) - { - abspos = pos + deque->head - deque->alloc_size; - } - else - { - abspos = pos + deque->head; - } - - if(deque->tail == 0) - { - lastpos = deque->alloc_size - unitSize; - } - else - { - lastpos = deque->tail - unitSize; - } - - if(abspos != lastpos) - { - if(deque->tail == 0) - { - memcpy(&deque->buf[abspos], &deque->buf[deque->alloc_size - unitSize], unitSize); - deque->tail = deque->alloc_size - unitSize; - } - else - { - memcpy(&deque->buf[abspos], &deque->buf[deque->tail - unitSize], unitSize); - deque->tail -= unitSize; - } - deque->size -= unitSize; - } - else - { - UDPC_Deque_pop_back(deque, unitSize); - } - - return 1; -} - -void UDPC_Deque_clear(UDPC_Deque *deque) -{ - deque->head = 0; - deque->tail = 0; - deque->size = 0; -} diff --git a/c_impl/src/UDPC_Deque.h b/c_impl/src/UDPC_Deque.h deleted file mode 100644 index 91be55a..0000000 --- a/c_impl/src/UDPC_Deque.h +++ /dev/null @@ -1,168 +0,0 @@ -#ifndef UDPC_DEQUE_H -#define UDPC_DEQUE_H - -#include - -typedef struct { - uint32_t head; - uint32_t tail; - uint32_t size; - uint32_t alloc_size; - char *buf; -} UDPC_Deque; - -/*! - * \return non-null on success - */ -UDPC_Deque* UDPC_Deque_init(uint32_t alloc_size); - -/*! - * Frees resources used by a UDPC_Deque - */ -void UDPC_Deque_destroy(UDPC_Deque *deque); - -/*! - * Fails if new_size is smaller than current size of Deque. - * On failure, deque remains unchanged. - * \return non-zero on success - */ -int UDPC_Deque_realloc(UDPC_Deque *deque, uint32_t new_size); - -/*! - * If there was not enough space in the Deque, then no data is inserted at all. - * \return non-zero on success (there was enough size to insert data) - */ -int UDPC_Deque_push_back(UDPC_Deque *deque, const void *data, uint32_t size); - -/*! - * If there was not enough space in the Deque, then no data is inserted at all. - * \return non-zero on success (there was enough size to insert data) - */ -int UDPC_Deque_push_front(UDPC_Deque *deque, const void *data, uint32_t size); - -/*! - * \brief Same as push_back, but realloc if not enough free space - * Note when realloc occurs, the allocated space is doubled. - * \return non-zero on data pushed into Deque success - */ -int UDPC_Deque_push_back_realloc(UDPC_Deque *deque, const void *data, uint32_t size); - -/*! - * \brief Same as push_front, but realloc if not enough free space - * Note when realloc occurs, the allocated space is doubled. - * \return non-zero on data pushed into Deque success - */ -int UDPC_Deque_push_front_realloc(UDPC_Deque *deque, const void *data, uint32_t size); - -/*! - * \return size in bytes of available data - */ -uint32_t UDPC_Deque_get_available(UDPC_Deque *deque); - -/*! - * \return size in bytes of used data - */ -uint32_t UDPC_Deque_get_used(UDPC_Deque *deque); - -/*! - * \brief Get data from back of deque - * Data must be free'd after use as it was allocated with malloc. - * When size is greater than deque size, partial data is allocated, size is - * updated to allocated amount. If deque is empty, no data is allocated. - * \return non-zero if full requested size was returned - */ -int UDPC_Deque_get_back(UDPC_Deque *deque, void **data, uint32_t *size); - -/*! - * \brief Get data ptr from back of deque - * The returned ptr is part of the Deque's internal buffer and must not be - * manually free'd; it will be free'd when the Deque itself is destroyed. - * \return non-null if tail of deque has contiguous data of size unitSize - */ -void* UDPC_Deque_get_back_ptr(UDPC_Deque *deque, uint32_t unitSize); - -/*! - * \brief Get data from front of deque - * Data must be free'd after use as it was allocated with malloc. - * When size is greater than deque size, partial data is allocated, size is - * updated to allocated amount. If deque is empty, no data is allocated. - * \return non-zero if full requested size was returned - */ -int UDPC_Deque_get_front(UDPC_Deque *deque, void **data, uint32_t *size); - -/*! - * \brief Get data ptr from front of deque - * The returned ptr is part of the Deque's internal buffer and must not be - * manually free'd; it will be free'd when the Deque itself is destroyed. - * \return non-null if head of deque has contiguous data of size unitSize - */ -void* UDPC_Deque_get_front_ptr(UDPC_Deque *deque, uint32_t unitSize); - -/*! - * \brief "free" data from the back of the deque - * If size is greater than data used, then all data will be "free"d. - * Note that this doesn't actually deallocate data, but changes internal values - * that keep track of data positions in the internal buffer. The data will only - * actually be removed when it is overwritten or the Deque is free'd. - */ -void UDPC_Deque_pop_back(UDPC_Deque *deque, uint32_t size); - -/*! - * \brief "free" data from the front of the deque - * If size is greater than data used, then all data will be "free"d. - * Note that this doesn't actually deallocate data, but changes internal values - * that keep track of data positions in the internal buffer. The data will only - * actually be removed when it is overwritten or the Deque is free'd. - */ -void UDPC_Deque_pop_front(UDPC_Deque *deque, uint32_t size); - -/*! - * \brief Get a unitSize sized chunk of data at position unitSize * index - * The data will be indexed relative to the head of the Deque. - * The out pointer will be malloc'd with size unitSize and will have a copy of - * the data at the specified unitSize * index. - * Note that the out data must be free'd, but on fail nothing will be malloc'd - * and *out will be set to NULL. - * \return non-zero if unitSize * index < size - */ -int UDPC_Deque_index(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, void **out); - -/*! - * \brief Get a ptr to the indexed data at position unitSize * index - * The ptr will be indexed relative to the head of the Deque. - * The returned ptr is part of the Deque's internal buffer and will be free'd - * when the Deque is destroyed, so it should not be free'd directly. - * \return non-null if indexed data is a valid contiguous part of the buffer - */ -void* UDPC_Deque_index_ptr(UDPC_Deque *deque, uint32_t unitSize, uint32_t index); - -/*! - * \brief Get a unitSize sized chunk of data at position relative to tail - * The out pointer will be malloc'd with size unitSize and will have a copy of - * the data at the specified unitSize * index relative to tail in reverse - * direction. - * Note that the out data must be free'd, but on fail nothing will be malloc'd - * and *out will be set to NULL. - * \return non-zero if unitSize * index < size - */ -int UDPC_Deque_index_rev(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, void **out); - -/*! - * \brief Get a ptr to the indexed data at position unitSize * index - * The ptr will be indexed relative to the tail of the Deque. - * The returned ptr is part of the Deque's internal buffer and will be free'd - * when the Deque is destroyed, so it should not be free'd directly. - * \return non-null if indexed data is a valid contiguous part of the buffer - */ -void* UDPC_Deque_index_rev_ptr(UDPC_Deque *deque, uint32_t unitSize, uint32_t index); - -/*! - * \brief Replaces the data at index with data at the end (if exists) - * Note this will reduce the size of the Deque by unitSize amount. - * \return non-zero if data was removed - */ -int UDPC_Deque_remove(UDPC_Deque *deque, uint32_t unitSize, uint32_t index); - -void UDPC_Deque_clear(UDPC_Deque *deque); - -#endif diff --git a/c_impl/src/UDPC_HashMap.c b/c_impl/src/UDPC_HashMap.c deleted file mode 100644 index ac7217e..0000000 --- a/c_impl/src/UDPC_HashMap.c +++ /dev/null @@ -1,315 +0,0 @@ -#include "UDPC_HashMap.h" - -#include -#include - -UDPC_HashMap* UDPC_HashMap_init(uint32_t capacity, uint32_t unitSize) -{ - UDPC_HashMap *m = malloc(sizeof(UDPC_HashMap)); - if(!m) - { - return NULL; - } - - int fail = 0; - m->size = 0; - m->capacity = (capacity > UDPC_HASHMAP_INIT_CAPACITY ? capacity : UDPC_HASHMAP_INIT_CAPACITY); - m->unitSize = unitSize; - - m->buckets = malloc(sizeof(UDPC_HashMap_Node*) * m->capacity); - if(!m->buckets) - { - free(m); - return NULL; - } - - for(int x = 0; x < m->capacity; ++x) - { - if(fail != 0) - { - m->buckets[x] = NULL; - continue; - } - m->buckets[x] = calloc(1, sizeof(UDPC_HashMap_Node)); - if(!m->buckets[x]) - { - fail = 1; - } - } - - if(fail != 0) - { - for(int x = 0; x < m->capacity; ++x) - { - if(m->buckets[x]) - { - free(m->buckets[x]); - } - } - free(m->buckets); - free(m); - return NULL; - } - - return m; -} - -void UDPC_HashMap_destroy(UDPC_HashMap *hashMap) -{ - UDPC_HashMap_Node *current; - UDPC_HashMap_Node *next; - for(int x = 0; x < hashMap->capacity; ++x) - { - current = hashMap->buckets[x]; - while(current) - { - next = current->next; - if(current->data) { free(current->data); } - free(current); - current = next; - } - } - free(hashMap->buckets); - free(hashMap); -} - -void* UDPC_HashMap_insert(UDPC_HashMap *hm, uint32_t key, void *data) -{ - if(hm->capacity <= hm->size) - { - if(UDPC_HashMap_realloc(hm, hm->capacity * 2) == 0) - { - return NULL; - } - } - - uint32_t hash = UDPC_HASHMAP_MOD(key, hm->capacity); - - UDPC_HashMap_Node *current = hm->buckets[hash]; - while(current->next) - { - current = current->next; - } - current->next = malloc(sizeof(UDPC_HashMap_Node)); - current->next->key = key; - if(hm->unitSize != 0) - { - current->next->data = malloc(hm->unitSize); - memcpy(current->next->data, data, hm->unitSize); - } - else - { - current->next->data = NULL; - } - current->next->next = NULL; - current->next->prev = current; - - ++hm->size; - return current->next->data; -} - -int UDPC_HashMap_remove(UDPC_HashMap *hm, uint32_t key) -{ - if(hm->size == 0) - { - return 0; - } - - uint32_t hash = UDPC_HASHMAP_MOD(key, hm->capacity); - - UDPC_HashMap_Node *current = hm->buckets[hash]->next; - while(current && current->key != key) - { - current = current->next; - } - - if(!current) { return 0; } - - current->prev->next = current->next; - if(current->next) { current->next->prev = current->prev; } - - if(current->data) { free(current->data); } - free(current); - - --hm->size; - - return 1; -} - -void* UDPC_HashMap_get(UDPC_HashMap *hm, uint32_t key) -{ - if(hm->size == 0) - { - return NULL; - } - - uint32_t hash = UDPC_HASHMAP_MOD(key, hm->capacity); - - UDPC_HashMap_Node *current = hm->buckets[hash]; - while(current && (current == hm->buckets[hash] || current->key != key)) - { - current = current->next; - } - - if(!current) { return NULL; } - - return current->data; -} - -int UDPC_HashMap_has(UDPC_HashMap *hm, uint32_t key) -{ - if(hm->size == 0) - { - return 0; - } - - uint32_t hash = UDPC_HASHMAP_MOD(key, hm->capacity); - - UDPC_HashMap_Node *current = hm->buckets[hash]; - while(current && (current == hm->buckets[hash] || current->key != key)) - { - current = current->next; - } - - return current != NULL ? 1 : 0; -} - -int UDPC_HashMap_realloc(UDPC_HashMap *hm, uint32_t newCapacity) -{ - if(hm->size > newCapacity) - { - return 0; - } - - // allocate newBuckets - int fail = 0; - UDPC_HashMap_Node **newBuckets = malloc(sizeof(UDPC_HashMap_Node*) * newCapacity); - if(!newBuckets) { return 0; } - for(int x = 0; x < newCapacity; ++x) - { - if(fail != 0) { newBuckets[x] = NULL; continue; } - newBuckets[x] = calloc(1, sizeof(UDPC_HashMap_Node)); - if(!newBuckets[x]) { fail = 1; } - } - if(fail != 0) - { - for(int x = 0; x < newCapacity; ++x) - { - if(newBuckets[x]) { free(newBuckets[x]); } - } - free(newBuckets); - return 0; - } - - // rehash entries from hm->buckets to newBuckets - uint32_t hash; - UDPC_HashMap_Node *current; - UDPC_HashMap_Node *next; - UDPC_HashMap_Node *newCurrent; - for(int x = 0; x < hm->capacity; ++x) - { - current = hm->buckets[x]->next; - while(current) - { - next = current->next; - hash = UDPC_HASHMAP_MOD(current->key, newCapacity); - newCurrent = newBuckets[hash]; - while(newCurrent->next) - { - newCurrent = newCurrent->next; - } - newCurrent->next = malloc(sizeof(UDPC_HashMap_Node)); - if(!newCurrent->next) - { - fail = 1; - break; - } - newCurrent->next->key = current->key; - newCurrent->next->data = current->data; - newCurrent->next->next = NULL; - newCurrent->next->prev = newCurrent; - current = next; - } - if(fail != 0) - { - break; - } - } - if(fail != 0) - { - for(int x = 0; x < newCapacity; ++x) - { - current = newBuckets[x]; - while(current) - { - next = current->next; - free(current); - current = next; - } - } - free(newBuckets); - return 0; - } - - // cleanup hm->buckets to be replaced by newBuckets - for(int x = 0; x < hm->capacity; ++x) - { - current = hm->buckets[x]; - while(current) - { - next = current->next; - // do not free current->data as it is now being pointed to by entries in newBuckets - free(current); - current = next; - } - } - free(hm->buckets); - - hm->capacity = newCapacity; - hm->buckets = newBuckets; - - return 1; -} - -void UDPC_HashMap_clear(UDPC_HashMap *hm) -{ - UDPC_HashMap_Node *current; - UDPC_HashMap_Node *next; - for(int x = 0; x < hm->capacity; ++x) - { - current = hm->buckets[x]->next; - while(current) - { - next = current->next; - if(current->data) { free(current->data); } - free(current); - current = next; - } - hm->buckets[x]->next = NULL; - } - hm->size = 0; -} - -uint32_t UDPC_HashMap_get_size(UDPC_HashMap *hm) -{ - return hm->size; -} - -uint32_t UDPC_HashMap_get_capacity(UDPC_HashMap *hm) -{ - return hm->capacity; -} - -void UDPC_HashMap_itercall(UDPC_HashMap *hm, void (*fn)(void*, uint32_t, char*), void *userData) -{ - UDPC_HashMap_Node *current; - for(int x = 0; x < hm->capacity; ++x) - { - current = hm->buckets[x]->next; - while(current) - { - fn(userData, current->key, current->data); - current = current->next; - } - } -} diff --git a/c_impl/src/UDPC_HashMap.h b/c_impl/src/UDPC_HashMap.h deleted file mode 100644 index c36d3af..0000000 --- a/c_impl/src/UDPC_HashMap.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef UDPC_HASHMAP_H -#define UDPC_HASHMAP_H - -#include - -// 5 8 2 7 3 6 1 -// 3 2 5 1 8 7 6 -#define UDPC_HASH32(x) ( \ - ( \ - (((x) & 0xF8000000) >> 5) | \ - (((x) & 0x07F80000) >> 6) | \ - (((x) & 0x00060000) << 10) | \ - (((x) & 0x0001FC00) >> 4) | \ - (((x) & 0x00000380) << 22) | \ - (((x) & 0x0000007E) >> 1) | \ - (((x) & 0x00000001) << 21) \ - ) ^ 0x96969696 \ -) - -#define UDPC_HASHMAP_INIT_CAPACITY 13 - -#define UDPC_HASHMAP_MOD(k, m) ((UDPC_HASH32(k) % (m * 2 + 1)) % m) - -struct UDPC_HashMap_Node { - uint32_t key; - char *data; - struct UDPC_HashMap_Node *next; - struct UDPC_HashMap_Node *prev; -}; -typedef struct UDPC_HashMap_Node UDPC_HashMap_Node; - -typedef struct { - uint32_t size; - uint32_t capacity; - uint32_t unitSize; - UDPC_HashMap_Node **buckets; -} UDPC_HashMap; - -/*! - * \brief Creates a HashMap structure - * Note that UDPC_HashMap_destroy must be called on the returned ptr to free - * resources to avoid a memory leak. - * \return non-null if creating the HashMap was successful - */ -UDPC_HashMap* UDPC_HashMap_init(uint32_t capacity, uint32_t unitSize); - -/*! - * \brief Releases resources used by a HashMap structure - */ -void UDPC_HashMap_destroy(UDPC_HashMap *hashMap); - -/*! - * \brief Inserts a copy of data pointed to by given pointer - * Note if size already equals capacity, the hash map's capacity is doubled - * with UDPC_HashMap_realloc(). realloc requires rehashing of all items which - * may be costly. - * Also, if the hash map runs out of space for a specific key to insert, it will - * also invoke realloc() with double the previous capacity and will attempt to - * insert again afterwards. - * It is possible to insert items with duplicate keys. In that case, the first - * duplicate inserted will be the first returned with get() and first removed - * with remove(). - * \return Pointer to inserted data, NULL on fail or unitSize = 0 - */ -void* UDPC_HashMap_insert(UDPC_HashMap *hm, uint32_t key, void *data); - -/*! - * \brief Removes data with the given key - * \return non-zero if data was successfully removed - */ -int UDPC_HashMap_remove(UDPC_HashMap *hm, uint32_t key); - -/*! - * \brief Returns a pointer to data with the given key - * Note if unitSize == 0, then the returned pointer will point to a copy of - * its integer key, which should not be changed manually (otherwise, the hash - * map would not be able to find it). - * \return non-NULL if data was found and unitSize != 0 - */ -void* UDPC_HashMap_get(UDPC_HashMap *hm, uint32_t key); - -/*! - * \return non-zero if item with specified key is in the hash map - */ -int UDPC_HashMap_has(UDPC_HashMap *hm, uint32_t key); - -/*! - * \brief Resizes the maximum capacity of a hash map - * Note on fail, the hash map is unchanged. - * If newCapacity is less than the current size of the hash map, this function - * will fail. - * \return non-zero if resizing was successful - */ -int UDPC_HashMap_realloc(UDPC_HashMap *hm, uint32_t newCapacity); - -/*! - * \brief Empties the hash map - */ -void UDPC_HashMap_clear(UDPC_HashMap *hm); - -uint32_t UDPC_HashMap_get_size(UDPC_HashMap *hm); - -uint32_t UDPC_HashMap_get_capacity(UDPC_HashMap *hm); - -/*! - * \brief Calls a fn with a ptr to each entry in the hash map - * The fn is called with userData, entry key, and entry data. - */ -void UDPC_HashMap_itercall(UDPC_HashMap *hm, void (*fn)(void*, uint32_t, char*), void *userData); - -#endif diff --git a/c_impl/src/UDPConnection.c b/c_impl/src/UDPConnection.c deleted file mode 100644 index 7278486..0000000 --- a/c_impl/src/UDPConnection.c +++ /dev/null @@ -1,1517 +0,0 @@ -#include "UDPC_Defines.h" -#include "UDPConnection.h" - -const char *UDPC_ERR_SOCKETFAIL_STR = "Failed to create socket"; -const char *UDPC_ERR_SOCKETBINDF_STR = "Failed to bind socket"; -const char *UDPC_ERR_SOCKETNONBF_STR = "Failed to set non-blocking on socket"; -const char *UDPC_ERR_MTXFAIL_STR = "Failed to create mutex"; -const char *UDPC_ERR_CVFAIL_STR = "Failed to create condition variable"; -const char *UDPC_ERR_THREADFAIL_STR = "Failed to create thread"; - -#include -#include -#include -#include -#include - -UDPC_Context* UDPC_init(uint16_t listenPort, uint32_t listenAddr, int isClient) -{ - UDPC_Context *context = malloc(sizeof(UDPC_Context)); - context->isThreaded = 0; - context->protocolID = UDPC_PKT_DEFAULT_PROTOCOL_ID; - context->error = UDPC_SUCCESS; - context->flags = 0x4C; - if(isClient != 0) context->flags |= 0x2; - context->threadFlags = 0; - context->conMap = UDPC_HashMap_init(13, sizeof(UDPC_INTERNAL_ConnectionData)); - context->idMap = UDPC_HashMap_init(13, sizeof(UDPC_INTERNAL_ConnectionData*)); - timespec_get(&context->lastUpdated, TIME_UTC); - context->atostrBuf[UDPC_ATOSTR_BUF_SIZE - 1] = 0; - context->connectedEvents = UDPC_Deque_init( - UDPC_CONNECTED_EVENT_SIZE * 4); - context->disconnectedEvents = UDPC_Deque_init( - UDPC_DISCONNECTED_EVENT_SIZE * 4); - context->receivedPackets = UDPC_Deque_init( - UDPC_REC_PKTS_ALLOC_SIZE * sizeof(UDPC_INTERNAL_PacketInfo)); - context->callbackConnected = NULL; - context->callbackConnectedUserData = NULL; - context->callbackDisconnected = NULL; - context->callbackDisconnectedUserData = NULL; - context->callbackReceived = NULL; - context->callbackReceivedUserData = NULL; - - // seed rand - srand(context->lastUpdated.tv_sec); - - // create socket - context->socketHandle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if(context->socketHandle <= 0) - { - context->socketHandle = 0; - context->error = UDPC_ERR_SOCKETFAIL; - UDPC_INTERNAL_log(context, 0, "Failed to create socket"); - return context; - } - - // bind socket - context->socketInfo.sin_family = AF_INET; - context->socketInfo.sin_addr.s_addr = - (listenAddr == 0 ? INADDR_ANY : listenAddr); - context->socketInfo.sin_port = htons(listenPort); - if(bind( - context->socketHandle, - (const struct sockaddr*) &context->socketInfo, - sizeof(struct sockaddr_in) - ) < 0) - { - context->error = UDPC_ERR_SOCKETBINDF; - CleanupSocket(context->socketHandle); - context->socketHandle = 0; - UDPC_INTERNAL_log(context, 0, "Failed to bind socket"); - return context; - } - - // set nonblocking on socket -#if UDPC_PLATFORM == UDPC_PLATFORM_MAC || UDPC_PLATFORM == UDPC_PLATFORM_LINUX - int nonblocking = 1; - if(fcntl(context->socketHandle, F_SETFL, O_NONBLOCK, nonblocking) == -1) - { -#elif UDPC_PLATFORM == UDPC_PLATFORM_WINDOWS - DWORD nonblocking = 1; - if(ioctlsocket(context->socketHandle, FIONBIO, &nonblocking) != 0) - { -#else - { -#endif - context->error = UDPC_ERR_SOCKETNONBF; - CleanupSocket(context->socketHandle); - context->socketHandle = 0; - UDPC_INTERNAL_log(context, 0, "Failed to set non-blocking on socket"); -#if UDPC_PLATFORM == UDPC_PLATFORM_UNKNOWN - UDPC_INTERNAL_log(context, 0, "(Unknown platform)"); -#endif - return context; - } - - return context; -} - -UDPC_Context* UDPC_init_threaded_update(uint16_t listenPort, uint32_t listenAddr, int isClient) -{ - UDPC_Context *context = UDPC_init(listenPort, listenAddr, isClient); - - context->isThreaded = 1; - - context->error = mtx_init(&context->tCVMtx, mtx_timed); - if(context->error != thrd_success) - { - CleanupSocket(context->socketHandle); - context->socketHandle = 0; - UDPC_INTERNAL_log(context, 0, "Failed to create mutex"); - context->error = UDPC_ERR_MTXFAIL; - return context; - } - context->error = UDPC_SUCCESS; - - context->error = mtx_init(&context->tflagsMtx, mtx_timed); - if(context->error != thrd_success) - { - CleanupSocket(context->socketHandle); - context->socketHandle = 0; - mtx_destroy(&context->tCVMtx); - UDPC_INTERNAL_log(context, 0, "Failed to create mutex"); - context->error = UDPC_ERR_MTXFAIL; - return context; - } - context->error = UDPC_SUCCESS; - - context->error = cnd_init(&context->threadCV); - if(context->error != thrd_success) - { - CleanupSocket(context->socketHandle); - context->socketHandle = 0; - mtx_destroy(&context->tCVMtx); - mtx_destroy(&context->tflagsMtx); - UDPC_INTERNAL_log(context, 0, "Failed to create condition variable"); - context->error = UDPC_ERR_CVFAIL; - return context; - } - context->error = UDPC_SUCCESS; - - context->error = thrd_create( - &context->threadHandle, UDPC_INTERNAL_threadfn, context); - if(context->error != thrd_success) - { - CleanupSocket(context->socketHandle); - context->socketHandle = 0; - mtx_destroy(&context->tCVMtx); - mtx_destroy(&context->tflagsMtx); - cnd_destroy(&context->threadCV); - UDPC_INTERNAL_log(context, 0, "Failed to create thread"); - context->error = UDPC_ERR_THREADFAIL; - return context; - } - context->error = UDPC_SUCCESS; - - return context; -} - -void UDPC_destroy(UDPC_Context *ctx) -{ - if(ctx->isThreaded != 0) - { - mtx_lock(&ctx->tflagsMtx); - ctx->threadFlags |= 0x1; - mtx_unlock(&ctx->tflagsMtx); - cnd_broadcast(&ctx->threadCV); - - thrd_join(ctx->threadHandle, NULL); - - mtx_destroy(&ctx->tCVMtx); - mtx_destroy(&ctx->tflagsMtx); - cnd_destroy(&ctx->threadCV); - } - - CleanupSocket(ctx->socketHandle); - UDPC_HashMap_itercall(ctx->conMap, UDPC_INTERNAL_destroy_conMap, NULL); - UDPC_HashMap_destroy(ctx->conMap); - UDPC_HashMap_destroy(ctx->idMap); - - UDPC_Deque_destroy(ctx->connectedEvents); - UDPC_Deque_destroy(ctx->disconnectedEvents); - - while(ctx->receivedPackets->size != 0) - { - UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_get_front_ptr(ctx->receivedPackets, sizeof(UDPC_INTERNAL_PacketInfo)); - if(pinfo->data) { free(pinfo->data); } - UDPC_Deque_pop_front(ctx->receivedPackets, sizeof(UDPC_INTERNAL_PacketInfo)); - } - UDPC_Deque_destroy(ctx->receivedPackets); - - free(ctx); -} - -void UDPC_INTERNAL_destroy_conMap(void *unused, uint32_t addr, char *data) -{ - UDPC_INTERNAL_ConnectionData *cd = (UDPC_INTERNAL_ConnectionData*)data; - - for(int x = 0; x * sizeof(UDPC_INTERNAL_PacketInfo) < cd->sentPkts->size; ++x) - { - UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_index_ptr( - cd->sentPkts, sizeof(UDPC_INTERNAL_PacketInfo), x); - if(pinfo->data) - { - free(pinfo->data); - } - } - UDPC_Deque_destroy(cd->sentPkts); - - for(int x = 0; x * sizeof(UDPC_INTERNAL_PacketInfo) < cd->sendPktQueue->size; ++x) - { - UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_index_ptr( - cd->sendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo), x); - if(pinfo->data) - { - free(pinfo->data); - } - } - UDPC_Deque_destroy(cd->sendPktQueue); - - for(int x = 0; x * sizeof(UDPC_INTERNAL_PacketInfo) < cd->priorityPktQueue->size; ++x) - { - UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_index_ptr( - cd->priorityPktQueue, sizeof(UDPC_INTERNAL_PacketInfo), x); - if(pinfo->data) - { - free(pinfo->data); - } - } - UDPC_Deque_destroy(cd->priorityPktQueue); -} - -void UDPC_set_callback_connected( - UDPC_Context *ctx, UDPC_callback_connected fptr, void *userData) -{ - if(ctx->isThreaded != 0) { mtx_lock(&ctx->tCVMtx); } - - ctx->callbackConnected = fptr; - ctx->callbackConnectedUserData = userData; - - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } -} - -void UDPC_set_callback_disconnected( - UDPC_Context *ctx, UDPC_callback_disconnected fptr, void *userData) -{ - if(ctx->isThreaded != 0) { mtx_lock(&ctx->tCVMtx); } - - ctx->callbackDisconnected = fptr; - ctx->callbackDisconnectedUserData = userData; - - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } -} - -void UDPC_set_callback_received( - UDPC_Context *ctx, UDPC_callback_received fptr, void *userData) -{ - if(ctx->isThreaded != 0) { mtx_lock(&ctx->tCVMtx); } - - ctx->callbackReceived = fptr; - ctx->callbackReceivedUserData = userData; - - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } -} - -void UDPC_check_events(UDPC_Context *ctx) -{ - if(ctx->isThreaded != 0) { mtx_lock(&ctx->tCVMtx); } - - if(ctx->callbackConnected) - { - for(int x = 0; x * 4 < ctx->connectedEvents->size; ++x) - { - ctx->callbackConnected(ctx->callbackConnectedUserData, - *((uint32_t*)UDPC_Deque_index_ptr(ctx->connectedEvents, 4, x))); - } - UDPC_Deque_clear(ctx->connectedEvents); - } - else - { - UDPC_INTERNAL_log(ctx, 0, "Connected callback not set"); - UDPC_Deque_clear(ctx->connectedEvents); - } - - if(ctx->callbackDisconnected) - { - for(int x = 0; x * 4 < ctx->disconnectedEvents->size; ++x) - { - ctx->callbackDisconnected(ctx->callbackDisconnectedUserData, - *((uint32_t*)UDPC_Deque_index_ptr(ctx->disconnectedEvents, 4, x))); - } - UDPC_Deque_clear(ctx->disconnectedEvents); - } - else - { - UDPC_INTERNAL_log(ctx, 0, "Disconnected callback not set"); - UDPC_Deque_clear(ctx->disconnectedEvents); - } - - if(ctx->callbackReceived) - { - for(int x = 0; x * sizeof(UDPC_INTERNAL_PacketInfo) < ctx->receivedPackets->size; ++x) - { - UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_index_ptr( - ctx->receivedPackets, sizeof(UDPC_INTERNAL_PacketInfo), x); - ctx->callbackReceived( - ctx->callbackReceivedUserData, - pinfo->addr, - pinfo->data, - pinfo->size); - free(pinfo->data); - } - UDPC_Deque_clear(ctx->receivedPackets); - } - else - { - UDPC_INTERNAL_log(ctx, 0, "Received callback not set"); - for(int x = 0; x * sizeof(UDPC_INTERNAL_PacketInfo) < ctx->receivedPackets->size; ++x) - { - UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_index_ptr( - ctx->receivedPackets, sizeof(UDPC_INTERNAL_PacketInfo), x); - free(pinfo->data); - } - UDPC_Deque_clear(ctx->receivedPackets); - } - - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } -} - -void UDPC_client_initiate_connection(UDPC_Context *ctx, uint32_t addr, uint16_t port) -{ - if(ctx->isThreaded != 0) { mtx_lock(&ctx->tCVMtx); } - - if((ctx->flags & 0x2) == 0 || UDPC_HashMap_has(ctx->conMap, addr) != 0) - { - // must be client or no already-existing connection to same address - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } - return; - } - - UDPC_INTERNAL_ConnectionData cd = { - 0x9, - 0, - 1, - 0, - 0xFFFFFFFF, - 0.0f, - 30.0f, - 0.0f, - 0.0f, - addr, - port, - UDPC_Deque_init(sizeof(UDPC_INTERNAL_PacketInfo) * UDPC_SENT_PKTS_ALLOC_SIZE), - UDPC_Deque_init(sizeof(UDPC_INTERNAL_PacketInfo) * UDPC_SEND_PKTS_ALLOC_SIZE), - UDPC_Deque_init(sizeof(UDPC_INTERNAL_PacketInfo) * UDPC_RESEND_PKTS_ALLOC_SIZE), - {0, 0}, - {0, 0}, - 0.0f - }; - - timespec_get(&cd.received, TIME_UTC); - cd.sent = cd.received; - cd.sent.tv_sec -= UDPC_INIT_PKT_INTERVAL + 1; - - UDPC_HashMap_insert(ctx->conMap, addr, &cd); - - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } -} - -int UDPC_queue_send(UDPC_Context *ctx, uint32_t addr, uint32_t isChecked, void *data, uint32_t size) -{ - if(ctx->isThreaded != 0) { mtx_lock(&ctx->tCVMtx); } - - UDPC_INTERNAL_ConnectionData *cd = UDPC_HashMap_get(ctx->conMap, addr); - if(cd) - { - UDPC_INTERNAL_PacketInfo pinfo = { - addr, - 0, - isChecked != 0 ? 0x2 : 0, - malloc(size), - size, - {0, 0} - }; - if(pinfo.data) - { - memcpy(pinfo.data, data, size); - if(UDPC_Deque_push_back(cd->sendPktQueue, &pinfo, sizeof(UDPC_INTERNAL_PacketInfo)) == 0) - { - UDPC_INTERNAL_log(ctx, 1, "Not enough free space in send " - "packet queue, failed to queue packet for sending"); - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } - return 0; - } - else - { - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } - return 1; - } - } - else - { - UDPC_INTERNAL_log(ctx, 0, "Failed to allocate memory to new send-packet queue entry"); - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } - return 0; - } - } - else - { - UDPC_INTERNAL_log(ctx, 0, "Cannot send to %s when connection has not been esablished", - UDPC_INTERNAL_atostr(ctx, addr)); - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } - return 0; - } -} - -int UDPC_get_queue_send_available(UDPC_Context *ctx, uint32_t addr) -{ - if(ctx->isThreaded != 0) { mtx_lock(&ctx->tCVMtx); } - - UDPC_INTERNAL_ConnectionData *cd = UDPC_HashMap_get(ctx->conMap, addr); - if(!cd) - { - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } - return 0; - } - - int available = UDPC_Deque_get_available(cd->sendPktQueue) / sizeof(UDPC_INTERNAL_PacketInfo); - - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } - - return available; -} - -int UDPC_get_accept_new_connections(UDPC_Context *ctx) -{ - if(ctx->isThreaded != 0) { mtx_lock(&ctx->tCVMtx); } - - int result = (ctx->flags & 0x40) != 0 ? 1 : 0; - - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } - - return result; -} - -void UDPC_set_accept_new_connections(UDPC_Context *ctx, int isAccepting) -{ - if(ctx->isThreaded != 0) { mtx_lock(&ctx->tCVMtx); } - - if(isAccepting != 0) { ctx->flags |= 0x40; } - else { ctx->flags &= 0xFFFFFFBF; } - - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } -} - -int UDPC_drop_connection(UDPC_Context *ctx, uint32_t addr) -{ - int wasDropped = 0; - - if(ctx->isThreaded != 0) { mtx_lock(&ctx->tCVMtx); } - - UDPC_INTERNAL_ConnectionData *cd = UDPC_HashMap_get(ctx->conMap, addr); - if(cd) - { - if((cd->flags & 0x10) != 0) - { - UDPC_HashMap_remove(ctx->idMap, cd->id); - } - UDPC_HashMap_remove(ctx->conMap, addr); - wasDropped = 1; - } - - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } - - return wasDropped; -} - -uint32_t UDPC_get_protocol_id(UDPC_Context *ctx) -{ - if(ctx->isThreaded != 0) { mtx_lock(&ctx->tCVMtx); } - - uint32_t id = ctx->protocolID; - - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } - - return id; -} - -void UDPC_set_protocol_id(UDPC_Context *ctx, uint32_t id) -{ - if(ctx->isThreaded != 0) { mtx_lock(&ctx->tCVMtx); } - - ctx->protocolID = id; - - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } -} - -uint32_t UDPC_get_error(UDPC_Context *ctx) -{ - if(ctx->isThreaded != 0) { mtx_lock(&ctx->tCVMtx); } - - uint32_t error = ctx->error; - ctx->error = 0; - - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } - - return error; -} - -const char* UDPC_get_error_str(uint32_t error) -{ - switch(error) - { - case UDPC_SUCCESS: return "No error"; - case UDPC_ERR_SOCKETFAIL: return UDPC_ERR_SOCKETFAIL_STR; - case UDPC_ERR_SOCKETBINDF: return UDPC_ERR_SOCKETBINDF_STR; - case UDPC_ERR_SOCKETNONBF: return UDPC_ERR_SOCKETNONBF_STR; - case UDPC_ERR_MTXFAIL: return UDPC_ERR_MTXFAIL_STR; - case UDPC_ERR_CVFAIL: return UDPC_ERR_CVFAIL_STR; - case UDPC_ERR_THREADFAIL: return UDPC_ERR_THREADFAIL_STR; - default: return "Unknown error"; - } -} - -void UDPC_set_logging_type(UDPC_Context *ctx, uint32_t logType) -{ - if(ctx->isThreaded != 0) { mtx_lock(&ctx->tCVMtx); } - - switch(logType) - { - case 0: - ctx->flags &= 0xFFFFFFC3; - break; - case 1: - ctx->flags &= 0xFFFFFFC7; - ctx->flags |= 0x4; - break; - case 2: - ctx->flags &= 0xFFFFFFCF; - ctx->flags |= (0x4 | 0x8); - break; - case 3: - ctx->flags &= 0xFFFFFFDF; - ctx->flags |= (0x4 | 0x8 | 0x10); - break; - default: - ctx->flags |= (0x4 | 0x8 | 0x10 | 0x20); - break; - } - - if(ctx->isThreaded != 0) { mtx_unlock(&ctx->tCVMtx); } -} - -void UDPC_update(UDPC_Context *ctx) -{ - UDPC_INTERNAL_update_struct us = { - {0, 0}, - 0.0f, - NULL, - ctx - }; - timespec_get(&us.tsNow, TIME_UTC); - us.dt = UDPC_INTERNAL_ts_diff(&us.tsNow, &ctx->lastUpdated); - ctx->lastUpdated = us.tsNow; - us.removedQueue = UDPC_Deque_init(4 * (ctx->conMap->size)); - - UDPC_HashMap_itercall(ctx->conMap, UDPC_INTERNAL_update_to_rtt_si, &us); - - // remove timed out - for(int x = 0; x * 4 < us.removedQueue->size; ++x) - { - uint32_t *key = UDPC_Deque_index_ptr(us.removedQueue, 4, x); - UDPC_INTERNAL_ConnectionData *cd = UDPC_HashMap_get(ctx->conMap, *key); - - while(cd->sentPkts->size != 0) - { - UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_get_front_ptr(cd->sentPkts, sizeof(UDPC_INTERNAL_PacketInfo)); - if(pinfo->data) { free(pinfo->data); } - UDPC_Deque_pop_front(cd->sentPkts, sizeof(UDPC_INTERNAL_PacketInfo)); - } - UDPC_Deque_destroy(cd->sentPkts); - - while(cd->sendPktQueue->size != 0) - { - UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_get_front_ptr(cd->sendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo)); - if(pinfo->data) { free(pinfo->data); } - UDPC_Deque_pop_front(cd->sendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo)); - } - UDPC_Deque_destroy(cd->sendPktQueue); - - while(cd->priorityPktQueue->size != 0) - { - UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_get_front_ptr(cd->priorityPktQueue, sizeof(UDPC_INTERNAL_PacketInfo)); - if(pinfo->data) { free(pinfo->data); } - UDPC_Deque_pop_front(cd->priorityPktQueue, sizeof(UDPC_INTERNAL_PacketInfo)); - } - UDPC_Deque_destroy(cd->priorityPktQueue); - - if((cd->flags & 0x10) != 0) - { - UDPC_HashMap_remove(ctx->idMap, cd->id); - } - UDPC_HashMap_remove(ctx->conMap, *key); - } - UDPC_Deque_destroy(us.removedQueue); - us.removedQueue = NULL; - - // check triggerSend to send packets to connected - UDPC_HashMap_itercall(ctx->conMap, UDPC_INTERNAL_update_send, &us); - - // receive packet -#if UDPC_PLATFORM == UDPC_PLATFORM_WINDOWS - typedef int socklen_t; -#endif - struct sockaddr_in receivedData; - socklen_t receivedDataSize = sizeof(receivedData); - int bytes = recvfrom( - ctx->socketHandle, - ctx->recvBuf, - UDPC_PACKET_MAX_SIZE, - 0, - (struct sockaddr*) &receivedData, - &receivedDataSize); - - if(bytes == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) - { - // expected result for non-blocking socket - return; - } - - if(bytes < 20) - { - UDPC_INTERNAL_log(ctx, 2, "Got invalid packet from %s port %d (too small)", - UDPC_INTERNAL_atostr(ctx, receivedData.sin_addr.s_addr), - ntohs(receivedData.sin_port)); - return; - } - - uint32_t temp = ntohl(*((uint32_t*)ctx->recvBuf)); - if(temp != ctx->protocolID) - { - UDPC_INTERNAL_log(ctx, 2, "Got invalid packet from %s port %d (invalid protocol id)", - UDPC_INTERNAL_atostr(ctx, receivedData.sin_addr.s_addr), - ntohs(receivedData.sin_port)); - return; - } - - uint32_t conID = ntohl(*((uint32_t*)(ctx->recvBuf + 4))); - uint32_t seqID = ntohl(*((uint32_t*)(ctx->recvBuf + 8))); - uint32_t rseq = ntohl(*((uint32_t*)(ctx->recvBuf + 12))); - uint32_t ack = ntohl(*((uint32_t*)(ctx->recvBuf + 16))); - - int isConnect = conID & UDPC_ID_CONNECT; - int isPing = conID & UDPC_ID_PING; - int isNotRecvCheck = conID & UDPC_ID_NO_REC_CHK; - int isResent = conID & UDPC_ID_RESENDING; - conID &= 0x0FFFFFFF; - - if(isConnect != 0 && (ctx->flags & 0x40) != 0) - { - if((ctx->flags & 0x2) == 0 - && !UDPC_HashMap_get(ctx->conMap, receivedData.sin_addr.s_addr)) - { - UDPC_INTERNAL_log(ctx, 2, "Establishing connection with %s port %d", - UDPC_INTERNAL_atostr(ctx, receivedData.sin_addr.s_addr), - ntohs(receivedData.sin_port)); - UDPC_INTERNAL_ConnectionData newCD = { - 0x19, - UDPC_INTERNAL_generate_id(ctx), - 0, - 0, - 0xFFFFFFFF, - 0.0f, - 30.0f, - 0.0f, - 0.0f, - receivedData.sin_addr.s_addr, - ntohs(receivedData.sin_port), - UDPC_Deque_init(sizeof(UDPC_INTERNAL_PacketInfo) * UDPC_SENT_PKTS_ALLOC_SIZE), - UDPC_Deque_init(sizeof(UDPC_INTERNAL_PacketInfo) * UDPC_SEND_PKTS_ALLOC_SIZE), - UDPC_Deque_init(sizeof(UDPC_INTERNAL_PacketInfo) * UDPC_RESEND_PKTS_ALLOC_SIZE), - us.tsNow, - us.tsNow, - 0.0f - }; - UDPC_HashMap_insert(ctx->conMap, newCD.addr, &newCD); - UDPC_HashMap_insert(ctx->idMap, newCD.id, UDPC_HashMap_get(ctx->conMap, newCD.addr)); - if(UDPC_Deque_get_available(ctx->connectedEvents) == 0) - { - UDPC_Deque_pop_front(ctx->connectedEvents, 4); - UDPC_Deque_push_back(ctx->connectedEvents, &receivedData.sin_addr.s_addr, 4); - UDPC_INTERNAL_log(ctx, 1, "Not enough free space in connected " - "events queue, removing oldest to make room"); - } - else - { - UDPC_Deque_push_back(ctx->connectedEvents, &receivedData.sin_addr.s_addr, 4); - } - } - else if((ctx->flags & 0x2) != 0) - { - UDPC_INTERNAL_ConnectionData *cd = UDPC_HashMap_get(ctx->conMap, receivedData.sin_addr.s_addr); - if(!cd) { return; } - - cd->flags &= 0xFFFFFFF7; - cd->flags |= 0x10; - cd->id = conID; - UDPC_INTERNAL_log(ctx, 2, "Got id %u from server %s", conID, - UDPC_INTERNAL_atostr(ctx, receivedData.sin_addr.s_addr)); - if(UDPC_Deque_get_available(ctx->connectedEvents) == 0) - { - UDPC_Deque_pop_front(ctx->connectedEvents, 4); - UDPC_Deque_push_back(ctx->connectedEvents, &receivedData.sin_addr.s_addr, 4); - UDPC_INTERNAL_log(ctx, 1, "Not enough free space in connected " - "events queue, removing oldest to make room"); - } - else - { - UDPC_Deque_push_back(ctx->connectedEvents, &receivedData.sin_addr.s_addr, 4); - } - } - return; - } - else if(isPing != 0) - { - UDPC_INTERNAL_ConnectionData *cd = UDPC_HashMap_get(ctx->conMap, receivedData.sin_addr.s_addr); - if(cd) - { - cd->flags |= 0x1; - } - } - - UDPC_INTERNAL_ConnectionData *cd = UDPC_HashMap_get(ctx->conMap, receivedData.sin_addr.s_addr); - if(!cd) - { - // Received packet from unknown, ignoring - return; - } - else if(conID != cd->id) - { - // Received packet id and known id does not match, ignoring - return; - } - - // packet is valid - UDPC_INTERNAL_log(ctx, 2, "Valid packet %d from %s", seqID, - UDPC_INTERNAL_atostr(ctx, receivedData.sin_addr.s_addr)); - - UDPC_INTERNAL_update_rtt(ctx, cd, rseq, &us.tsNow); - cd->received = us.tsNow; - UDPC_INTERNAL_check_pkt_timeout(ctx, cd, rseq, ack, &us.tsNow); - - int isOutOfOrder = 0; - uint32_t diff = 0; - if(seqID > cd->rseq) - { - diff = seqID - cd->rseq; - if(diff <= 0x7FFFFFFF) - { - // seqeuence is more recent - cd->rseq = seqID; - cd->ack = (cd->ack >> diff) | 0x80000000; - } - else - { - // sequence is older id, diff requires recalc - diff = 0xFFFFFFFF - seqID + 1 + cd->rseq; - if((cd->ack & (0x80000000 >> (diff - 1))) != 0) - { - // already received packet - UDPC_INTERNAL_log(ctx, 2, "Ignoring already received pkt from %s", - UDPC_INTERNAL_atostr(ctx, cd->addr)); - return; - } - cd->ack |= (0x80000000 >> (diff - 1)); - - isOutOfOrder = 1; - } - } - else if(seqID < cd->rseq) - { - diff = cd->rseq - seqID; - if(diff <= 0x7FFFFFFF) - { - // sequence is older - if((cd->ack & (0x80000000 >> (diff - 1))) != 0) - { - // already received packet - UDPC_INTERNAL_log(ctx, 2, "Ignoring already received pkt from %s", - UDPC_INTERNAL_atostr(ctx, cd->addr)); - return; - } - cd->ack |= (0x80000000 >> (diff - 1)); - - isOutOfOrder = 1; - } - else - { - // sequence is more recent, diff requires recalc - diff = 0xFFFFFFFF - cd->rseq + 1 + seqID; - cd->rseq = seqID; - cd->ack = (cd->ack >> diff) | 0x80000000; - } - } - else - { - // already received packet - UDPC_INTERNAL_log(ctx, 2, "Ignoring already received (duplicate) pkt from %s", - UDPC_INTERNAL_atostr(ctx, cd->addr)); - return; - } - - if(isOutOfOrder != 0) - { - UDPC_INTERNAL_log(ctx, 2, "Received valid packet from %s is out of order", - UDPC_INTERNAL_atostr(ctx, cd->addr)); - } - - if(bytes > 20) - { - UDPC_INTERNAL_PacketInfo receivedInfo; - receivedInfo.addr = receivedData.sin_addr.s_addr; - receivedInfo.id = conID; - receivedInfo.flags = (isNotRecvCheck != 0 ? 0 : 0x2) | (isResent != 0 ? 0x5 : 0); - receivedInfo.data = malloc(bytes - 20); - memcpy(receivedInfo.data, ctx->recvBuf + 20, bytes - 20); - receivedInfo.size = bytes - 20; - receivedInfo.sent = us.tsNow; - - if(UDPC_Deque_get_available(ctx->receivedPackets) == 0) - { - UDPC_INTERNAL_PacketInfo *rpinfo = UDPC_Deque_get_front_ptr( - ctx->receivedPackets, sizeof(UDPC_INTERNAL_PacketInfo)); - if(rpinfo->data) { free(rpinfo->data); } - UDPC_Deque_pop_front(ctx->receivedPackets, sizeof(UDPC_INTERNAL_PacketInfo)); - UDPC_Deque_push_back(ctx->receivedPackets, &receivedInfo, sizeof(UDPC_INTERNAL_PacketInfo)); - UDPC_INTERNAL_log(ctx, 1, "Received packet but not enough space in received queue, removing oldest packet to make room"); - } - else - { - UDPC_Deque_push_back(ctx->receivedPackets, &receivedInfo, sizeof(UDPC_INTERNAL_PacketInfo)); - } - } - else - { - UDPC_INTERNAL_log(ctx, 3, "Packet has no payload, not adding to received queue"); - } -} - -void UDPC_INTERNAL_update_to_rtt_si(void *userData, uint32_t addr, char *data) -{ - UDPC_INTERNAL_update_struct *us = - (UDPC_INTERNAL_update_struct*)userData; - UDPC_INTERNAL_ConnectionData *cd = (UDPC_INTERNAL_ConnectionData*)data; - - // check for timed out connection - if(UDPC_INTERNAL_ts_diff(&us->tsNow, &cd->received) >= UDPC_TIMEOUT_SECONDS) - { - UDPC_Deque_push_back(us->removedQueue, &addr, 4); - UDPC_INTERNAL_log(us->ctx, 2, "Connection timed out with addr %s port %d", - UDPC_INTERNAL_atostr(us->ctx, addr), - cd->port); - if(UDPC_Deque_get_available(us->ctx->disconnectedEvents) == 0) - { - UDPC_Deque_pop_front(us->ctx->disconnectedEvents, 4); - UDPC_Deque_push_back(us->ctx->disconnectedEvents, &addr, 4); - UDPC_INTERNAL_log(us->ctx, 1, "Not enough free space in " - "disconnected events queue, removing oldest event to make room"); - } - else - { - UDPC_Deque_push_back(us->ctx->disconnectedEvents, &addr, 4); - } - return; - } - - // check good/bad mode - cd->toggleTimer += us->dt; - cd->toggledTimer += us->dt; - if((cd->flags & 0x2) != 0 && (cd->flags & 0x4) == 0) - { - // good mode, bad rtt - UDPC_INTERNAL_log(us->ctx, 2, "Connection with %s switching to bad mode", - UDPC_INTERNAL_atostr(us->ctx, addr)); - - cd->flags = cd->flags & 0xFFFFFFFD; - if(cd->toggledTimer <= 10.0f) - { - cd->toggleT *= 2.0f; - if(cd->toggleT > 60.0f) - { - cd->toggleT = 60.0f; - } - } - cd->toggledTimer = 0.0f; - } - else if((cd->flags & 0x2) != 0) - { - // good mode, good rtt - if(cd->toggleTimer >= 10.0f) - { - cd->toggleTimer = 0.0f; - cd->toggleT /= 2.0f; - if(cd->toggleT < 1.0f) - { - cd->toggleT = 1.0f; - } - } - } - else if((cd->flags & 0x2) == 0 && (cd->flags & 0x4) != 0) - { - // bad mode, good rtt - if(cd->toggledTimer >= cd->toggleT) - { - cd->toggleTimer = 0.0f; - cd->toggledTimer = 0.0f; - UDPC_INTERNAL_log(us->ctx, 2, "Connection with %s switching to good mode", - UDPC_INTERNAL_atostr(us->ctx, addr)); - cd->flags |= 0x2; - } - } - else - { - // bad mode, bad rtt - cd->toggledTimer = 0.0f; - } - - // check send interval - cd->timer += us->dt; - if(cd->timer >= ((cd->flags & 0x2) != 0 - ? UDPC_GOOD_MODE_SEND_INTERVAL : UDPC_BAD_MODE_SEND_INTERVAL)) - { - cd->timer = 0.0f; - cd->flags |= 0x1; - } -} - -void UDPC_INTERNAL_update_send(void *userData, uint32_t addr, char *data) -{ - UDPC_INTERNAL_update_struct *us = - (UDPC_INTERNAL_update_struct*)userData; - UDPC_INTERNAL_ConnectionData *cd = (UDPC_INTERNAL_ConnectionData*)data; - - if((cd->flags & 0x1) == 0) - { - return; - } - - cd->flags = cd->flags & 0xFFFFFFFE; - - if((cd->flags & 0x8) != 0) - { - if((us->ctx->flags & 0x2) != 0) - { - // initiate connection to server - if(UDPC_INTERNAL_ts_diff(&us->tsNow, &cd->sent) < UDPC_INIT_PKT_INTERVAL_F) - { - return; - } - cd->sent = us->tsNow; - - char *data = malloc(20); - UDPC_INTERNAL_prepare_pkt( - data, - us->ctx->protocolID, - 0, - 0, - 0xFFFFFFFF, - NULL, - 0x8); - - struct sockaddr_in destinationInfo; - destinationInfo.sin_family = AF_INET; - destinationInfo.sin_addr.s_addr = addr; - destinationInfo.sin_port = htons(cd->port); - long int sentBytes = sendto( - us->ctx->socketHandle, - data, - 20, - 0, - (struct sockaddr*) &destinationInfo, - sizeof(struct sockaddr_in)); - if(sentBytes != 20) - { - UDPC_INTERNAL_log(us->ctx, 0, "Failed to send init packet to %s " - "port %d", UDPC_INTERNAL_atostr(us->ctx, addr), cd->port); - free(data); - return; - } - free(data); - } - else - { - // initiate connection to client - cd->flags &= 0xFFFFFFF7; - cd->sent = us->tsNow; - - char *data = malloc(20); - UDPC_INTERNAL_prepare_pkt( - data, - us->ctx->protocolID, - cd->id, - cd->rseq, - cd->ack, - &cd->lseq, - 0x8); - - struct sockaddr_in destinationInfo; - destinationInfo.sin_family = AF_INET; - destinationInfo.sin_addr.s_addr = addr; - destinationInfo.sin_port = htons(cd->port); - long int sentBytes = sendto( - us->ctx->socketHandle, - data, - 20, - 0, - (struct sockaddr*) &destinationInfo, - sizeof(struct sockaddr_in)); - if(sentBytes != 20) - { - UDPC_INTERNAL_log(us->ctx, 0, "Failed to send init packet to %s " - "port %d", UDPC_INTERNAL_atostr(us->ctx, addr), cd->port); - free(data); - return; - } - free(data); - } - return; - } - - if(cd->sendPktQueue->size == 0 && cd->priorityPktQueue->size == 0) - { - // send and resend packet queue is empty, send heartbeat packet - if(UDPC_INTERNAL_ts_diff(&us->tsNow, &cd->sent) < UDPC_HEARTBEAT_PKT_INTERVAL) - { - return; - } - - char *data = malloc(20); - UDPC_INTERNAL_prepare_pkt( - data, us->ctx->protocolID, cd->id, cd->rseq, cd->ack, &cd->lseq, 0); - - struct sockaddr_in destinationInfo; - destinationInfo.sin_family = AF_INET; - destinationInfo.sin_addr.s_addr = addr; - destinationInfo.sin_port = htons(cd->port); - long int sentBytes = sendto( - us->ctx->socketHandle, - data, - 20, - 0, - (struct sockaddr*) &destinationInfo, - sizeof(struct sockaddr_in)); - if(sentBytes != 20) - { - UDPC_INTERNAL_log(us->ctx, 0, "Failed to send packet to %s port %d", - UDPC_INTERNAL_atostr(us->ctx, addr), cd->port); - free(data); - return; - } - - UDPC_INTERNAL_PacketInfo sentInfo = { - addr, - cd->lseq - 1, - 0, - NULL, - 0, - us->tsNow - }; - UDPC_Deque_push_back( - cd->sentPkts, &sentInfo, sizeof(UDPC_INTERNAL_PacketInfo)); - while(cd->sentPkts->size / sizeof(UDPC_INTERNAL_PacketInfo) > UDPC_SENT_PKTS_MAX_SIZE) - { - UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_get_front_ptr( - cd->sentPkts, - sizeof(UDPC_INTERNAL_PacketInfo)); - if(pinfo->data && pinfo->size != 0) - { - free(pinfo->data); - } - UDPC_Deque_pop_front(cd->sentPkts, sizeof(UDPC_INTERNAL_PacketInfo)); - } - free(data); - } - else // sendPktQueue or priorityPktQueue not empty - { - UDPC_INTERNAL_PacketInfo *pinfo; - int isResendingPkt = 0; - - if(cd->priorityPktQueue->size != 0) - { - pinfo = UDPC_Deque_get_front_ptr( - cd->priorityPktQueue, sizeof(UDPC_INTERNAL_PacketInfo)); - isResendingPkt = 1; - } - else - { - pinfo = UDPC_Deque_get_front_ptr( - cd->sendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo)); - } - char *data = malloc(20 + pinfo->size); - UDPC_INTERNAL_prepare_pkt( - data, - us->ctx->protocolID, - cd->id, - cd->rseq, - cd->ack, - &cd->lseq, - ((pinfo->flags & 0x3) << 1)); - memcpy(&data[20], pinfo->data, pinfo->size); - - struct sockaddr_in destinationInfo; - destinationInfo.sin_family = AF_INET; - destinationInfo.sin_addr.s_addr = addr; - destinationInfo.sin_port = htons(cd->port); - long int sentBytes = sendto( - us->ctx->socketHandle, - data, - 20 + pinfo->size, - 0, - (struct sockaddr*) &destinationInfo, - sizeof(struct sockaddr_in)); - if(sentBytes != 20 + pinfo->size) - { - UDPC_INTERNAL_log(us->ctx, 0, "Failed to send packet to %s port %d", - UDPC_INTERNAL_atostr(us->ctx, addr), cd->port); - free(data); - free(pinfo->data); - if(isResendingPkt != 0) - { - UDPC_Deque_pop_front(cd->priorityPktQueue, sizeof(UDPC_INTERNAL_PacketInfo)); - } - else - { - UDPC_Deque_pop_front(cd->sendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo)); - } - return; - } - - if((pinfo->flags & 0x2) != 0) - { - UDPC_INTERNAL_PacketInfo sentInfo = { - addr, - cd->lseq - 1, - 0x2, - data, - 20 + pinfo->size, - us->tsNow - }; - UDPC_Deque_push_back( - cd->sentPkts, &sentInfo, sizeof(UDPC_INTERNAL_PacketInfo)); - } - else - { - UDPC_INTERNAL_PacketInfo sentInfo = { - addr, - cd->lseq - 1, - 0, - NULL, - 0, - us->tsNow - }; - UDPC_Deque_push_back( - cd->sentPkts, &sentInfo, sizeof(UDPC_INTERNAL_PacketInfo)); - free(data); - } - - while(cd->sentPkts->size / sizeof(UDPC_INTERNAL_PacketInfo) > UDPC_SENT_PKTS_MAX_SIZE) - { - UDPC_INTERNAL_PacketInfo *pinfoCached = UDPC_Deque_get_front_ptr( - cd->sentPkts, sizeof(UDPC_INTERNAL_PacketInfo)); - if(pinfoCached->data && pinfoCached->size != 0) - { - free(pinfoCached->data); - } - UDPC_Deque_pop_front(cd->sentPkts, sizeof(UDPC_INTERNAL_PacketInfo)); - } - - free(pinfo->data); - if(isResendingPkt != 0) - { - UDPC_Deque_pop_front(cd->priorityPktQueue, sizeof(UDPC_INTERNAL_PacketInfo)); - } - else - { - UDPC_Deque_pop_front(cd->sendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo)); - } - } -} - -void UDPC_INTERNAL_update_rtt( - UDPC_Context *ctx, - UDPC_INTERNAL_ConnectionData *cd, - uint32_t rseq, - struct timespec *tsNow) -{ - for(int x = 0; x * sizeof(UDPC_INTERNAL_PacketInfo) < cd->sentPkts->size; ++x) - { - UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_index_ptr(cd->sentPkts, sizeof(UDPC_INTERNAL_PacketInfo), x); - if(pinfo->id == rseq) - { - float diff = UDPC_INTERNAL_ts_diff(tsNow, &pinfo->sent); - if(diff > cd->rtt) - { - cd->rtt += (diff - cd->rtt) / 10.0f; - } - else - { - cd->rtt -= (cd->rtt - diff) / 10.0f; - } - - if(cd->rtt > UDPC_GOOD_RTT_LIMIT_SEC) - { - cd->flags &= 0xFFFFFFFB; - } - else - { - cd->flags |= 0x4; - } - - UDPC_INTERNAL_log(ctx, 2, "%d RTT (%s) %.3fs from %s", - rseq, - cd->rtt > UDPC_GOOD_RTT_LIMIT_SEC ? "B" : "G", - cd->rtt, - UDPC_INTERNAL_atostr(ctx, cd->addr)); - break; - } - } -} - -void UDPC_INTERNAL_check_pkt_timeout( - UDPC_Context *ctx, - UDPC_INTERNAL_ConnectionData *cd, - uint32_t rseq, - uint32_t ack, - struct timespec *tsNow) -{ - --rseq; - for(; ack != 0; ack = ack << 1) - { - if((ack & 0x80000000) != 0) { --rseq; continue; } - - // not received by peer yet, check if packet timed out - for(int x = 0; x * sizeof(UDPC_INTERNAL_PacketInfo) < cd->sentPkts->size; ++x) - { - UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_index_rev_ptr(cd->sentPkts, sizeof(UDPC_INTERNAL_PacketInfo), x); - if(pinfo->id == rseq) - { - if((pinfo->flags & 0x2) == 0 || (pinfo->flags & 0x4) != 0) - { - // is not received checked or already resent - break; - } - float seconds = UDPC_INTERNAL_ts_diff(tsNow, &pinfo->sent); - if(seconds >= UDPC_PACKET_TIMEOUT_SEC) - { - if(pinfo->size <= 20) - { - UDPC_INTERNAL_log(ctx, 0, - "Timed out sentPkt (%d) to %s has size at most 20", - rseq, - UDPC_INTERNAL_atostr(ctx, cd->addr)); - pinfo->flags |= 0x4; // treat as resent to avoid reprinting error - break; - } - // packet timed out, resending - UDPC_INTERNAL_PacketInfo newPkt = { - cd->addr, - 0, - 0, - NULL, - 0, - {0, 0} - }; - newPkt.size = pinfo->size - 20; - newPkt.data = malloc(newPkt.size); - memcpy(newPkt.data, pinfo->data + 20, newPkt.size); - free(pinfo->data); - - pinfo->flags |= 0x4; - pinfo->data = NULL; - pinfo->size = 0; - UDPC_Deque_push_back( - cd->priorityPktQueue, - &newPkt, - sizeof(UDPC_INTERNAL_PacketInfo)); - } - break; - } - } - - --rseq; - } -} - -float UDPC_INTERNAL_ts_diff(struct timespec *ts0, struct timespec *ts1) -{ - float sec = 0.0f; - if(!ts0 || !ts1) - { - return sec; - } - - if(ts0->tv_sec > ts1->tv_sec) - { - sec = ts0->tv_sec - ts1->tv_sec; - if(ts0->tv_nsec > ts1->tv_nsec) - { - sec += ((float)(ts0->tv_nsec - ts1->tv_nsec)) / 1000000000.0f; - } - else if(ts0->tv_nsec < ts1->tv_nsec) - { - sec -= 1.0f; - sec += ((float)(1000000000 + ts0->tv_nsec - ts1->tv_nsec)) / 1000000000.0f; - } - } - else if(ts0->tv_sec < ts1->tv_sec) - { - sec = ts1->tv_sec - ts0->tv_sec; - if(ts0->tv_nsec < ts1->tv_nsec) - { - sec += ((float)(ts1->tv_nsec - ts0->tv_nsec)) / 1000000000.0f; - } - else if(ts0->tv_nsec > ts1->tv_nsec) - { - sec -= 1.0f; - sec += ((float)(1000000000 + ts1->tv_nsec - ts0->tv_nsec)) / 1000000000.0f; - } - } - else - { - if(ts0->tv_nsec > ts1->tv_nsec) - { - sec += ((float)(ts0->tv_nsec - ts1->tv_nsec)) / 1000000000.0f; - } - else - { - sec += ((float)(ts1->tv_nsec - ts0->tv_nsec)) / 1000000000.0f; - } - } - - return sec; -} - -int UDPC_INTERNAL_threadfn(void *context) -{ - UDPC_Context *ctx = (UDPC_Context*)context; - - int shouldStop = 0; - struct timespec ts; - - while(shouldStop == 0) - { - timespec_get(&ts, TIME_UTC); - ts.tv_nsec += 16666666; - while(ts.tv_nsec >= 1000000000) - { - ts.tv_nsec -= 1000000000; - ts.tv_sec += 1; - } - mtx_lock(&ctx->tCVMtx); - cnd_timedwait(&ctx->threadCV, &ctx->tCVMtx, &ts); - UDPC_update(ctx); - mtx_unlock(&ctx->tCVMtx); - - mtx_lock(&ctx->tflagsMtx); - shouldStop = ctx->threadFlags & 0x1; - mtx_unlock(&ctx->tflagsMtx); - } - - return 0; -} - -void UDPC_INTERNAL_prepare_pkt( - void *data, - uint32_t protocolID, - uint32_t conID, - uint32_t rseq, - uint32_t ack, - uint32_t *seqID, - int flags) -{ - char *d = data; - uint32_t temp; - - temp = htonl(protocolID); - memcpy(d, &temp, 4); - - temp = htonl(conID - | ((flags & 0x1) != 0 ? UDPC_ID_PING : 0) - | ((flags & 0x2) != 0 ? UDPC_ID_RESENDING : 0) - | ((flags & 0x4) == 0 ? UDPC_ID_NO_REC_CHK : 0) - | ((flags & 0x8) != 0 ? UDPC_ID_CONNECT : 0)); - memcpy(&d[4], &temp, 4); - - if(seqID) - { - temp = htonl(*seqID); - ++(*seqID); - } - else - { - temp = 0; - } - - memcpy(&d[8], &temp, 4); - temp = htonl(rseq); - memcpy(&d[12], &temp, 4); - temp = htonl(ack); - memcpy(&d[16], &temp, 4); -} - -void UDPC_INTERNAL_log(UDPC_Context *ctx, uint32_t level, const char *msg, ...) -{ - va_list args; - va_start(args, msg); - switch(level) - { - case 0: - default: - if((ctx->flags & 0x4) == 0) break; - fprintf(stderr, "ERR: "); - break; - case 1: - if((ctx->flags & 0x8) == 0) break; - fprintf(stderr, "WARN: "); - break; - case 2: - if((ctx->flags & 0x10) == 0) break; - fprintf(stderr, "INFO: "); - break; - case 3: - if((ctx->flags & 0x20) == 0) break; - fprintf(stderr, "VERBOSE: "); - break; - } - vfprintf(stderr, msg, args); - fprintf(stderr, "\n"); - va_end(args); -} - -char* UDPC_INTERNAL_atostr(UDPC_Context *ctx, uint32_t addr) -{ - int index = 0; - for(int x = 0; x < 4; ++x) - { - unsigned char temp = (addr >> (x * 8)) & 0xFF; - - if(temp >= 100) - { - ctx->atostrBuf[index++] = '0' + temp / 100; - } - if(temp >= 10) - { - ctx->atostrBuf[index++] = '0' + ((temp / 10) % 10); - } - ctx->atostrBuf[index++] = '0' + temp % 10; - - if(x < 3) - { - ctx->atostrBuf[index++] = '.'; - } - } - ctx->atostrBuf[index] = 0; - - return ctx->atostrBuf; -} - -uint32_t UDPC_INTERNAL_generate_id(UDPC_Context *ctx) -{ - uint32_t newID = 0x10000000; - - while(newID == 0x10000000) - { - newID = rand() % 0x10000000; - if(UDPC_HashMap_has(ctx->idMap, newID) != 0) - { - newID = 0x10000000; - } - } - - return newID; -} - -uint32_t UDPC_strtoa(const char *addrStr) -{ - uint32_t addr = 0; - uint32_t temp = 0; - uint32_t index = 0; - while(*addrStr != 0) - { - if(*addrStr >= '0' && *addrStr <= '9') - { - temp *= 10; - temp += *addrStr - '0'; - } - else if(*addrStr == '.' && temp <= 0xFF && index < 3) - { - addr |= (temp << (8 * index++)); - temp = 0; - } - else - { - return 0; - } - ++addrStr; - } - - if(index == 3 && temp <= 0xFF) - { - addr |= temp << 24; - return addr; - } - else - { - return 0; - } -} diff --git a/c_impl/src/UDPConnection.h b/c_impl/src/UDPConnection.h deleted file mode 100644 index 1f7a941..0000000 --- a/c_impl/src/UDPConnection.h +++ /dev/null @@ -1,325 +0,0 @@ -#ifndef UDPCONNECTION_H -#define UDPCONNECTION_H - -/*! - * Any function or struct starting with "UDPC_INTERNAL" should never be used, - * as they are used internally by this library. - */ - -#include -#include -#include -#include - -#include "UDPC_Defines.h" -#include "UDPC_Deque.h" -#include "UDPC_HashMap.h" - -#if UDPC_PLATFORM == UDPC_PLATFORM_WINDOWS - #include - - #define CleanupSocket(x) closesocket(x) -#elif UDPC_PLATFORM == UDPC_PLATFORM_MAC || UDPC_PLATFORM == UDPC_PLATFORM_LINUX - #include - #include - #include - #include - - #define CleanupSocket(x) close(x) -#else - #define CleanupSocket(x) ((void)0) -#endif - -#define UDPC_ATOSTR_BUF_SIZE 16 - -/// (void *userData, uint32_t address) -/*! - * Note address is in network byte order (usually big-endian) - */ -typedef void (*UDPC_callback_connected)(void*, uint32_t); - -/// (void *userData, uint32_t address) -/*! - * Note address is in network byte order (usually big-endian) - */ -typedef void (*UDPC_callback_disconnected)(void*, uint32_t); - -/// (void *userData, uint32_t address, char *packetData, uint32_t packetSize) -/*! - * The data pointed to by the packetData argument is to data internally managed - * by the UDPC_Context. It will change every time this callback is called so do - * not depend on it persisting. This means you should copy the data out of it - * when the callback is invoked and work with the copied data. - */ -typedef void (*UDPC_callback_received)(void*, uint32_t, char*, uint32_t); - -/// This struct should not be used outside of this library -typedef struct { - uint32_t addr; // in network order (big-endian) - uint32_t id; - /* - * 0x1 - is resending - * 0x2 - is check received packet - * 0x4 - has been re-sent - * 0x8 - initiate connection packet - */ - uint32_t flags; - char *data; // no-header in sendPktQueue and receivedPackets, header in sentPkts - uint32_t size; - struct timespec sent; -} UDPC_INTERNAL_PacketInfo; - -/// This struct should not be used outside of this library -typedef struct { - /* - * 0x1 - trigger send - * 0x2 - is good mode - * 0x4 - is good rtt - * 0x8 - initiating connection to server - * 0x10 - is id set - */ - uint32_t flags; - uint32_t id; - uint32_t lseq; - uint32_t rseq; - uint32_t ack; - float timer; - float toggleT; - float toggleTimer; - float toggledTimer; - uint32_t addr; // in network order (big-endian) - uint16_t port; - UDPC_Deque *sentPkts; - UDPC_Deque *sendPktQueue; - UDPC_Deque *priorityPktQueue; - struct timespec received; - struct timespec sent; - float rtt; -} UDPC_INTERNAL_ConnectionData; - -/// This struct should not be used externally, only passed to functions that require it -typedef struct { - int isThreaded; - /* - * 0x1 - unused - * 0x2 - is client - * 0x4 - log errors - * 0x8 - log warnings - * 0x10 - log info - * 0x20 - log verbose - * 0x40 - accept new connections - */ - uint32_t flags; - /* - * 0x1 - thread should stop - */ - uint32_t threadFlags; - uint32_t protocolID; - uint32_t error; - int socketHandle; - struct sockaddr_in socketInfo; - thrd_t threadHandle; - mtx_t tCVMtx; - mtx_t tflagsMtx; - cnd_t threadCV; - UDPC_HashMap *conMap; - // Clients intentionally do not use idMap at all - UDPC_HashMap *idMap; - struct timespec lastUpdated; - char atostrBuf[UDPC_ATOSTR_BUF_SIZE]; - char recvBuf[UDPC_PACKET_MAX_SIZE]; - UDPC_Deque *connectedEvents; - UDPC_Deque *disconnectedEvents; - UDPC_Deque *receivedPackets; - - UDPC_callback_connected callbackConnected; - void *callbackConnectedUserData; - UDPC_callback_disconnected callbackDisconnected; - void *callbackDisconnectedUserData; - UDPC_callback_received callbackReceived; - void *callbackReceivedUserData; -} UDPC_Context; - -/// This struct should not be used outside of this library -typedef struct { - struct timespec tsNow; - float dt; - UDPC_Deque *removedQueue; - UDPC_Context *ctx; -} UDPC_INTERNAL_update_struct; - -/// Creates a new UDPC_Context, for establishing a connection via UDP -/*! - * Callbacks must be set to use UDPC effectively, using the following functions: - * - UDPC_set_callback_connected() - * - UDPC_set_callback_disconnected() - * - UDPC_set_callback_received() - * - * Clients should also use UDPC_client_initiate_connection() to let UDPC know - * what server to connect to. - * - * UDPC_update() must be called periodically (ideally at 30 updates per second - * or faster), to send and receive UDP packets, and establish new connections - * when enabled. An init variant "UDPC_init_threaded_update()" is available - * which will call update periodically on a separate thread. - * - * UDPC_check_events() must also be called to call the set callbacks for - * connected, disconnected, and received events. - * - * When finished using UDPC, UDPC_destroy must be called on the context to free - * resources. - */ -UDPC_Context* UDPC_init(uint16_t listenPort, uint32_t listenAddr, int isClient); - -/// Creates a new UDPC_Context, where a thread is created to update UDPC on its own -/*! - * If using a UDPC_Context created by this init variant, UDPC_update() must not - * be manually called, as it is called automatically by a separate thread. - * - * See the documentation for UDPC_init() for more details. - */ -UDPC_Context* UDPC_init_threaded_update(uint16_t listenPort, uint32_t listenAddr, int isClient); - -/// This fn must be called on a UDPC_Context to free resources -void UDPC_destroy(UDPC_Context *ctx); - -void UDPC_INTERNAL_destroy_conMap(void *unused, uint32_t addr, char *data); - -/// Sets the callback for connected events -void UDPC_set_callback_connected( - UDPC_Context *ctx, UDPC_callback_connected fptr, void *userData); - -/// Sets the callback for disconnected events -void UDPC_set_callback_disconnected( - UDPC_Context *ctx, UDPC_callback_disconnected fptr, void *userData); - -/// Sets the callback for received packet events -void UDPC_set_callback_received( - UDPC_Context *ctx, UDPC_callback_received fptr, void *userData); - -/// Invokes callbacks based on events that have ocurred during UDPC_update() -void UDPC_check_events(UDPC_Context *ctx); - -/// Tells UDPC to initiate a connection to a server -void UDPC_client_initiate_connection(UDPC_Context *ctx, uint32_t addr, uint16_t port); - -/*! - * \brief Queues a packet to send to a connected peer - * Note addr is expected to be in network-byte-order (big-endian). - * If isChecked is non-zero, UDPC will attempt to resend the packet if peer has - * not received it within UDPC_PACKET_TIMEOUT_SEC seconds. - * \return non-zero on success - */ -int UDPC_queue_send( - UDPC_Context *ctx, uint32_t addr, uint32_t isChecked, void *data, uint32_t size); - -/*! - * \brief get the number of packets that can be queued to the addr - * \return number of queueable packets or 0 if connection has not been established - */ -int UDPC_get_queue_send_available(UDPC_Context *ctx, uint32_t addr); - -/// Returns non-zero if UDPC is accepting new connections -int UDPC_get_accept_new_connections(UDPC_Context *ctx); - -/// Set isAccepting to non-zero to let UDPC accept new connections -/*! - * Set isAccepting to zero to prevent UDPC from accepting new connections. - */ -void UDPC_set_accept_new_connections(UDPC_Context *ctx, int isAccepting); - -/// Drops a connection specified by addr -/*! - * \return non-zero if the connection existed and was dropped - */ -int UDPC_drop_connection(UDPC_Context *ctx, uint32_t addr); - -/// Gets the currently set protocol id -uint32_t UDPC_get_protocol_id(UDPC_Context *ctx); - -/// Sets the protocol id -/*! - * Note that UDPC can only connect to other UDPC instances that use the same - * protocol id. - */ -void UDPC_set_protocol_id(UDPC_Context *ctx, uint32_t id); - -/*! - * \brief Get the currently set error code, and clear it internally - * Error codes and their meanings are defined in UDPC_Defines.h . - * Use UDPC_get_error_str() to get a string describing the error. - */ -uint32_t UDPC_get_error(UDPC_Context *ctx); - -/// Returns a string describing the error code for UDPC -const char* UDPC_get_error_str(uint32_t error); - -/*! - * 0 - log nothing - * 1 - log only errors - * 2 - log only errors and warnings - * 3 - log errors, warnings, and info - * 4+ - log everything - * - * By default, erros and warnings are logged. - */ -void UDPC_set_logging_type(UDPC_Context *ctx, uint32_t logType); - -/// If threaded, this function is called automatically -void UDPC_update(UDPC_Context *ctx); - -void UDPC_INTERNAL_update_to_rtt_si(void *userData, uint32_t addr, char *data); - -void UDPC_INTERNAL_update_send(void *userData, uint32_t addr, char *data); - -void UDPC_INTERNAL_update_rtt( - UDPC_Context *ctx, - UDPC_INTERNAL_ConnectionData *cd, - uint32_t rseq, - struct timespec *tsNow); - -void UDPC_INTERNAL_check_pkt_timeout( - UDPC_Context *ctx, - UDPC_INTERNAL_ConnectionData *cd, - uint32_t rseq, - uint32_t ack, - struct timespec *tsNow); - -float UDPC_INTERNAL_ts_diff(struct timespec *ts0, struct timespec *ts1); - -int UDPC_INTERNAL_threadfn(void *context); - -/* - * 0x1 - is ping - * 0x2 - is resending - * 0x4 - is checked received packet - * 0x8 - is init connection packet - */ -void UDPC_INTERNAL_prepare_pkt( - void *data, - uint32_t protocolID, - uint32_t conID, - uint32_t rseq, - uint32_t ack, - uint32_t *seqID, - int flags); - -/*! - * 0 - error - * 1 - warning - * 2 - info - * 3 - verbose - */ -void UDPC_INTERNAL_log(UDPC_Context *ctx, uint32_t level, const char *msg, ...); - -char* UDPC_INTERNAL_atostr(UDPC_Context *ctx, uint32_t addr); - -uint32_t UDPC_INTERNAL_generate_id(UDPC_Context *ctx); - -/*1 - * \brief Converts a IPV4 string to a 32-bit unsigned integer address in big-endian - * \return 0 if string is invalid, address in big-endian format otherwise - */ -uint32_t UDPC_strtoa(const char *addrStr); - -#endif diff --git a/c_impl/src/test/UDPC_NetworkTest.c b/c_impl/src/test/UDPC_NetworkTest.c deleted file mode 100644 index 380e472..0000000 --- a/c_impl/src/test/UDPC_NetworkTest.c +++ /dev/null @@ -1,163 +0,0 @@ -#include -#include -#include -#include - -#include - -typedef struct -{ - int isConnected; - int hasConnectedOnce; - uint32_t addr; -} TestContext; - -void printUsage() -{ - printf("Usage: [-c] [-t] -a -p -l " - " [-d ]\n"); -} - -void conCallback(void *userdata, uint32_t addr) -{ - TestContext *ctx = userdata; - ctx->isConnected = 1; - ctx->hasConnectedOnce = 1; - ctx->addr = addr; - printf("Connected callback called\n"); -} - -void discCallback(void *userdata, uint32_t addr) -{ - TestContext *ctx = userdata; - ctx->isConnected = 0; - printf("Disconnected callback called\n"); -} - -void recCallback(void *userdata, uint32_t addr, char *data, uint32_t size) -{ - TestContext *ctx = userdata; - if(ctx->addr == addr && size == 7 && data[6] == '\0') - { - printf("Got %s\n", data); - } -} - -void updateSendBuffer(uint32_t *index, char *buffer) -{ - ++(*index); - if(*index >= 26 * 26 * 26 * 26 * 26 * 26) - { - *index = 0; - } - - uint32_t temp = 1; - for(int x = 0; x < 6; ++x) - { - buffer[x] = (*index / temp) % 26 + 'a'; - temp *= 26; - } -} - -int main(int argc, char** argv) -{ - int isClient = 0; - int isThreaded = 0; - uint32_t targetAddress = 0; - uint16_t targetPort = 0; - uint32_t listenAddress = 0; - uint16_t listenPort = 0; - TestContext testCtx = {0, 0}; - - uint32_t sendIndex = 0; - char sendBuffer[7] = { - 'a', 'a', 'a', - 'a', 'a', 'a', - '\0' - }; - - --argc; ++argv; - while(argc > 0) - { - if(strcmp("-c", argv[0]) == 0) - { - isClient = 1; - } - else if(strcmp("-t", argv[0]) == 0) - { - isThreaded = 1; - } - else if(strcmp("-a", argv[0]) == 0 && argc > 1) - { - targetAddress = UDPC_strtoa(argv[1]); - --argc; ++argv; - } - else if(strcmp("-p", argv[0]) == 0 && argc > 1) - { - targetPort = strtoul(argv[1], NULL, 10); - --argc; ++argv; - } - else if(strcmp("-l", argv[0]) == 0 && argc > 1) - { - listenPort = strtoul(argv[1], NULL, 10); - --argc; ++argv; - } - else if(strcmp("-d", argv[0]) == 0 && argc > 1) - { - listenAddress = UDPC_strtoa(argv[1]); - --argc; ++argv; - } - else if(strcmp("-h", argv[0]) == 0 || strcmp("--help", argv[0]) == 0) - { - printUsage(); - return 0; - } - --argc; ++argv; - } - - UDPC_Context *ctx; - if(isThreaded == 0) - { - ctx = UDPC_init(listenPort, listenAddress, isClient); - } - else - { - ctx = UDPC_init_threaded_update(listenPort, listenAddress, isClient); - } - - printf("isClient: %s, targetAddr: %s, targetPort: %u, listenPort: %u\n", - isClient == 0 ? "false" : "true", - UDPC_INTERNAL_atostr(ctx, targetAddress), - targetPort, - listenPort); - - if(UDPC_get_error(ctx) == UDPC_SUCCESS) - { - UDPC_set_logging_type(ctx, 4); - UDPC_set_callback_connected(ctx, conCallback, &testCtx); - UDPC_set_callback_disconnected(ctx, discCallback, &testCtx); - UDPC_set_callback_received(ctx, recCallback, &testCtx); - while(UDPC_get_error(ctx) == UDPC_SUCCESS) - { - if(isClient && testCtx.isConnected == 0) - { - UDPC_client_initiate_connection(ctx, targetAddress, targetPort); - } - if(isThreaded == 0) { UDPC_update(ctx); } - UDPC_check_events(ctx); - if(testCtx.isConnected != 0 && UDPC_get_queue_send_available(ctx, testCtx.addr) > 0) - { - UDPC_queue_send(ctx, testCtx.addr, 0, sendBuffer, 7); - updateSendBuffer(&sendIndex, sendBuffer); - } - thrd_sleep(&(struct timespec){0, 16666666}, NULL); - if(testCtx.hasConnectedOnce != 0 && testCtx.isConnected == 0) - { - break; - } - } - } - UDPC_destroy(ctx); - - return 0; -} diff --git a/c_impl/src/test/UDPC_UnitTest.c b/c_impl/src/test/UDPC_UnitTest.c deleted file mode 100644 index 353c9bd..0000000 --- a/c_impl/src/test/UDPC_UnitTest.c +++ /dev/null @@ -1,419 +0,0 @@ -#include "UDPC_UnitTest.h" - -#include -#include -#include -#include - -static UnitTestState UDPC_uts = {0, 0}; - -void TEST_DEQUE() -{ - int arr[32]; - char *temp = NULL; - uint32_t size; - for(int x = 0; x < 32; ++x) - { - arr[x] = x; - } - UDPC_Deque *deque; - - // init - deque = UDPC_Deque_init(sizeof(int) * 32); - ASSERT_TRUE(deque); - ASSERT_TRUE(deque->buf); - ASSERT_EQ(deque->head, 0); - ASSERT_EQ(deque->tail, 0); - ASSERT_EQ(deque->size, 0); - ASSERT_EQ(deque->alloc_size, sizeof(int) * 32); - - // realloc smaller success - ASSERT_TRUE(UDPC_Deque_realloc(deque, sizeof(int) * 16)); - ASSERT_TRUE(deque->buf); - ASSERT_EQ(deque->head, 0); - ASSERT_EQ(deque->tail, 0); - ASSERT_EQ(deque->size, 0); - ASSERT_EQ(deque->alloc_size, sizeof(int) * 16); - - // push back success - ASSERT_TRUE(UDPC_Deque_push_back(deque, arr, sizeof(int) * 4)); - ASSERT_EQ_MEM(arr, deque->buf, sizeof(int) * 4); - ASSERT_EQ_MEM(arr, UDPC_Deque_get_back_ptr(deque, sizeof(int) * 4), sizeof(int) * 4); - ASSERT_EQ_MEM(arr, UDPC_Deque_get_front_ptr(deque, sizeof(int) * 4), sizeof(int) * 4); - for(int x = 0; x < 4; ++x) - { - ASSERT_EQ_MEM(&arr[x], UDPC_Deque_index_ptr(deque, sizeof(int), x), sizeof(int)); - ASSERT_EQ_MEM(&arr[3 - x], UDPC_Deque_index_rev_ptr(deque, sizeof(int), x), sizeof(int)); - } - ASSERT_EQ(deque->size, sizeof(int) * 4); - - // push front success - ASSERT_TRUE(UDPC_Deque_push_front(deque, &arr[4], sizeof(int) * 4)); - ASSERT_EQ_MEM(&arr[4], &deque->buf[sizeof(int) * 12], sizeof(int) * 4); - ASSERT_EQ_MEM(arr, UDPC_Deque_get_back_ptr(deque, sizeof(int) * 4), sizeof(int) * 4); - ASSERT_EQ_MEM(&arr[4], UDPC_Deque_get_front_ptr(deque, sizeof(int) * 4), sizeof(int) * 4); - for(int x = 0; x < 4; ++x) - { - ASSERT_EQ_MEM(&arr[x + 4], UDPC_Deque_index_ptr(deque, sizeof(int), x), sizeof(int)); - ASSERT_EQ_MEM(&arr[x], UDPC_Deque_index_ptr(deque, sizeof(int), x + 4), sizeof(int)); - ASSERT_EQ_MEM(&arr[3 - x], UDPC_Deque_index_rev_ptr(deque, sizeof(int), x), sizeof(int)); - ASSERT_EQ_MEM(&arr[7 - x], UDPC_Deque_index_rev_ptr(deque, sizeof(int), x + 4), sizeof(int)); - } - ASSERT_EQ(deque->size, sizeof(int) * 8); - - // realloc bigger success - ASSERT_TRUE(UDPC_Deque_realloc(deque, sizeof(int) * 32)); - ASSERT_EQ_MEM(&arr[4], deque->buf, sizeof(int) * 4); - ASSERT_EQ_MEM(arr, &deque->buf[sizeof(int) * 4], sizeof(int) * 4); - ASSERT_EQ(deque->alloc_size, sizeof(int) * 32); - - // pop front success - UDPC_Deque_pop_front(deque, sizeof(int) * 4); - ASSERT_EQ(deque->size, sizeof(int) * 4); - - // get front success - size = sizeof(int) * 4; - ASSERT_TRUE(UDPC_Deque_get_front(deque, (void**)&temp, &size)); - ASSERT_EQ(size, sizeof(int) * 4); - ASSERT_EQ_MEM(arr, temp, size); - free(temp); - - // pop back success - UDPC_Deque_pop_back(deque, sizeof(int) * 4); - ASSERT_EQ(deque->size, 0); - - // push front success - ASSERT_TRUE(UDPC_Deque_push_front(deque, arr, sizeof(int) * 16)); - ASSERT_EQ(deque->size, sizeof(int) * 16); - - // get front success - size = sizeof(int) * 16; - ASSERT_TRUE(UDPC_Deque_get_front(deque, (void**)&temp, &size)); - ASSERT_EQ(size, sizeof(int) * 16); - ASSERT_EQ_MEM(arr, temp, size); - free(temp); - - // get back success - size = sizeof(int) * 16; - ASSERT_TRUE(UDPC_Deque_get_back(deque, (void**)&temp, &size)); - ASSERT_EQ(size, sizeof(int) * 16); - ASSERT_EQ_MEM(arr, temp, size); - free(temp); - - // realloc smaller fail - ASSERT_FALSE(UDPC_Deque_realloc(deque, sizeof(int) * 8)); - ASSERT_EQ(deque->size, sizeof(int) * 16); - ASSERT_EQ(deque->alloc_size, sizeof(int) * 32); - - // realloc smaller success - ASSERT_TRUE(UDPC_Deque_realloc(deque, sizeof(int) * 16)); - ASSERT_EQ(deque->size, sizeof(int) * 16); - ASSERT_EQ(deque->alloc_size, sizeof(int) * 16); - ASSERT_EQ_MEM(deque->buf, arr, sizeof(int) * 16); - - // push back fail - ASSERT_FALSE(UDPC_Deque_push_back(deque, arr, sizeof(int) * 16)); - ASSERT_EQ(deque->size, sizeof(int) * 16); - ASSERT_EQ(deque->alloc_size, sizeof(int) * 16); - ASSERT_EQ_MEM(deque->buf, arr, sizeof(int) * 16); - - // push front fail - ASSERT_FALSE(UDPC_Deque_push_back(deque, arr, sizeof(int) * 16)); - ASSERT_EQ(deque->size, sizeof(int) * 16); - ASSERT_EQ(deque->alloc_size, sizeof(int) * 16); - ASSERT_EQ_MEM(deque->buf, arr, sizeof(int) * 16); - - // pop back - UDPC_Deque_pop_back(deque, sizeof(int) * 8); - - // get front success - size = sizeof(int) * 8; - ASSERT_TRUE(UDPC_Deque_get_front(deque, (void**)&temp, &size)); - ASSERT_EQ(size, sizeof(int) * 8); - ASSERT_EQ_MEM(temp, arr, sizeof(int) * 8); - free(temp); - - // get front fail - size = sizeof(int) * 16; - ASSERT_FALSE(UDPC_Deque_get_front(deque, (void**)&temp, &size)); - ASSERT_EQ(size, sizeof(int) * 8); - ASSERT_EQ_MEM(temp, arr, sizeof(int) * 8); - free(temp); - - // get back success - size = sizeof(int) * 8; - ASSERT_TRUE(UDPC_Deque_get_back(deque, (void**)&temp, &size)); - ASSERT_EQ(size, sizeof(int) * 8); - ASSERT_EQ_MEM(temp, arr, sizeof(int) * 8); - free(temp); - - // get back fail - size = sizeof(int) * 16; - ASSERT_FALSE(UDPC_Deque_get_back(deque, (void**)&temp, &size)); - ASSERT_EQ(size, sizeof(int) * 8); - ASSERT_EQ_MEM(temp, arr, sizeof(int) * 8); - free(temp); - - // index success - for(int x = 0; x < 8; ++x) - { - ASSERT_TRUE(UDPC_Deque_index(deque, sizeof(int), x, (void**)&temp)); - if(temp) - { - ASSERT_EQ_MEM(temp, &arr[x], sizeof(int)); - free(temp); - } - } - - // index fail - ASSERT_FALSE(UDPC_Deque_index(deque, sizeof(int), 8, (void**)&temp)); - ASSERT_FALSE(temp); - - // index_rev success - for(int x = 0; x < 8; ++x) - { - ASSERT_TRUE(UDPC_Deque_index_rev(deque, sizeof(int), x, (void**)&temp)); - if(temp) - { - ASSERT_EQ_MEM(temp, &arr[7 - x], sizeof(int)); - free(temp); - } - } - - // index_rev fail - ASSERT_FALSE(UDPC_Deque_index_rev(deque, sizeof(int), 8, (void**)&temp)); - ASSERT_FALSE(temp); - - // remove success front - ASSERT_TRUE(UDPC_Deque_remove(deque, sizeof(int), 0)); - ASSERT_EQ(sizeof(int) * 7, deque->size); - ASSERT_EQ_MEM(deque->buf, &arr[7], sizeof(int)); - - // remove success end - ASSERT_TRUE(UDPC_Deque_remove(deque, sizeof(int), 6)); - ASSERT_EQ(sizeof(int) * 6, deque->size); - ASSERT_EQ_MEM(&deque->buf[deque->tail - sizeof(int)], &arr[5], sizeof(int)); - - // remove success middle - ASSERT_TRUE(UDPC_Deque_remove(deque, sizeof(int), 2)); - ASSERT_EQ(sizeof(int) * 5, deque->size); - ASSERT_EQ_MEM(&deque->buf[deque->head + sizeof(int) * 2], &arr[5], sizeof(int)); - - // remove success until empty - while(deque->size > 0) - { - ASSERT_TRUE(UDPC_Deque_remove(deque, sizeof(int), 0)); - } - ASSERT_EQ(deque->size, 0); - - // test push_back_realloc - ASSERT_EQ(deque->alloc_size, 16 * sizeof(int)); - for(int x = 0; x < 16; ++x) - { - ASSERT_NEQ(UDPC_Deque_push_back(deque, &x, sizeof(int)), 0); - } - int tempInt = 20; - ASSERT_EQ(UDPC_Deque_push_back(deque, &tempInt, sizeof(int)), 0); - ASSERT_NEQ(UDPC_Deque_push_back_realloc(deque, &tempInt, sizeof(int)), 0); - ASSERT_EQ(deque->alloc_size, 32 * sizeof(int)); - ASSERT_EQ_MEM(UDPC_Deque_get_back_ptr(deque, sizeof(int)), &tempInt, sizeof(int)); - - UDPC_Deque_pop_back(deque, sizeof(int)); - ASSERT_NEQ(UDPC_Deque_realloc(deque, 16 * sizeof(int)), 0); - - // test push_front_realloc - ASSERT_EQ(UDPC_Deque_push_front(deque, &tempInt, sizeof(int)), 0); - ASSERT_NEQ(UDPC_Deque_push_front_realloc(deque, &tempInt, sizeof(int)), 0); - ASSERT_EQ(deque->alloc_size, 32 * sizeof(int)); - ASSERT_EQ_MEM(UDPC_Deque_get_front_ptr(deque, sizeof(int)), &tempInt, sizeof(int)); - - /* - for(int x = 0; x < deque->tail / sizeof(int); ++x) - { - temp = &deque->buf[x * sizeof(int)]; - printf("%d: %d ", x, *((int*)temp)); - } - printf("\n"); - printf("asize %d, size %d, head %d, tail %d\n", - deque->alloc_size, deque->size, deque->head, deque->tail); - */ - - UDPC_Deque_destroy(deque); - UNITTEST_REPORT(DEQUE) -} - -void TEST_ATOSTR() -{ - UDPC_Context ctx; - ASSERT_EQ_MEM( - UDPC_INTERNAL_atostr(&ctx, (0xFF << 24) | (0x1 << 16) | (0x1E << 8) | 0xAC), - "172.30.1.255", - 13); - UNITTEST_REPORT(ATOSTR); -} - -void TEST_HASHMAP_itercall_comp(void *userData, uint32_t key, char *data) -{ - *((int*)userData) += 1; - int temp = *((int*)(data)) / 100; - ASSERT_EQ(temp, key); -} - -void TEST_HASHMAP() -{ - UDPC_HashMap *hm = UDPC_HashMap_init(0, sizeof(int)); - int temp; - - temp = 1333; - ASSERT_NEQ(UDPC_HashMap_insert(hm, 0, &temp), NULL); - ASSERT_EQ_MEM(UDPC_HashMap_get(hm, 0), &temp, sizeof(int)); - ASSERT_NEQ(UDPC_HashMap_has(hm, 0), 0); - ASSERT_EQ(UDPC_HashMap_has(hm, 1), 0); - - temp = 9999; - ASSERT_NEQ(UDPC_HashMap_insert(hm, 1, &temp), NULL); - ASSERT_EQ_MEM(UDPC_HashMap_get(hm, 1), &temp, sizeof(int)); - ASSERT_NEQ(UDPC_HashMap_has(hm, 0), 0); - ASSERT_NEQ(UDPC_HashMap_has(hm, 1), 0); - ASSERT_EQ(UDPC_HashMap_has(hm, 2), 0); - - temp = 1235987; - ASSERT_NEQ(UDPC_HashMap_insert(hm, 2, &temp), NULL); - ASSERT_EQ_MEM(UDPC_HashMap_get(hm, 2), &temp, sizeof(int)); - ASSERT_NEQ(UDPC_HashMap_has(hm, 0), 0); - ASSERT_NEQ(UDPC_HashMap_has(hm, 1), 0); - ASSERT_NEQ(UDPC_HashMap_has(hm, 2), 0); - ASSERT_EQ(UDPC_HashMap_has(hm, 3), 0); - - ASSERT_NEQ(UDPC_HashMap_remove(hm, 1), 0); - temp = 1333; - ASSERT_EQ_MEM(UDPC_HashMap_get(hm, 0), &temp, sizeof(int)); - temp = 1235987; - ASSERT_EQ_MEM(UDPC_HashMap_get(hm, 2), &temp, sizeof(int)); - ASSERT_NEQ(UDPC_HashMap_has(hm, 0), 0); - ASSERT_EQ(UDPC_HashMap_has(hm, 1), 0); - ASSERT_NEQ(UDPC_HashMap_has(hm, 2), 0); - - ASSERT_EQ(UDPC_HashMap_realloc(hm, 0), 0); - ASSERT_NEQ(UDPC_HashMap_realloc(hm, 16), 0); - - temp = 1333; - ASSERT_EQ_MEM(UDPC_HashMap_get(hm, 0), &temp, sizeof(int)); - temp = 1235987; - ASSERT_EQ_MEM(UDPC_HashMap_get(hm, 2), &temp, sizeof(int)); - ASSERT_NEQ(UDPC_HashMap_has(hm, 0), 0); - ASSERT_EQ(UDPC_HashMap_has(hm, 1), 0); - ASSERT_NEQ(UDPC_HashMap_has(hm, 2), 0); - - UDPC_HashMap_clear(hm); - ASSERT_EQ(hm->size, 0); - ASSERT_EQ(hm->capacity, 16); - - ASSERT_NEQ(UDPC_HashMap_realloc(hm, 8), 0); - ASSERT_EQ(hm->size, 0); - ASSERT_EQ(hm->capacity, 8); - - for(int x = 0; x < 8; ++x) - { - temp = x * 100; - ASSERT_NEQ(UDPC_HashMap_insert(hm, x, &temp), NULL); - } - for(int x = 0; x < 8; ++x) - { - temp = x * 100; - ASSERT_EQ_MEM(UDPC_HashMap_get(hm, x), &temp, sizeof(int)); - ASSERT_NEQ(UDPC_HashMap_has(hm, x), 0); - } - ASSERT_GTE(hm->capacity, 8); - - temp = 800; - ASSERT_NEQ(UDPC_HashMap_insert(hm, 8, &temp), NULL); - for(int x = 0; x < 9; ++x) - { - temp = x * 100; - ASSERT_EQ_MEM(UDPC_HashMap_get(hm, x), &temp, sizeof(int)); - ASSERT_NEQ(UDPC_HashMap_has(hm, x), 0); - } - ASSERT_GTE(hm->capacity, 16); - - for(int x = 0; x < 9; ++x) - { - ASSERT_NEQ(UDPC_HashMap_remove(hm, x), 0); - ASSERT_EQ(UDPC_HashMap_has(hm, x), 0); - } - ASSERT_EQ(hm->size, 0); - ASSERT_GTE(hm->capacity, 16); - - for(int x = 0; x < 32; ++x) - { - temp = x * 100; - ASSERT_NEQ(UDPC_HashMap_insert(hm, x, &temp), NULL); - } - ASSERT_EQ(hm->size, 32); - - for(int x = 0; x < 32; ++x) - { - temp = x * 100; - ASSERT_EQ_MEM(UDPC_HashMap_get(hm, x), &temp, sizeof(int)); - ASSERT_NEQ(UDPC_HashMap_has(hm, x), 0); - } - - temp = 0; - UDPC_HashMap_itercall(hm, TEST_HASHMAP_itercall_comp, &temp); - ASSERT_EQ(temp, 32); - - // TODO DEBUG - /* - printf("Size = %d\n", hm->size); - printf("Capacity = %d\n", hm->capacity); - for(int x = 0; x < hm->capacity; ++x) - { - for(int y = 0; y * (4 + sizeof(int)) < hm->buckets[x]->size; ++y) - { - printf("Bucket%d[%d] = %d\n", x, y, - *((int*)&hm->buckets[x]->buf[y * (4 + sizeof(int)) + 4])); - } - } - for(int x = 0; x < hm->overflow->size; ++x) - { - printf("Overflow[%d] = %d\n", x, - *((int*)&hm->overflow->buf[x * (4 + sizeof(int)) + 4])); - } - */ - - UDPC_HashMap_destroy(hm); - UNITTEST_REPORT(HASHMAP); -} - -void TEST_STRTOA() -{ - ASSERT_EQ(0x04030201, UDPC_strtoa("1.2.3.4")); - ASSERT_EQ(0x0100007F, UDPC_strtoa("127.0.0.1")); - ASSERT_EQ(0xFF01A8C0, UDPC_strtoa("192.168.1.255")); - ASSERT_EQ(0, UDPC_strtoa("1.2.3.4.5")); - ASSERT_EQ(0, UDPC_strtoa("100.20.30")); - ASSERT_EQ(0, UDPC_strtoa("200.400.30.50")); - UNITTEST_REPORT(STRTOA); -} - -void TEST_ATOSTRTOA() -{ - UDPC_Context ctx; - - ASSERT_EQ(0x01020304, UDPC_strtoa(UDPC_INTERNAL_atostr(&ctx, 0x01020304))); - ASSERT_EQ(0x7F000001, UDPC_strtoa(UDPC_INTERNAL_atostr(&ctx, 0x7F000001))); - ASSERT_EQ(0xC0A801FF, UDPC_strtoa(UDPC_INTERNAL_atostr(&ctx, 0xC0A801FF))); - ASSERT_EQ(0xFFFEFDFC, UDPC_strtoa(UDPC_INTERNAL_atostr(&ctx, 0xFFFEFDFC))); - - UNITTEST_REPORT(ATOSTRTOA); -} - -int main() -{ - TEST_DEQUE(); - TEST_ATOSTR(); - TEST_STRTOA(); - TEST_ATOSTRTOA(); - TEST_HASHMAP(); - return 0; -} diff --git a/c_impl/src/test/UDPC_UnitTest.h b/c_impl/src/test/UDPC_UnitTest.h deleted file mode 100644 index 1940761..0000000 --- a/c_impl/src/test/UDPC_UnitTest.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef UDPC_UNIT_TEST_H -#define UDPC_UNIT_TEST_H - -#include -#include - -/* -#include -*/ - -#define ASSERT_TRUE(x) \ - if(!x) { printf("%d: ASSERT_TRUE(%s) FAILED\n", __LINE__, #x); \ - ++UDPC_uts.failed; } ++UDPC_uts.total; -#define ASSERT_FALSE(x) \ - if(x) { printf("%d: ASSERT_FALSE(%s) FAILED\n", __LINE__, #x); \ - ++UDPC_uts.failed; } ++UDPC_uts.total; -#define ASSERT_EQ(x, y) \ - if(x != y) { printf("%d: ASSERT_EQ(%s, %s) FAILED\n", __LINE__, #x, #y); \ - ++UDPC_uts.failed; } ++UDPC_uts.total; -#define ASSERT_NEQ(x, y) \ - if(x == y) { printf("%d: ASSERT_NEQ(%s, %s) FAILED\n", __LINE__, #x, #y); \ - ++UDPC_uts.failed; } ++UDPC_uts.total; -#define ASSERT_EQ_MEM(x, y, size) \ - if(memcmp(x, y, size) != 0) { printf("%d: ASSERT_EQ_MEM(%s, %s, %s) FAILED\n", \ - __LINE__, #x, #y, #size); ++UDPC_uts.failed; } ++UDPC_uts.total; -#define ASSERT_NEQ_MEM(x, y, size) \ - if(memcmp(x, y, size) == 0) { printf("%d: ASSERT_NEQ_MEM(%s, %s, %s) FAILED\n", \ - __LINE__, #x, #y, #size); ++UDPC_uts.failed; } ++UDPC_uts.total; -#define ASSERT_GT(x, y) \ - if(x <= y) { printf("%d: ASSERT_GT(%s, %s) FAILED\n", __LINE__, #x, #y); \ - ++UDPC_uts.failed; } ++UDPC_uts.total; -#define ASSERT_GTE(x, y) \ - if(x < y) { printf("%d: ASSERT_GTE(%s, %s) FAILED\n", __LINE__, #x, #y); \ - ++UDPC_uts.failed; } ++UDPC_uts.total; -#define ASSERT_LT(x, y) \ - if(x >= y) { printf("%d: ASSERT_LT(%s, %s) FAILED\n", __LINE__, #x, #y); \ - ++UDPC_uts.failed; } ++UDPC_uts.total; -#define ASSERT_LTE(x, y) \ - if(x > y) { printf("%d: ASSERT_LTE(%s, %s) FAILED\n", __LINE__, #x, #y); \ - ++UDPC_uts.failed; } ++UDPC_uts.total; - -#define UNITTEST_REPORT(x) { \ - printf("%s: %d/%d tests failed\n", #x, UDPC_uts.failed, UDPC_uts.total); \ - UDPC_uts.failed = 0; \ - UDPC_uts.total = 0; } - - -typedef struct -{ - int result; -} UnitTest_Test; - -typedef struct -{ - int failed; - int total; -} UnitTestState; - -static UnitTestState UDPC_uts; - -#endif diff --git a/rust_binding/.gitignore b/rust_binding/.gitignore deleted file mode 100644 index 1e7caa9..0000000 --- a/rust_binding/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -Cargo.lock -target/ diff --git a/rust_binding/Cargo.toml b/rust_binding/Cargo.toml deleted file mode 100644 index b2d5560..0000000 --- a/rust_binding/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "udpc_rs" -version = "0.1.0" -authors = ["Stephen Seo "] -edition = "2018" - -[dependencies] - -[build-dependencies] -bindgen = "0.42.2" -cmake = "0.1" diff --git a/rust_binding/build.rs b/rust_binding/build.rs deleted file mode 100644 index 197c169..0000000 --- a/rust_binding/build.rs +++ /dev/null @@ -1,56 +0,0 @@ -use cmake::Config; -use bindgen; - -use std::env; -use std::path::PathBuf; - -fn main() { - let mut config = Config::new("../c_impl"); - if env::var("PROFILE").unwrap().eq("release") { - config.define("CMAKE_BUILD_TYPE", "Release"); - } else { - config.define("CMAKE_BUILD_TYPE", "Debug"); - } - let mut dst = config.build(); - dst.push("lib"); - - println!("cargo:rustc-link-search=native={}", dst.display()); - println!("cargo:rustc-link-lib=static=UDPConnection"); - - let bindings = bindgen::Builder::default() - .header("wrapper.h") - .whitelist_type("UDPC_callback_connected") - .whitelist_type("UDPC_callback_disconnected") - .whitelist_type("UDPC_callback_received") - .whitelist_type("UDPC_Context") - .whitelist_function("UDPC_init") - .whitelist_function("UDPC_init_threaded_update") - .whitelist_function("UDPC_destroy") - .whitelist_function("UDPC_set_callback_connected") - .whitelist_function("UDPC_set_callback_disconnected") - .whitelist_function("UDPC_set_callback_received") - .whitelist_function("UDPC_check_events") - .whitelist_function("UDPC_client_initiate_connection") - .whitelist_function("UDPC_queue_send") - .whitelist_function("UDPC_get_queue_send_available") - .whitelist_function("UDPC_get_accept_new_connections") - .whitelist_function("UDPC_set_accept_new_connections") - .whitelist_function("UDPC_drop_connection") - .whitelist_function("UDPC_get_protocol_id") - .whitelist_function("UDPC_set_protocol_id") - .whitelist_function("UDPC_get_error") - .whitelist_function("UDPC_get_error_str") - .whitelist_function("UDPC_set_logging_type") - .whitelist_function("UDPC_update") - .whitelist_function("UDPC_strtoa") - .opaque_type("UDPC_Context") - .opaque_type("UDPC_Deque") - .opaque_type("UDPC_HashMap") - .generate() - .expect("Unable to generate bindings"); - - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); - bindings - .write_to_file(out_path.join("bindings.rs")) - .expect("Couldn't write bindings!"); -} diff --git a/rust_binding/src/lib.rs b/rust_binding/src/lib.rs deleted file mode 100644 index a38a13a..0000000 --- a/rust_binding/src/lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![allow(non_upper_case_globals)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] - -include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/rust_binding/wrapper.h b/rust_binding/wrapper.h deleted file mode 100644 index ae5a4d9..0000000 --- a/rust_binding/wrapper.h +++ /dev/null @@ -1 +0,0 @@ -#include "../c_impl/src/UDPConnection.h" diff --git a/cpp_impl/src/TSLQueue.hpp b/src/TSLQueue.hpp similarity index 100% rename from cpp_impl/src/TSLQueue.hpp rename to src/TSLQueue.hpp diff --git a/cpp_impl/src/UDPC_Defines.hpp b/src/UDPC_Defines.hpp similarity index 100% rename from cpp_impl/src/UDPC_Defines.hpp rename to src/UDPC_Defines.hpp diff --git a/cpp_impl/src/UDPConnection.cpp b/src/UDPConnection.cpp similarity index 100% rename from cpp_impl/src/UDPConnection.cpp rename to src/UDPConnection.cpp diff --git a/cpp_impl/src/UDPConnection.h b/src/UDPConnection.h similarity index 100% rename from cpp_impl/src/UDPConnection.h rename to src/UDPConnection.h diff --git a/cpp_impl/src/test/TestTSLQueue.cpp b/src/test/TestTSLQueue.cpp similarity index 100% rename from cpp_impl/src/test/TestTSLQueue.cpp rename to src/test/TestTSLQueue.cpp diff --git a/cpp_impl/src/test/TestUDPC.cpp b/src/test/TestUDPC.cpp similarity index 100% rename from cpp_impl/src/test/TestUDPC.cpp rename to src/test/TestUDPC.cpp diff --git a/cpp_impl/src/test/UDPC_NetworkTest.cpp b/src/test/UDPC_NetworkTest.cpp similarity index 100% rename from cpp_impl/src/test/UDPC_NetworkTest.cpp rename to src/test/UDPC_NetworkTest.cpp diff --git a/cpp_impl/src/test/UDPC_UnitTest.cpp b/src/test/UDPC_UnitTest.cpp similarity index 100% rename from cpp_impl/src/test/UDPC_UnitTest.cpp rename to src/test/UDPC_UnitTest.cpp