-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CMake samples #84
base: cmake
Are you sure you want to change the base?
CMake samples #84
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
NXDK_NET=y | ||
|
||
WS2_32_SRCS := \ | ||
$(wildcard $(NXDK_DIR)/lib/winapi/ws2_32/*.c) | ||
|
||
WS2_32_OBJS = $(addsuffix .obj, $(basename $(WS2_32_SRCS))) | ||
|
||
NXDK_CFLAGS += -I$(NXDK_DIR)/lib/winapi/ws2_32 | ||
NXDK_CXXFLAGS += -I$(NXDK_DIR)/lib/winapi/ws2_32 | ||
|
||
$(NXDK_DIR)/lib/ws2_32.lib: $(WS2_32_OBJS) | ||
|
||
main.exe: $(NXDK_DIR)/lib/ws2_32.lib | ||
|
||
CLEANRULES += clean-ws2_32 | ||
|
||
.PHONY: clean-ws2_32 | ||
clean-ws2_32: | ||
$(VE)rm -f $(WS2_32_OBJS) $(NXDK_DIR)/lib/ws2_32.lib |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
#define DHCP | ||
|
||
|
||
#include "lwip/sockets.h" | ||
#include "lwip/sys.h" | ||
#include "lwip/netdb.h" | ||
#include <lwip/debug.h> | ||
#ifdef DHCP | ||
#include <lwip/dhcp.h> | ||
#else | ||
#include <lwip/autoip.h> | ||
#endif | ||
#include <lwip/init.h> | ||
#include <lwip/netif.h> | ||
#include <lwip/sys.h> | ||
#include <lwip/tcpip.h> | ||
#include <lwip/timeouts.h> | ||
#include <netif/etharp.h> | ||
#include <pktdrv.h> | ||
#include <xboxkrnl/xboxkrnl.h> | ||
|
||
#include <hal/debug.h> | ||
|
||
#include "winsock2.h" | ||
|
||
|
||
#define PKT_TMR_INTERVAL 5 /* ms */ | ||
#define DEBUGGING 0 | ||
|
||
struct netif nforce_netif, *g_pnetif; | ||
|
||
err_t nforceif_init(struct netif *netif); | ||
static void packet_timer(void *arg); | ||
|
||
static void tcpip_init_done(void *arg) | ||
{ | ||
sys_sem_t *init_complete = arg; | ||
sys_sem_signal(init_complete); | ||
} | ||
|
||
static void packet_timer(void *arg) | ||
{ | ||
LWIP_UNUSED_ARG(arg); | ||
Pktdrv_ReceivePackets(); | ||
sys_timeout(PKT_TMR_INTERVAL, packet_timer, NULL); | ||
} | ||
|
||
#include <windows.h> | ||
#include <assert.h> | ||
|
||
static int map_error_to_winsock(int error) { | ||
switch(error) { | ||
#define MAP_ERROR(error_name) case error_name: return WSA ## error_name; | ||
#undef MAP_ERROR | ||
default: | ||
debugPrint("unhandled error: %d\n", error); | ||
assert(0); | ||
break; | ||
} | ||
return -1; | ||
} | ||
|
||
|
||
int WSAStartup( | ||
WORD wVersionRequired, | ||
LPWSADATA lpWSAData | ||
) { | ||
assert(wVersionRequired == MAKEDWORD(1,1)); | ||
lpWSAData->wVersion = wVersionRequired; | ||
lpWSAData->wHighVersion = MAKEDWORD(1,1); | ||
|
||
|
||
|
||
|
||
|
||
sys_sem_t init_complete; | ||
const ip4_addr_t *ip; | ||
static ip4_addr_t ipaddr, netmask, gw; | ||
|
||
#if DEBUGGING | ||
asm volatile ("jmp ."); | ||
debug_flags = LWIP_DBG_ON; | ||
#else | ||
debug_flags = 0; | ||
#endif | ||
|
||
/* Initialize the TCP/IP stack. Wait for completion. */ | ||
sys_sem_new(&init_complete, 0); | ||
tcpip_init(tcpip_init_done, &init_complete); | ||
sys_sem_wait(&init_complete); | ||
sys_sem_free(&init_complete); | ||
|
||
g_pnetif = netif_add(&nforce_netif, &ipaddr, &netmask, &gw, | ||
NULL, nforceif_init, ethernet_input); | ||
if (!g_pnetif) { | ||
debugPrint("netif_add failed\n"); | ||
return 1; | ||
} | ||
|
||
netif_set_default(g_pnetif); | ||
netif_set_up(g_pnetif); | ||
|
||
#ifdef DHCP | ||
dhcp_start(g_pnetif); | ||
#else | ||
autoip_start(g_pnetif); | ||
#endif | ||
|
||
packet_timer(NULL); | ||
|
||
|
||
#ifdef DHCP | ||
debugPrint("Waiting for IP (DHCP)...\n"); | ||
while (dhcp_supplied_address(g_pnetif) == 0) | ||
NtYieldExecution(); | ||
#else | ||
debugPrint("Waiting for IP (AUTOIP)...\n"); | ||
while (autoip_supplied_address(g_pnetif) == 0) | ||
NtYieldExecution(); | ||
#endif | ||
debugPrint("IP bound!\n"); | ||
|
||
debugPrint("\n"); | ||
debugPrint("IP address.. %s\n", ip4addr_ntoa(netif_ip4_addr(g_pnetif))); | ||
debugPrint("Mask........ %s\n", ip4addr_ntoa(netif_ip4_netmask(g_pnetif))); | ||
debugPrint("Gateway..... %s\n", ip4addr_ntoa(netif_ip4_gw(g_pnetif))); | ||
debugPrint("\n"); | ||
|
||
|
||
|
||
return 0; | ||
} | ||
|
||
|
||
static int last_winsock_error = 0; | ||
|
||
int WSAGetLastError() { | ||
return last_winsock_error; | ||
} | ||
|
||
void WSASetLastError( | ||
int iError | ||
) { | ||
last_winsock_error = iError; | ||
} | ||
|
||
int WSAAPI WSASendTo( | ||
SOCKET s, | ||
LPWSABUF lpBuffers, | ||
DWORD dwBufferCount, | ||
LPDWORD lpNumberOfBytesSent, | ||
DWORD dwFlags, | ||
const sockaddr *lpTo, | ||
int iTolen, | ||
LPWSAOVERLAPPED lpOverlapped, | ||
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine | ||
) { | ||
assert(lpOverlapped == NULL); | ||
assert(lpCompletionRoutine == NULL); | ||
|
||
int flags = dwFlags; //FIXME: Should we filter certain flags? | ||
|
||
struct iovec *iov = __builtin_alloca(sizeof(struct iovec) * dwBufferCount); | ||
for(int i = 0; i < dwBufferCount; i++) { | ||
iov[i].iov_base = lpBuffers[i].buf; | ||
iov[i].iov_len = lpBuffers[i].len; | ||
} | ||
|
||
struct msghdr msg; | ||
|
||
msg.msg_name = (const sockaddr *)lpTo; | ||
msg.msg_namelen = iTolen; | ||
msg.msg_iov = iov; | ||
msg.msg_iovlen = dwBufferCount; | ||
msg.msg_control = NULL; | ||
msg.msg_controllen = 0; | ||
msg.msg_flags = 0; | ||
ssize_t ret = sendmsg(s, &msg, flags); | ||
if (ret == -1) { | ||
WSASetLastError(map_error_to_winsock(errno)); | ||
return SOCKET_ERROR; | ||
} | ||
|
||
*lpNumberOfBytesSent = ret; | ||
|
||
return 0; | ||
} | ||
|
||
int WSAAPI WSARecvFrom( | ||
SOCKET s, | ||
LPWSABUF lpBuffers, | ||
DWORD dwBufferCount, | ||
LPDWORD lpNumberOfBytesRecvd, | ||
LPDWORD lpFlags, | ||
sockaddr *lpFrom, | ||
LPINT lpFromlen, | ||
LPWSAOVERLAPPED lpOverlapped, | ||
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine | ||
) { | ||
assert(lpOverlapped == NULL); | ||
assert(lpCompletionRoutine == NULL); | ||
assert(dwBufferCount == 1); | ||
|
||
int flags = *lpFlags; //FIXME: Should we filter certain flags? | ||
|
||
struct iovec *iov = __builtin_alloca(sizeof(struct iovec) * dwBufferCount); | ||
for(int i = 0; i < dwBufferCount; i++) { | ||
iov[i].iov_base = lpBuffers[i].buf; | ||
iov[i].iov_len = lpBuffers[i].len; | ||
} | ||
|
||
struct msghdr msg; | ||
|
||
msg.msg_name = (const sockaddr *)lpFrom; | ||
msg.msg_namelen = *lpFromlen; | ||
msg.msg_iov = iov; | ||
msg.msg_iovlen = dwBufferCount; | ||
msg.msg_control = NULL; | ||
msg.msg_controllen = 0; | ||
msg.msg_flags = 0; | ||
ssize_t ret = recvmsg(s, &msg, flags); | ||
if (ret == -1) { | ||
WSASetLastError(map_error_to_winsock(errno)); | ||
return SOCKET_ERROR; | ||
} | ||
|
||
*lpFromlen = msg.msg_namelen; //FIXME: Is this updated? It almost certainly isn't winsock behaviour | ||
*lpFlags = msg.msg_flags; | ||
*lpNumberOfBytesRecvd = ret; | ||
|
||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
|
||
typedef unsigned long u_long; | ||
|
||
// We do not support this | ||
#define gethostbyaddr(...) NULL | ||
#define WSACleanup(...) Pktdrv_Quit() | ||
|
||
#define SOMAXCONN 128 | ||
|
||
#define MSG_PARTIAL 0 | ||
|
||
#include <lwip/sockets.h> | ||
#include <lwip/netdb.h> | ||
|
||
#include <windows.h> | ||
|
||
#define WSAAPI | ||
|
||
#define MAKEDWORD(...) 1 | ||
#define HIBYTE(...) 1 | ||
#define LOBYTE(...) 1 | ||
#define MAKEWORD(...) 1 | ||
|
||
typedef int SOCKET; | ||
#define INVALID_SOCKET ((SOCKET)-1) | ||
#define SOCKET_ERROR -1 | ||
|
||
typedef struct WSAData { | ||
WORD wVersion; | ||
WORD wHighVersion; | ||
//FIXME: There's potentially more here | ||
} WSADATA; | ||
|
||
typedef struct sockaddr sockaddr; | ||
|
||
typedef WSADATA *LPWSADATA; | ||
|
||
typedef void *LPWSAOVERLAPPED_COMPLETION_ROUTINE; //FIXME: !!! | ||
typedef void *LPWSAOVERLAPPED; //FIXME: !!! | ||
|
||
int WSAStartup( | ||
WORD wVersionRequired, | ||
LPWSADATA lpWSAData | ||
); | ||
|
||
typedef struct _WSABUF { | ||
ULONG len; | ||
CHAR *buf; | ||
} WSABUF, *LPWSABUF; | ||
|
||
int WSAGetLastError(); | ||
|
||
void WSASetLastError( | ||
int iError | ||
); | ||
|
||
int WSAAPI WSASendTo( | ||
SOCKET s, | ||
LPWSABUF lpBuffers, | ||
DWORD dwBufferCount, | ||
LPDWORD lpNumberOfBytesSent, | ||
DWORD dwFlags, | ||
const sockaddr *lpTo, | ||
int iTolen, | ||
LPWSAOVERLAPPED lpOverlapped, | ||
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine | ||
); | ||
|
||
int WSAAPI WSARecvFrom( | ||
SOCKET s, | ||
LPWSABUF lpBuffers, | ||
DWORD dwBufferCount, | ||
LPDWORD lpNumberOfBytesRecvd, | ||
LPDWORD lpFlags, | ||
sockaddr *lpFrom, | ||
LPINT lpFromlen, | ||
LPWSAOVERLAPPED lpOverlapped, | ||
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
build/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Dummy file, so the CI doesn't trip | ||
# Ideally this should be building the CMake projects on CI | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO |
||
all: |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
if(NXDK) | ||
# Hack for winsock2.h and mmsystem.h | ||
include_directories(SYSTEM "${NXDK_DIR}/lib/winapi/ws2_32;${NXDK_DIR}/lib/winapi/winmm") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These should be part of default includes; I believe this is an upstream nxdk bug which will have to be integrated in #82 (speaking about winmm; obviously ws2_32 is a separate issue as it's part of this PR) |
||
|
||
# Create lwip import lib | ||
add_subdirectory(${NXDK_DIR}/lib/net/lwip "${CMAKE_BINARY_DIR}/lwip/") | ||
get_target_property(LWIPCORE_INCLUDES lwipcore INCLUDE_DIRECTORIES) | ||
message("${LWIPCORE_INCLUDES}") | ||
set_target_properties(lwipcore | ||
PROPERTIES INCLUDE_DIRECTORIES "${NXDK_DIR}/lib/net/lwip/src/include/;${NXDK_DIR}/lib/net/nforceif/include/") | ||
set_target_properties(lwipcore | ||
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${NXDK_DIR}/lib/net/lwip/src/include/;${NXDK_DIR}/lib/net/nforceif/include/") | ||
get_target_property(LWIPCORE_INCLUDES lwipcore INCLUDE_DIRECTORIES) | ||
message("${LWIPCORE_INCLUDES}") | ||
|
||
# Add pktdrv | ||
add_library(pktdrv ${NXDK_DIR}/lib/net/pktdrv/pktdrv.c) | ||
target_include_directories(pktdrv PUBLIC ${NXDK_DIR}/lib/net/pktdrv/) | ||
|
||
# Combine lwip and Xbox driver into libnet | ||
add_library(net | ||
"${NXDK_DIR}/lib/net/nforceif/src/driver.c" | ||
"${NXDK_DIR}/lib/net/nforceif/src/sys_arch.c" | ||
) | ||
target_link_libraries(net lwipcore pktdrv) | ||
endif() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This should be part of nxdk, not of this sample. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Teufelchen1: This is probably a good task for you (nxdk issue 454: "Network stack should be a static library") |
||
|
||
# Add enet and fix a bug in enet where include folder is not known to itself | ||
add_subdirectory(enet) | ||
set_target_properties(enet | ||
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/enet/include/") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this is broken due to https://github.com/lsalzman/enet/blame/master/CMakeLists.txt#L58 using the wrong variable? However, it should not be setting include directories for all targets anyway |
||
|
||
if(NXDK) | ||
# Make enet depend on Xbox network | ||
set_target_properties(enet | ||
PROPERTIES LINK_LIBRARIES "${NXDK_DIR}/lib/ws2_32.lib;${NXDK_DIR}/lib/winmm.lib;net") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why aren't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Part of lsalzman/enet#147 and lsalzman/enet#184 |
||
endif() | ||
|
||
# Build project | ||
add_executable(server server.c) | ||
target_link_libraries(server enet) | ||
add_executable(client client.c) | ||
target_link_libraries(client enet) | ||
if(NXDK) | ||
add_executable(default main.c) | ||
endif() | ||
|
||
if(NXDK) | ||
create_xiso("${CMAKE_BINARY_DIR}/enet.iso" "${CMAKE_BINARY_DIR}/") | ||
endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ws2_32 should be split from this PR, cleaned, polished, and upstreamed.
Maybe @dracc or @Teufelchen1 (also @thrimbor or @Ryzee119, but those got too many tasks already)