3 * - Acess kernel emulation on another OS using SDL and UDP
12 #include "../../KernelLand/Kernel/include/logdebug.h"
15 #include <sys/socket.h>
16 #include <netinet/in.h>
18 #include <sys/eventfd.h>
21 #include <SDL/SDL.h> // for worker
23 typedef struct sNetSocket tNetSocket;
37 int Net_Wrap_WatcherThread(void *arg);
39 int gNet_Wrap_EventFD;
40 tNetSocket *gNet_Wrap_FirstSocket;
41 tNetSocket *gNet_Wrap_LastSocket;
42 SDL_Thread *gNet_Wrap_SelectChecker;
45 void Net_Wrap_Init(void)
47 gNet_Wrap_EventFD = eventfd(0, 0);
48 gNet_Wrap_SelectChecker = SDL_CreateThread( Net_Wrap_WatcherThread, NULL );
51 static inline void Net_Wrap_ProdWatcher(void)
54 write(gNet_Wrap_EventFD, &val, sizeof(val));
57 int Net_Wrap_WatcherThread(void *arg)
61 int maxfd = gNet_Wrap_EventFD;
62 fd_set rfds, wfds, efds;
66 // Event FD used to wake this thread when the list changes
67 FD_SET(gNet_Wrap_EventFD, &rfds);
68 // Populate socket FDs
69 for( tNetSocket *s = gNet_Wrap_FirstSocket; s; s = s->Next )
73 if( !s->bSkipRead ) FD_SET(s->FD, &rfds);
74 if( !s->bSkipWrite ) FD_SET(s->FD, &wfds);
75 if( !s->bSkipError ) FD_SET(s->FD, &efds);
78 LOG("select(%i+1, ...)", maxfd);
79 int rv = select(maxfd+1, &rfds, &wfds, &efds, NULL);
84 if( FD_ISSET(gNet_Wrap_EventFD, &rfds) )
87 read(gNet_Wrap_EventFD, &val, 8);
90 for( tNetSocket *s = gNet_Wrap_FirstSocket; s; s = s->Next )
92 if( FD_ISSET(s->FD, &rfds) ) {
93 VFS_MarkAvaliable(s->Node, 1);
96 if( FD_ISSET(s->FD, &wfds) ) {
97 VFS_MarkFull(s->Node, 0);
100 if( FD_ISSET(s->FD, &efds) ) {
101 VFS_MarkError(s->Node, 1);
102 s->bSkipError = 1; // TODO: how will err be acked?
108 void *Net_Wrap_ConnectTcp(void *Node, short SrcPort, short DstPort, int Type, const void *Addr)
110 struct sockaddr_in addr4;
111 struct sockaddr *addr;
119 addr = (struct sockaddr*)&addr4;
120 addr_size = sizeof(addr4);
121 memset(addr, 0, addr_size);
122 LOG("%02x%02x%02x%02x",
123 ((uint8_t*)Addr)[0], ((uint8_t*)Addr)[1],
124 ((uint8_t*)Addr)[2], ((uint8_t*)Addr)[3]);
125 memcpy(&addr4.sin_addr, Addr, 4);
126 //addr4.sin_addr.s_addr = htonl( addr4.sin_addr.s_addr);
127 addr4.sin_port = htons(DstPort);
129 //case 6: af = AF_INET6; break;
134 addr->sa_family = af;
136 int fd = socket(af, SOCK_STREAM, 0);
138 Log_Warning("NetWrap", "TODO: Support setting TCP source port");
140 Debug_HexDump("NetWrap: addr=", addr, addr_size);
141 if( connect(fd, addr, addr_size) ) {
143 Log_Notice("NetWrap", "connect() failed: %s", strerror(errno));
145 inet_ntop(af, addr->sa_data+2, tmp, sizeof(tmp));
146 printf("addr = %p %s\n", tmp, tmp);
150 tNetSocket *ret = malloc( sizeof(tNetSocket) );
163 if( gNet_Wrap_FirstSocket ) {
164 gNet_Wrap_LastSocket->Next = ret;
165 ret->Prev = gNet_Wrap_LastSocket;
168 gNet_Wrap_FirstSocket = ret;
171 gNet_Wrap_LastSocket = ret;
173 Net_Wrap_ProdWatcher();
178 static void Net_Wrap_UpdateFlags(tNetSocket *hdl)
180 struct pollfd fdinfo = {.fd = hdl->FD, .events=POLLIN|POLLOUT, .revents=0};
184 VFS_MarkAvaliable(hdl->Node, !!(fdinfo.revents & POLLIN));
185 VFS_MarkFull(hdl->Node, !(fdinfo.revents & POLLOUT));
187 // If no data can be written, re-enable select
188 if( !(fdinfo.revents & POLLOUT) )
190 // Same for if no data to read
191 if( !(fdinfo.revents & POLLIN) )
194 Net_Wrap_ProdWatcher();
197 size_t Net_Wrap_ReadSocket(void *Handle, size_t Bytes, void *Dest)
199 tNetSocket *hdl = Handle;
201 size_t rv = read(hdl->FD, Dest, Bytes);
202 Net_Wrap_UpdateFlags(hdl);
206 size_t Net_Wrap_WriteSocket(void *Handle, size_t Bytes, const void *Dest)
208 tNetSocket *hdl = Handle;
210 size_t rv = write(hdl->FD, Dest, Bytes);
211 Net_Wrap_UpdateFlags(hdl);
215 void Net_Wrap_CloseSocket(void *Handle)
217 tNetSocket *hdl = Handle;
221 hdl->Prev->Next = hdl->Next;
223 gNet_Wrap_FirstSocket = hdl->Next;
225 hdl->Next->Prev = hdl->Prev;
227 gNet_Wrap_LastSocket = hdl->Prev;
228 Net_Wrap_ProdWatcher();