AcessNative - Huge changes, cleaning up and getting it to work
[tpg/acess2.git] / AcessNative / ld-acess_src / request.c
1 /*
2  */
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stdio.h>
6 #ifdef __WIN32__
7 # include <windows.h>
8 # include <winsock.h>
9 #else
10 # include <unistd.h>
11 # include <sys/socket.h>
12 # include <netinet/in.h>
13 #endif
14 #include "request.h"
15 #include "../syscalls.h"
16
17 #define USE_TCP 0
18
19 // === PROTOTYPES ===
20 void    SendData(void *Data, int Length);
21  int    ReadData(void *Dest, int MaxLen, int Timeout);
22
23 // === GLOBALS ===
24 #ifdef __WIN32__
25 WSADATA gWinsock;
26 SOCKET  gSocket = INVALID_SOCKET;
27 #else
28 # define INVALID_SOCKET -1
29  int    gSocket = INVALID_SOCKET;
30 #endif
31 // Client ID to pass to server
32 // TODO: Implement such that each thread gets a different one
33  int    giSyscall_ClientID = 0;
34 struct sockaddr_in      gSyscall_ServerAddr;
35
36 // === CODE ===
37 int _InitSyscalls()
38 {
39         
40         #ifdef __WIN32__
41         /* Open windows connection */
42         if (WSAStartup(0x0101, &gWinsock) != 0)
43         {
44                 fprintf(stderr, "Could not open Windows connection.\n");
45                 exit(0);
46         }
47         #endif
48         
49         #if USE_TCP
50         // Open TCP Connection
51         gSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
52         #else
53         // Open UDP Connection
54         gSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
55         #endif
56         if (gSocket == INVALID_SOCKET)
57         {
58                 fprintf(stderr, "Could not create socket.\n");
59                 #if __WIN32__
60                 WSACleanup();
61                 #endif
62                 exit(0);
63         }
64         
65         // Set server address
66         memset((void *)&gSyscall_ServerAddr, '\0', sizeof(struct sockaddr_in));
67         gSyscall_ServerAddr.sin_family = AF_INET;
68         gSyscall_ServerAddr.sin_port = htons(SERVER_PORT);
69         gSyscall_ServerAddr.sin_addr.s_addr = htonl(0x7F000001);
70         
71         #if 0
72         // Set client address
73         memset((void *)&client, '\0', sizeof(struct sockaddr_in));
74         client.sin_family = AF_INET;
75         client.sin_port = htons(0);
76         client.sin_addr.s_addr = htonl(0x7F000001);
77         #endif
78         
79         #if USE_TCP
80         if( connect(gSocket, (struct sockaddr *)&gSyscall_ServerAddr, sizeof(struct sockaddr_in)) < 0 )
81         {
82                 fprintf(stderr, "Cannot connect to server (localhost:%i)\n", SERVER_PORT);
83                 perror("_InitSyscalls");
84                 #if __WIN32__
85                 closesocket(gSocket);
86                 WSACleanup();
87                 #else
88                 close(gSocket);
89                 #endif
90                 exit(0);
91         }
92         giSyscall_ClientID = gSocket;   // A bit of a hack really :(
93         #endif
94         
95         #if 0
96         // Bind
97         if( bind(gSocket, (struct sockaddr *)&client, sizeof(struct sockaddr_in)) == -1 )
98         {
99                 fprintf(stderr, "Cannot bind address to socket.\n");
100                 #if __WIN32__
101                 closesocket(gSocket);
102                 WSACleanup();
103                 #else
104                 close(gSocket);
105                 #endif
106                 exit(0);
107         }
108         #endif
109         
110         #if !USE_TCP
111         // Ask server for a client ID
112         {
113                 tRequestHeader  req;
114                  int    len;
115                 req.ClientID = 0;
116                 req.CallID = 0;
117                 req.NParams = 0;
118                 
119                 SendData(&req, sizeof(req));
120                 
121                 len = ReadData(&req, sizeof(req), 5);
122                 if( len == 0 ) {
123                         fprintf(stderr, "Unable to connect to server (localhost:%i)\n", SERVER_PORT);
124                         exit(-1);
125                 }
126                 
127                 giSyscall_ClientID = req.ClientID;
128         }
129         #endif
130         
131         return 0;
132 }
133
134 int SendRequest(tRequestHeader *Request, int RequestSize, int ResponseSize)
135 {
136         if( gSocket == INVALID_SOCKET )
137         {
138                 _InitSyscalls();                
139         }
140         
141         // Set header
142         Request->ClientID = giSyscall_ClientID;
143         
144         #if 0
145         {
146                 for(i=0;i<RequestSize;i++)
147                 {
148                         printf("%02x ", ((uint8_t*)Request)[i]);
149                         if( i % 16 == 15 )      printf("\n");
150                 }
151                 printf("\n");
152         }
153         #endif
154         {
155                  int    i;
156                 char    *data = (char*)&Request->Params[Request->NParams];
157                 printf("Request #%i (%s) -", Request->CallID, casSYSCALL_NAMES[Request->CallID]);
158                 for( i = 0; i < Request->NParams; i ++ )
159                 {
160                         switch(Request->Params[i].Type)
161                         {
162                         case ARG_TYPE_INT32:
163                                 printf(" 0x%08x", *(uint32_t*)data);
164                                 data += sizeof(uint32_t);
165                                 break;
166                         case ARG_TYPE_INT64:
167                                 printf(" 0x%016llx", *(uint64_t*)data);
168                                 data += sizeof(uint64_t);
169                                 break;
170                         case ARG_TYPE_STRING:
171                                 printf(" '%s'", (char*)data);
172                                 data += Request->Params[i].Length;
173                                 break;
174                         case ARG_TYPE_DATA:
175                                 printf(" %p:0x%x", (char*)data, Request->Params[i].Length);
176                                 if( !(Request->Params[i].Flags & ARG_FLAG_ZEROED) )
177                                         data += Request->Params[i].Length;
178                                 break;
179                         }
180                 }
181                 printf("\n");
182         }
183         
184         // Send it off
185         SendData(Request, RequestSize);
186         
187         // Wait for a response (no timeout)
188         return ReadData(Request, ResponseSize, 0);
189 }
190
191 void SendData(void *Data, int Length)
192 {
193          int    len;
194         
195         #if USE_TCP
196         len = send(Data, Length, 0);
197         #else
198         len = sendto(gSocket, Data, Length, 0,
199                 (struct sockaddr*)&gSyscall_ServerAddr, sizeof(gSyscall_ServerAddr));
200         #endif
201         
202         if( len != Length ) {
203                 perror("SendData");
204                 exit(-1);
205         }
206 }
207
208 int ReadData(void *Dest, int MaxLength, int Timeout)
209 {
210          int    ret;
211         fd_set  fds;
212         struct timeval  tv;
213         struct timeval  *timeoutPtr;
214         
215         FD_ZERO(&fds);
216         FD_SET(gSocket, &fds);
217         
218         if( Timeout ) {
219                 tv.tv_sec = Timeout;
220                 tv.tv_usec = 0;
221                 timeoutPtr = &tv;
222         }
223         else {
224                 timeoutPtr = NULL;
225         }
226         
227         ret = select(gSocket+1, &fds, NULL, NULL, timeoutPtr);
228         if( ret == -1 ) {
229                 perror("ReadData - select");
230                 exit(-1);
231         }
232         
233         if( !ret ) {
234                 printf("Timeout reading from socket\n");
235                 return 0;       // Timeout
236         }
237         
238         #if USE_TCP
239         ret = recv(gSocket, Dest, MaxLength, 0);
240         #else
241         ret = recvfrom(gSocket, Dest, MaxLength, 0, NULL, 0);
242         #endif
243         
244         if( ret < 0 ) {
245                 perror("ReadData");
246                 exit(-1);
247         }
248         
249         printf("%i bytes read from socket\n", ret);
250         
251         return ret;
252 }

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