3 * - Acess kernel emulation on another OS using SDL and UDP
11 #include "../../KernelLand/Kernel/include/logdebug.h"
14 #include <sys/socket.h>
15 #include <netinet/in.h>
17 #include <sys/eventfd.h>
20 #include <SDL/SDL.h> // for worker
22 typedef struct sNetSocket tNetSocket;
36 int Net_Wrap_WatcherThread(void *arg);
38 int gNet_Wrap_EventFD;
39 tNetSocket *gNet_Wrap_FirstSocket;
40 tNetSocket *gNet_Wrap_LastSocket;
41 SDL_Thread *gNet_Wrap_SelectChecker;
44 void Net_Wrap_Init(void)
46 gNet_Wrap_EventFD = eventfd(0, 0);
47 gNet_Wrap_SelectChecker = SDL_CreateThread( Net_Wrap_WatcherThread, NULL );
50 static inline void Net_Wrap_ProdWatcher(void)
53 write(gNet_Wrap_EventFD, &val, sizeof(val));
56 int Net_Wrap_WatcherThread(void *arg)
60 int maxfd = gNet_Wrap_EventFD;
61 fd_set rfds, wfds, efds;
65 // Event FD used to wake this thread when the list changes
66 FD_SET(gNet_Wrap_EventFD, &rfds);
67 // Populate socket FDs
68 for( tNetSocket *s = gNet_Wrap_FirstSocket; s; s = s->Next )
72 if( !s->bSkipRead ) FD_SET(s->FD, &rfds);
73 if( !s->bSkipWrite ) FD_SET(s->FD, &wfds);
74 if( !s->bSkipError ) FD_SET(s->FD, &efds);
77 LOG("select(%i+1, ...)", maxfd);
78 int rv = select(maxfd+1, &rfds, &wfds, &efds, NULL);
83 if( FD_ISSET(gNet_Wrap_EventFD, &rfds) )
86 read(gNet_Wrap_EventFD, &val, 8);
89 for( tNetSocket *s = gNet_Wrap_FirstSocket; s; s = s->Next )
91 if( FD_ISSET(s->FD, &rfds) ) {
92 VFS_MarkAvaliable(s->Node, 1);
95 if( FD_ISSET(s->FD, &wfds) ) {
96 VFS_MarkFull(s->Node, 0);
99 if( FD_ISSET(s->FD, &efds) ) {
100 VFS_MarkError(s->Node, 1);
101 s->bSkipError = 1; // TODO: how will err be acked?
107 void *Net_Wrap_ConnectTcp(void *Node, short SrcPort, short DstPort, int Type, const void *Addr)
109 struct sockaddr_in addr4;
110 struct sockaddr *addr;
118 addr = (struct sockaddr*)&addr4;
119 addr_size = sizeof(addr4);
120 memset(addr, 0, addr_size);
121 LOG("%02x%02x%02x%02x",
122 ((uint8_t*)Addr)[0], ((uint8_t*)Addr)[1],
123 ((uint8_t*)Addr)[2], ((uint8_t*)Addr)[3]);
124 memcpy(&addr4.sin_addr, Addr, 4);
125 //addr4.sin_addr.s_addr = htonl( addr4.sin_addr.s_addr);
126 addr4.sin_port = htons(DstPort);
128 //case 6: af = AF_INET6; break;
133 addr->sa_family = af;
135 int fd = socket(af, SOCK_STREAM, 0);
137 Log_Warning("NetWrap", "TODO: Support setting TCP source port");
139 Debug_HexDump("NetWrap: addr=", addr, addr_size);
140 if( connect(fd, addr, addr_size) ) {
142 Log_Notice("NetWrap", "connect() failed: %s", strerror(errno));
144 inet_ntop(af, addr->sa_data+2, tmp, sizeof(tmp));
145 printf("addr = %p %s\n", tmp, tmp);
149 tNetSocket *ret = malloc( sizeof(tNetSocket) );
162 if( gNet_Wrap_FirstSocket ) {
163 gNet_Wrap_LastSocket->Next = ret;
164 ret->Prev = gNet_Wrap_LastSocket;
167 gNet_Wrap_FirstSocket = ret;
170 gNet_Wrap_LastSocket = ret;
172 Net_Wrap_ProdWatcher();
177 static void Net_Wrap_UpdateFlags(tNetSocket *hdl)
179 struct pollfd fdinfo = {.fd = hdl->FD, .events=POLLIN|POLLOUT, .revents=0};
183 VFS_MarkAvaliable(hdl->Node, !!(fdinfo.revents & POLLIN));
184 VFS_MarkFull(hdl->Node, !(fdinfo.revents & POLLOUT));
186 // If no data can be written, re-enable select
187 if( !(fdinfo.revents & POLLOUT) )
189 // Same for if no data to read
190 if( !(fdinfo.revents & POLLIN) )
193 Net_Wrap_ProdWatcher();
196 size_t Net_Wrap_ReadSocket(void *Handle, size_t Bytes, void *Dest)
198 tNetSocket *hdl = Handle;
200 size_t rv = read(hdl->FD, Dest, Bytes);
201 Net_Wrap_UpdateFlags(hdl);
205 size_t Net_Wrap_WriteSocket(void *Handle, size_t Bytes, const void *Dest)
207 tNetSocket *hdl = Handle;
209 size_t rv = write(hdl->FD, Dest, Bytes);
210 Net_Wrap_UpdateFlags(hdl);
214 void Net_Wrap_CloseSocket(void *Handle)
216 tNetSocket *hdl = Handle;
220 hdl->Prev->Next = hdl->Next;
222 gNet_Wrap_FirstSocket = hdl->Next;
224 hdl->Next->Prev = hdl->Prev;
226 gNet_Wrap_LastSocket = hdl->Prev;
227 Net_Wrap_ProdWatcher();