Tools/NetTest - TCP stack testing, going well
[tpg/acess2.git] / Tools / NetTest / tcpserver.c
1 /*
2  * Acess2 Networking Test Suite (NetTest)
3  * - By John Hodge (thePowersGang)
4  *
5  * tcpserver.c
6  * - TCP Client tester
7  */
8 #include <vfs.h>
9 #include <vfs_ext.h>
10 #include <nettest.h>
11 #include "tcpserver.h"
12
13 #define MAX_CLIENTS     4
14
15 struct sNetTest_TCPServer
16 {
17          int    ServerFD;
18          int    nClients;
19         struct sClient {
20                  int    FD;
21         } Clients[MAX_CLIENTS];
22 };
23
24 // === CODE ===
25 tNetTest_TCPServer *NetTest_TCPServer_Create(int Port)
26 {
27         tNetTest_TCPServer *ret;
28         ret = calloc(sizeof(*ret), 1);
29         ret->ServerFD = VFS_Open("/Devices/ip/1/tcps", VFS_OPENFLAG_READ);
30         ASSERT(ret->ServerFD >= 0);
31         VFS_IOCtl(ret->ServerFD, 4, &Port);
32         return ret;
33 }
34
35 void NetTest_TCPServer_Close(tNetTest_TCPServer *Srv)
36 {
37         VFS_Close(Srv->ServerFD);
38         for( int i = 0; i < Srv->nClients; i ++ )
39         {
40                 struct sClient  *client = &Srv->Clients[i];
41                 VFS_Close(client->FD);
42         }
43         free(Srv);
44 }
45
46 int NetTest_TCPServer_FillSelect(tNetTest_TCPServer *Srv, fd_set *fds)
47 {
48         ASSERT(Srv->ServerFD >= 0);
49          int    max = -1;
50         
51         if( Srv->nClients == MAX_CLIENTS ) {
52                 max = Srv->ServerFD;
53                 FD_SET(Srv->ServerFD, fds);
54         }
55         for( int i = 0; i < Srv->nClients; i ++ )
56         {
57                  int    fd = Srv->Clients[i].FD;
58                 if( fd > max )  max = fd;
59                 FD_SET(fd, fds);
60         }
61         return max;
62 }
63
64 void NetTest_TCPServer_HandleSelect(tNetTest_TCPServer *Srv, const fd_set *rfds, const fd_set *wfds, const fd_set *efds)
65 {
66         if( FD_ISSET(Srv->ServerFD, rfds) )
67         {
68                 // New connection!
69                 ASSERT(Srv->nClients != MAX_CLIENTS);
70                 struct sClient *client = &Srv->Clients[Srv->nClients++];
71                 client->FD = VFS_OpenChild(Srv->ServerFD, "", VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE);
72         }
73
74         for( int i = 0; i < Srv->nClients; i ++ )
75         {
76                 struct sClient  *client = &Srv->Clients[i];
77                 if( FD_ISSET(client->FD, rfds) )
78                 {
79                         // RX'd data on client
80                 }
81                 
82                 if( FD_ISSET(client->FD, efds) )
83                 {
84                         // Drop client
85                         VFS_Close(client->FD);
86                         memmove(client, client+1, (Srv->nClients-i-1) * sizeof(*client));
87                         Srv->nClients --;
88                         i --;   // counteract i++
89                 }
90         }
91 }
92

UCC git Repository :: git.ucc.asn.au