Kernel/debug - Clean up Debug() method, bind to #define config
[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 #define DEBUG   1
9 #include <vfs.h>
10 #include <vfs_ext.h>
11 #include <nettest.h>
12 #include "tcpserver.h"
13
14 #define MAX_CLIENTS     4
15
16 struct sNetTest_TCPServer
17 {
18          int    ServerFD;
19          int    nClients;
20         struct sClient {
21                  int    FD;
22         } Clients[MAX_CLIENTS];
23 };
24
25 // === CODE ===
26 tNetTest_TCPServer *NetTest_TCPServer_Create(int Port)
27 {
28         tNetTest_TCPServer *ret;
29         ret = calloc(sizeof(*ret), 1);
30         ret->ServerFD = VFS_Open("/Devices/ip/1/tcps", VFS_OPENFLAG_READ);
31         ASSERT(ret->ServerFD >= 0);
32         VFS_IOCtl(ret->ServerFD, 4, &Port);
33         return ret;
34 }
35
36 void NetTest_TCPServer_Close(tNetTest_TCPServer *Srv)
37 {
38         VFS_Close(Srv->ServerFD);
39         for( int i = 0; i < Srv->nClients; i ++ )
40         {
41                 struct sClient  *client = &Srv->Clients[i];
42                 VFS_Close(client->FD);
43         }
44         free(Srv);
45 }
46
47 int NetTest_TCPServer_FillSelect(tNetTest_TCPServer *Srv, fd_set *fds)
48 {
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         LOG("Srv=%p", Srv);
67         if( FD_ISSET(Srv->ServerFD, rfds) )
68         {
69                 // New connection!
70                 ASSERT(Srv->nClients != MAX_CLIENTS);
71                 struct sClient *client = &Srv->Clients[Srv->nClients++];
72                 LOG("Child?");
73                 client->FD = VFS_OpenChild(Srv->ServerFD, "", VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE);
74                 LOG("client->FD = %i", client->FD);
75         }
76         if( FD_ISSET(Srv->ServerFD, efds) )
77         {
78                 LOG("Oops, error on server");
79                 VFS_Close(Srv->ServerFD);
80                 Srv->ServerFD = -1;
81         }
82
83         for( int i = 0; i < Srv->nClients; i ++ )
84         {
85                 struct sClient  *client = &Srv->Clients[i];
86                 if( FD_ISSET(client->FD, rfds) )
87                 {
88                         // RX'd data on client
89                         // TODO: Cache until '.' is seen, and send all data before+incl that character
90                         char    buf[1024];
91                         size_t len = VFS_Read(client->FD, sizeof(buf), buf);
92                         Debug_HexDump("TCP Srv Rx", buf, len);
93                         VFS_Write(client->FD, len, buf);
94                 }
95                 
96                 if( FD_ISSET(client->FD, efds) )
97                 {
98                         // Drop client
99                         VFS_Close(client->FD);
100                         memmove(client, client+1, (Srv->nClients-i-1) * sizeof(*client));
101                         Srv->nClients --;
102                         i --;   // counteract i++
103                 }
104         }
105 }
106

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