diff --git a/CMakeLists.txt b/CMakeLists.txt index 83789d06..d34269b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,7 +59,12 @@ if(UNDEFINED_BEHAVIOR_SANITIZER) enableSanitizer("undefined") endif() -add_definitions("-Wunused-variable -Werror=sequence-point -Werror=pointer-sign -Werror=return-type -Werror=sizeof-pointer-memaccess -Wincompatible-pointer-types -DHTTP_DO_NOT_USE_CUSTOM_CONFIG -DMQTT_DO_NOT_USE_CUSTOM_CONFIG") +add_definitions("-DHTTP_DO_NOT_USE_CUSTOM_CONFIG -DMQTT_DO_NOT_USE_CUSTOM_CONFIG") +if(NOT WIN32) +add_definitions("-Wunused-variable -Werror=sequence-point -Werror=pointer-sign -Werror=return-type -Werror=sizeof-pointer-memaccess -Wincompatible-pointer-types") +else() +add_definitions("-D__BYTE_ORDER=1234") +endif() add_subdirectory(src) add_subdirectory(examples) @@ -105,6 +110,7 @@ ExternalProject_Add(usrsctp CMAKE_ARGS -DCMAKE_C_FLAGS="-fPIC" -Dsctp_build_programs=off + -Dsctp_werror=off -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/dist -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} ) diff --git a/examples/generic/CMakeLists.txt b/examples/generic/CMakeLists.txt index de023db3..b6e46e8b 100644 --- a/examples/generic/CMakeLists.txt +++ b/examples/generic/CMakeLists.txt @@ -6,5 +6,8 @@ include_directories(${CMAKE_SOURCE_DIR}/src) add_executable(sample ${SRCS}) -target_link_libraries(sample peer pthread) +target_link_libraries(sample peer) +if(NOT WIN32) + target_link_libraries(sample pthread) +endif() diff --git a/examples/generic/main.c b/examples/generic/main.c index 8fc13ffd..40672096 100644 --- a/examples/generic/main.c +++ b/examples/generic/main.c @@ -1,12 +1,18 @@ -#include #include #include #include -#include -#include - +#include "ports.h" #include "peer.h" #include "reader.h" +#ifdef WIN32 +#include +#define pthread_t HANDLE +#define pthread_create(th, attr, func, arg) (*(th) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(func), (arg), 0, NULL)) +#define pthread_join(th, res) WaitForSingleObject((th), INFINITE) +#define pthread_exit(res) ExitThread(0) +#else +#include +#endif int g_interrupted = 0; PeerConnection* g_pc = NULL; @@ -39,27 +45,19 @@ static void signal_handler(int signal) { static void* peer_singaling_task(void* data) { while (!g_interrupted) { peer_signaling_loop(); - usleep(1000); + ports_sleep_ms(1); } - pthread_exit(NULL); } static void* peer_connection_task(void* data) { while (!g_interrupted) { peer_connection_loop(g_pc); - usleep(1000); + ports_sleep_ms(1); } - pthread_exit(NULL); } -static uint64_t get_timestamp() { - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec * 1000 + tv.tv_usec / 1000; -} - void print_usage(const char* prog_name) { printf("Usage: %s -u [-t ]\n", prog_name); } @@ -126,7 +124,7 @@ int main(int argc, char* argv[]) { while (!g_interrupted) { if (g_state == PEER_CONNECTION_COMPLETED) { - curr_time = get_timestamp(); + curr_time = ports_get_epoch_time(); // FPS 25 if (curr_time - video_time > 40) { @@ -147,7 +145,7 @@ int main(int argc, char* argv[]) { audio_time = curr_time; } } - usleep(1000); + ports_sleep_ms(1); } pthread_join(peer_singaling_thread, NULL); diff --git a/examples/generic/reader.c b/examples/generic/reader.c index 85ef8a57..72e2b983 100644 --- a/examples/generic/reader.c +++ b/examples/generic/reader.c @@ -2,7 +2,6 @@ #include #include #include -#include static int g_video_size = 0; static int g_audio_size = 0; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7721f875..97d082d4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,12 +4,21 @@ file(GLOB SRCS "*.c") file(GLOB HEADERS "peer.h" "peer_connection.h" "peer_signaling.h") +if(WIN32) +add_library(peer STATIC + ${SRCS} + ${HTTP_SOURCES} + ${MQTT_SOURCES} + ${MQTT_SERIALIZER_SOURCES} +) +else() add_library(peer ${SRCS} ${HTTP_SOURCES} ${MQTT_SOURCES} ${MQTT_SERIALIZER_SOURCES} ) +endif() include_directories(peer PUBLIC ${HTTP_INCLUDE_PUBLIC_DIRS} diff --git a/src/address.h b/src/address.h index 6f8eb781..3de81a5f 100644 --- a/src/address.h +++ b/src/address.h @@ -4,6 +4,9 @@ #include "config.h" #if CONFIG_USE_LWIP #include +#elif defined(WIN32) +#include +#include #else #include #include diff --git a/src/agent.c b/src/agent.c index 57de5c95..92e4a367 100644 --- a/src/agent.c +++ b/src/agent.c @@ -1,8 +1,9 @@ #include #include #include +#ifndef WIN32 #include -#include +#endif #include "agent.h" #include "base64.h" diff --git a/src/agent.h b/src/agent.h index 382d5a4e..9a00c26b 100644 --- a/src/agent.h +++ b/src/agent.h @@ -4,9 +4,7 @@ #include #include #include -#include -#include "base64.h" #include "ice.h" #include "socket.h" #include "stun.h" diff --git a/src/dtls_srtp.c b/src/dtls_srtp.c index dd546169..22c7828c 100644 --- a/src/dtls_srtp.c +++ b/src/dtls_srtp.c @@ -1,7 +1,6 @@ #include #include #include -#include #include "address.h" #include "config.h" diff --git a/src/mdns.c b/src/mdns.c index 6d7881cb..007542ba 100644 --- a/src/mdns.c +++ b/src/mdns.c @@ -2,8 +2,10 @@ #include #include #include +#ifndef WIN32 #include #include +#endif #include "address.h" #include "socket.h" #include "utils.h" @@ -53,6 +55,7 @@ static int mdns_add_hostname(const char* hostname, uint8_t* buf, int size) { buf[offset++] = 0x00; return offset; } + static int mdns_parse_answer(uint8_t* buf, int size, Address* addr, const char* hostname) { int flags_qr, offset; DnsHeader* header; diff --git a/src/peer.c b/src/peer.c index f24bf9df..f14bc25d 100644 --- a/src/peer.c +++ b/src/peer.c @@ -1,7 +1,6 @@ #include #include #include -#include #include "peer.h" #include "sctp.h" diff --git a/src/peer_connection.c b/src/peer_connection.c index c763e806..d56810c2 100644 --- a/src/peer_connection.c +++ b/src/peer_connection.c @@ -1,7 +1,6 @@ #include #include #include -#include #include "agent.h" #include "config.h" diff --git a/src/peer_signaling.c b/src/peer_signaling.c index f5dbd838..9d277189 100644 --- a/src/peer_signaling.c +++ b/src/peer_signaling.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include diff --git a/src/ports.c b/src/ports.c index 2346f609..a3f300db 100644 --- a/src/ports.c +++ b/src/ports.c @@ -1,9 +1,11 @@ #include #include + +#ifndef WIN32 #include #include #include - +#endif #include "config.h" #if CONFIG_USE_LWIP @@ -11,6 +13,12 @@ #include "lwip/netdb.h" #include "lwip/netif.h" #include "lwip/sys.h" +#elif WIN32 +#include +// Windows implementation using GetAdaptersAddresses +#include +#pragma comment(lib, "iphlpapi.lib") +#pragma comment(lib, "ws2_32.lib") #else #include #include @@ -51,6 +59,73 @@ int ports_get_host_addr(Address* addr, const char* iface_prefix) { break; } } +#elif WIN32 + ULONG out_buf_len = 15000; + IP_ADAPTER_ADDRESSES* addresses = (IP_ADAPTER_ADDRESSES *)malloc(out_buf_len); + if (addresses == NULL) { + LOGE("Memory allocation failed for IP_ADAPTER_ADDRESSES struct"); + return -1; + } + + DWORD dwRetVal = GetAdaptersAddresses(addr->family, + GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER, + NULL, addresses, &out_buf_len); + + if (dwRetVal == ERROR_BUFFER_OVERFLOW) { + free(addresses); + addresses = (IP_ADAPTER_ADDRESSES *)malloc(out_buf_len); + if (addresses == NULL) { + LOGE("Memory allocation failed for IP_ADAPTER_ADDRESSES struct"); + return -1; + } + dwRetVal = GetAdaptersAddresses(addr->family, + GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER, + NULL, addresses, &out_buf_len); + } + + if (dwRetVal != NO_ERROR) { + LOGE("GetAdaptersAddresses() failed: %ld", dwRetVal); + free(addresses); + return ret; + } + + for (IP_ADAPTER_ADDRESSES* addr_ptr = addresses; addr_ptr != NULL; addr_ptr = addr_ptr->Next) { + if (iface_prefix && strlen(iface_prefix) > 0) { + if (strncmp(addr_ptr->AdapterName, iface_prefix, strlen(iface_prefix)) != 0) { + continue; + } + } else { + if (addr_ptr->OperStatus != IfOperStatusUp) { + continue; + } + if (addr_ptr->IfType == IF_TYPE_SOFTWARE_LOOPBACK) { + continue; + } + } + + IP_ADAPTER_UNICAST_ADDRESS *unicast = addr_ptr->FirstUnicastAddress; + for (; unicast != NULL; unicast = unicast->Next) { + if (unicast->Address.lpSockaddr->sa_family != addr->family) + continue; + + switch (addr->family) { + case AF_INET6: + memcpy(&addr->sin6, unicast->Address.lpSockaddr, sizeof(struct sockaddr_in6)); + break; + case AF_INET: + default: + memcpy(&addr->sin, unicast->Address.lpSockaddr, sizeof(struct sockaddr_in)); + break; + } + ret = 1; + break; + } + if (ret) + break; + } + + free(addresses); + #else struct ifaddrs *ifaddr, *ifa; @@ -144,13 +219,28 @@ int ports_resolve_addr(const char* host, Address* addr) { uint32_t ports_get_epoch_time() { struct timeval tv; +#if WIN32 + FILETIME ft; + ULARGE_INTEGER uli; + GetSystemTimeAsFileTime(&ft); + uli.LowPart = ft.dwLowDateTime; + uli.HighPart = ft.dwHighDateTime; + // FILETIME is in 100-nanosecond intervals since Jan 1, 1601 (UTC) + // Convert to milliseconds since Unix epoch (Jan 1, 1970) + uint64_t epoch = (uli.QuadPart - 116444736000000000ULL) / 10000ULL; + tv.tv_sec = (long)(epoch / 1000); + tv.tv_usec = (long)((epoch % 1000) * 1000); +#else gettimeofday(&tv, NULL); +#endif return (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; } void ports_sleep_ms(int ms) { #if CONFIG_USE_LWIP sys_msleep(ms); +#elif WIN32 + Sleep(ms); #else usleep(ms * 1000); #endif diff --git a/src/rtp.h b/src/rtp.h index 4f946145..e5fbd7d3 100644 --- a/src/rtp.h +++ b/src/rtp.h @@ -53,13 +53,13 @@ typedef struct RtpHeader { uint16_t seq_number; uint32_t timestamp; uint32_t ssrc; - uint32_t csrc[0]; + //uint32_t csrc[0]; } RtpHeader; typedef struct RtpPacket { RtpHeader header; - uint8_t payload[0]; + uint8_t payload[1]; } RtpPacket; diff --git a/src/sctp.c b/src/sctp.c index 644f8d8e..663dd69f 100644 --- a/src/sctp.c +++ b/src/sctp.c @@ -184,7 +184,7 @@ void sctp_parse_data_channel_open(Sctp* sctp, uint16_t sid, char* data, size_t l char* label = (char*)(data + 12); // copy and null-terminate - char label_str[label_length + 1]; + char* label_str = malloc(label_length + 1); memcpy(label_str, label, label_length); label_str[label_length] = '\0'; @@ -195,6 +195,7 @@ void sctp_parse_data_channel_open(Sctp* sctp, uint16_t sid, char* data, size_t l sctp_add_stream_mapping(sctp, label_str, sid); char ack = DATA_CHANNEL_ACK; sctp_outgoing_data(sctp, &ack, 1, DATA_CHANNEL_PPID_CONTROL, sid); + free(label_str); } } diff --git a/src/socket.c b/src/socket.c index 6f7d8ef2..60aaeee3 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1,7 +1,5 @@ #include #include -#include - #include "socket.h" #include "utils.h" diff --git a/src/ssl_transport.c b/src/ssl_transport.c index 9847616f..7c4a6863 100644 --- a/src/ssl_transport.c +++ b/src/ssl_transport.c @@ -7,8 +7,9 @@ #include "mbedtls/debug.h" #include "mbedtls/entropy.h" #include "mbedtls/ssl.h" - +#ifndef WIN32 #include +#endif #include "config.h" #include "ports.h" #include "ssl_transport.h" diff --git a/src/stun.c b/src/stun.c index d3872410..616c0c4d 100644 --- a/src/stun.c +++ b/src/stun.c @@ -2,7 +2,6 @@ #include #include #include -#include #include "stun.h" #include "utils.h" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6c0c6dfd..07902192 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -8,8 +8,10 @@ foreach(sourcefile ${SRCS}) string(REPLACE ".c" "" appname ${sourcefile}) string(REPLACE "${PROJECT_SOURCE_DIR}/" "" appname ${appname}) add_executable(${appname} ${sourcefile}) - target_link_libraries(${appname} peer pthread) + target_link_libraries(${appname} peer) endforeach(sourcefile ${TEST_SRCS}) target_link_libraries(test_peer_connection cjson) - +if(NOT WIN32) + target_link_libraries(test_peer_connection pthread) +endif() diff --git a/tests/test_dtls.c b/tests/test_dtls.c index 635c0e80..eb933364 100644 --- a/tests/test_dtls.c +++ b/tests/test_dtls.c @@ -1,8 +1,6 @@ #include #include #include -#include - #include "dtls_srtp.h" void test_handshake(int argc, char* argv[]) { diff --git a/tests/test_peer_connection.c b/tests/test_peer_connection.c index 55526259..5d16981c 100644 --- a/tests/test_peer_connection.c +++ b/tests/test_peer_connection.c @@ -1,9 +1,17 @@ -#include #include #include -#include - #include "peer.h" +#include "ports.h" +#ifdef WIN32 +#include +#define pthread_t HANDLE +#define pthread_create(th, attr, func, arg) (*(th) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(func), (arg), 0, NULL)) +#define pthread_join(th, res) WaitForSingleObject((th), INFINITE) +#define pthread_exit(res) ExitThread(0) +#else +#include +#include +#endif #define MAX_CONNECTION_ATTEMPTS 25 #define OFFER_DATACHANNEL_MESSAGE "Hello World" @@ -52,7 +60,7 @@ static void* peer_connection_task(void* user_data) { while (!test_complete) { peer_connection_loop(peer_connection); - usleep(1000); + ports_sleep_ms(1); } pthread_exit(NULL); @@ -118,7 +126,7 @@ int main(int argc, char* argv[]) { peer_connection_datachannel_send(test_user_data.answer_peer_connection, ANSWER_DATACHANNEL_MESSAGE, sizeof(ANSWER_DATACHANNEL_MESSAGE)); attempts++; - usleep(250000); + ports_sleep_ms(250); } if (strcmp(DATACHANNEL_NAME, peer_connection_lookup_sid_label(test_user_data.answer_peer_connection, 0)) != 0) {