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

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