diff --git a/src/app/platform_win32/win32_foldhaus.cpp b/src/app/platform_win32/win32_foldhaus.cpp index 653dbe6..7f9b24a 100644 --- a/src/app/platform_win32/win32_foldhaus.cpp +++ b/src/app/platform_win32/win32_foldhaus.cpp @@ -423,6 +423,26 @@ Win32_SendAddressedDataBuffers_Job(gs_thread_context Context, gs_data Arg) Win32_SendAddressedDataBuffers(Context, *OutputData); } +#pragma pack(push, 1) +struct test_microphone_packet +{ + b8 ChangeAnimation; + char AnimationFileName[32]; + b8 SetLayer; + char LayerName[32]; + r32 LayerOpacity; + b8 SetLayerParamColor; + char LayerParamColor[7]; + r32 OverrideDuration; +}; +#pragma pack(pop) + +inline u32 +UpackB4(const u8* ptr) +{ + return (u32)(ptr[3] | (ptr[2] << 8) | (ptr[1] << 16) | (ptr[0] << 24)); +} + int WINAPI WinMain ( HINSTANCE HInstance, @@ -562,6 +582,20 @@ WinMain ( WSAStartup(MAKEWORD(2, 2), &WSAData); Win32Sockets = Win32SocketArray_Create(16, &PlatformPermanent); + + win32_socket TestSocket = Win32Socket_ConnectToAddress("127.0.0.1", "20185"); + test_microphone_packet* Recv = 0; + while (true) + { + gs_data Data = Win32Socket_Receive(&TestSocket, ThreadContext.Transient); + if (Data.Size > 0) + { + OutputDebugStringA("Received\n"); + Recv = (test_microphone_packet*)Data.Memory; + } + ClearArena(ThreadContext.Transient); + } + Win32SerialArray_Create(ThreadContext); s32 RenderMemorySize = MB(12); diff --git a/src/app/platform_win32/win32_foldhaus_socket.h b/src/app/platform_win32/win32_foldhaus_socket.h index 18df318..a95b806 100644 --- a/src/app/platform_win32/win32_foldhaus_socket.h +++ b/src/app/platform_win32/win32_foldhaus_socket.h @@ -54,6 +54,82 @@ Win32SocketArray_Get(win32_socket_array Array, s32 Index) global win32_socket_array Win32Sockets; +internal win32_socket +Win32Socket_Create(s32 AddressFamily, s32 Type, s32 Protocol) +{ + win32_socket Result = {0}; + Result.Socket = socket(AddressFamily, Type, Protocol); + if (Result.Socket == INVALID_SOCKET) + { + s32 Error = WSAGetLastError(); + InvalidCodePath; + } + return Result; +} + +internal void +Win32Socket_Bind(win32_socket* Socket, s32 AddressFamily, char* Address, s32 Port) +{ + sockaddr_in Service = {0}; + Service.sin_family = AddressFamily; + Service.sin_addr.s_addr = inet_addr(Address); + Service.sin_port = htons(Port); + + s32 Result = bind(Socket->Socket, (SOCKADDR*)&Service, sizeof(Service)); + if (Result == SOCKET_ERROR) + { + s32 Error = WSAGetLastError(); + InvalidCodePath; + } +} + +internal win32_socket +Win32Socket_ConnectToAddress(char* Address, char* DefaultPort) +{ + win32_socket Result = {}; + + addrinfo Hints = {0}; + Hints.ai_family = AF_UNSPEC; + Hints.ai_socktype = SOCK_STREAM; + Hints.ai_protocol = IPPROTO_TCP; + + addrinfo* PotentialConnections; + s32 Error = getaddrinfo(Address, DefaultPort, &Hints, &PotentialConnections); + if (Error == 0) + { + for (addrinfo* InfoAt = PotentialConnections; InfoAt != NULL; InfoAt = InfoAt->ai_next) + { + win32_socket Socket = Win32Socket_Create(InfoAt->ai_family, InfoAt->ai_socktype, InfoAt->ai_protocol); + if (Socket.Socket == INVALID_SOCKET) + { + Error = WSAGetLastError(); + InvalidCodePath; + } + + Error = connect(Socket.Socket, InfoAt->ai_addr, (int)InfoAt->ai_addrlen); + if (Error == SOCKET_ERROR) + { + closesocket(Socket.Socket); + continue; + } + else + { + Result = Socket; + break; + } + } + } + else + { + Error = WSAGetLastError(); + InvalidCodePath; + } + + freeaddrinfo(PotentialConnections); + + return Result; +} + internal s32 Win32Socket_SetOption(win32_socket* Socket, s32 Level, s32 Option, const char* OptionValue, s32 OptionLength) { @@ -74,32 +150,6 @@ Win32Socket_SetOption(platform_socket_handle SocketHandle, s32 Level, s32 Option return Win32Socket_SetOption(Socket, Level, Option, OptionValue, OptionLength); } -PLATFORM_GET_SOCKET_HANDLE(Win32GetSocketHandle) -{ - // NOTE(Peter): These used to be passed in as paramters, but we only use this function - // with AF_INET, SOCK_DGRAM, and Protocol = 0. These are also platform specific values - // so I was having to include windows.h in the platform agnostic code to accomodate that - // function signature. - s32 AddressFamily = AF_INET; - s32 Type = SOCK_DGRAM; - s32 Protocol = 0; - - s32 Result = Win32SocketArray_Take(&Win32Sockets); - win32_socket* Socket = Win32SocketArray_Get(Win32Sockets, Result); - Socket->Socket = socket(AddressFamily, Type, Protocol); - if (Socket->Socket != INVALID_SOCKET) - { - int Error = Win32Socket_SetOption(Socket, IPPROTO_IP, IP_MULTICAST_TTL, - (const char*)(&Multicast_TimeToLive), sizeof(Multicast_TimeToLive)); - } - else - { - s32 Error = WSAGetLastError(); - InvalidCodePath; - } - - return (platform_socket_handle)Result; -} internal s32 Win32Socket_SendTo(platform_socket_handle SocketHandle, u32 Address, u32 Port, const char* Buffer, s32 BufferLength, s32 Flags) @@ -129,6 +179,61 @@ Win32Socket_SendTo(platform_socket_handle SocketHandle, u32 Address, u32 Port, c return LengthSent; } +internal void +Win32Socket_SetListening(win32_socket* Socket) +{ + if (listen(Socket->Socket, SOMAXCONN) == SOCKET_ERROR) + { + // TODO(pjs): Error logging + s32 Error = WSAGetLastError(); + InvalidCodePath; + } +} + +internal s32 +Win32Socket_PeekGetTotalSize(win32_socket* Socket) +{ + s32 Flags = MSG_PEEK; + char Temp[4]; + s32 BytesQueued = recv(Socket->Socket, Temp, 4, Flags); + if (BytesQueued == SOCKET_ERROR) + { + // TODO(pjs): Error logging + s32 Error = WSAGetLastError(); + BytesQueued = 0; + } + return BytesQueued; +} + +internal gs_data +Win32Socket_Receive(win32_socket* Socket, gs_memory_arena* Storage) +{ +#if 0 + gs_data Result = {}; + s32 BytesQueued = Win32Socket_PeekGetTotalSize(Socket); + if (BytesQueued > 0) + { + Result = PushSizeToData(Storage, BytesQueued); + s32 Flags = 0; + s32 BytesReceived = recv(Socket->Socket, (char*)Result.Memory, Result.Size, Flags); + Assert(BytesReceived == BytesQueued); + } + return Result; +#else + gs_data Result = PushSizeToData(Storage, 1024); + s32 Flags = 0; + s32 BytesReceived = recv(Socket->Socket, (char*)Result.Memory, Result.Size, Flags); + if (BytesReceived == SOCKET_ERROR) + { + // TODO(pjs): Error logging + s32 Error = WSAGetLastError(); + InvalidCodePath; + } + Result.Size = BytesReceived; + return Result; +#endif +} + internal void Win32Socket_Close(win32_socket* Socket) { @@ -136,5 +241,16 @@ Win32Socket_Close(win32_socket* Socket) Socket->Socket = INVALID_SOCKET; } +PLATFORM_GET_SOCKET_HANDLE(Win32GetSocketHandle) +{ + s32 Result = Win32SocketArray_Take(&Win32Sockets); + s32 Error = 0; + win32_socket* Socket = Win32SocketArray_Get(Win32Sockets, Result); + *Socket = Win32Socket_Create(AF_INET, SOCK_DGRAM, 0); + Error = Win32Socket_SetOption(Socket, IPPROTO_IP, IP_MULTICAST_TTL, + (const char*)(&Multicast_TimeToLive), sizeof(Multicast_TimeToLive)); + return (platform_socket_handle)Result; +} + #define WIN32_FOLDHAUS_SOCKET_H #endif // WIN32_FOLDHAUS_SOCKET_H \ No newline at end of file