Lots of work on the AcessNative kernel
[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 SERVER_PORT     0xACE
18
19 // === GLOBALS ===
20 #ifdef __WIN32__
21 WSADATA gWinsock;
22 SOCKET  gSocket = INVALID_SOCKET;
23 #else
24 # define INVALID_SOCKET -1
25  int    gSocket = INVALID_SOCKET;
26 #endif
27 // Client ID to pass to server
28 // TODO: Implement such that each thread gets a different one
29 static int      siSyscall_ClientID = 0;
30
31 // === CODE ===
32 int _InitSyscalls()
33 {
34         struct sockaddr_in      server;
35         struct sockaddr_in      client;
36         
37         #ifdef __WIN32__
38         /* Open windows connection */
39         if (WSAStartup(0x0101, &gWinsock) != 0)
40         {
41                 fprintf(stderr, "Could not open Windows connection.\n");
42                 exit(0);
43         }
44         #endif
45         
46         // Open TCP Connection
47         gSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
48         // Open UDP Connection
49         //gSocket = socket(AF_INET, SOCK_DGRAM, 0);
50         if (gSocket == INVALID_SOCKET)
51         {
52                 fprintf(stderr, "Could not create socket.\n");
53                 #if __WIN32__
54                 WSACleanup();
55                 #endif
56                 exit(0);
57         }
58         
59         // Set server address
60         memset((void *)&server, '\0', sizeof(struct sockaddr_in));
61         server.sin_family = AF_INET;
62         server.sin_port = htons(SERVER_PORT);
63         server.sin_addr.s_addr = htonl(0x7F00001);
64         
65         // Set client address
66         memset((void *)&client, '\0', sizeof(struct sockaddr_in));
67         client.sin_family = AF_INET;
68         client.sin_port = htons(0);
69         client.sin_addr.s_addr = htonl(0x7F00001);
70         
71         if( connect(gSocket, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0 )
72         {
73                 fprintf(stderr, "Cannot connect to server (localhost:%i)\n", SERVER_PORT);
74                 perror("_InitSyscalls");
75                 #if __WIN32__
76                 closesocket(gSocket);
77                 WSACleanup();
78                 #else
79                 close(gSocket);
80                 #endif
81                 exit(0);
82         }
83         
84         #if 0
85         // Bind
86         if( bind(gSocket, (struct sockaddr *)&client, sizeof(struct sockaddr_in)) == -1 )
87         {
88                 fprintf(stderr, "Cannot bind address to socket.\n");
89                 #if __WIN32__
90                 closesocket(gSocket);
91                 WSACleanup();
92                 #else
93                 close(gSocket);
94                 #endif
95                 exit(0);
96         }
97         #endif
98         
99         return 0;
100 }
101
102 int SendRequest(int RequestID, int NumOutput, tOutValue **Output, int NumInput, tInValue **Input)
103 {
104         tRequestHeader  *request;
105         tRequestValue   *value;
106         char    *data;
107          int    requestLen;
108          int    i;
109         
110         if( gSocket == INVALID_SOCKET )
111         {
112                 _InitSyscalls();                
113         }
114         
115         // See ../syscalls.h for details of request format
116         requestLen = sizeof(tRequestHeader) + (NumOutput + NumInput) * sizeof(tRequestValue);
117         
118         // Get total param length
119         for( i = 0; i < NumOutput; i ++ )
120                 requestLen += Output[i]->Length;
121         
122         // Allocate request
123         request = malloc( requestLen );
124         value = request->Params;
125         data = (char*)&request->Params[ NumOutput + NumInput ];
126         
127         // Set header
128         request->ClientID = siSyscall_ClientID;
129         request->CallID = RequestID;    // Syscall
130         request->NParams = NumOutput;
131         request->NReturn = NumInput;
132         
133         // Set parameters
134         for( i = 0; i < NumOutput; i ++ )
135         {
136                 switch(Output[i]->Type)
137                 {
138                 case 'i':       value->Type = ARG_TYPE_INT32;   break;
139                 case 'I':       value->Type = ARG_TYPE_INT64;   break;
140                 case 'd':       value->Type = ARG_TYPE_DATA;    break;
141                 case 's':       value->Type = ARG_TYPE_DATA;    break;
142                 default:
143                         fprintf(stderr, __FILE__" SendRequest: Unknown output type '%c'\n",
144                                 Output[i]->Type);
145                         return -1;
146                 }
147                 value->Length = Output[i]->Length;
148                 
149                 memcpy(data, Output[i]->Data, Output[i]->Length);
150                 
151                 value ++;
152                 data += Output[i]->Length;
153         }
154         
155         // Set return values
156         for( i = 0; i < NumInput; i ++ )
157         {
158                 switch(Input[i]->Type)
159                 {
160                 case 'i':       value->Type = ARG_TYPE_INT32;   break;
161                 case 'I':       value->Type = ARG_TYPE_INT64;   break;
162                 case 'd':       value->Type = ARG_TYPE_DATA;    break;
163                 default:
164                         fprintf(stderr, " SendRequest: Unknown input type '%c'\n",
165                                 Input[i]->Type);
166                         return -1;
167                 }
168                 value->Length = Input[i]->Length;
169                 value ++;
170         }
171         #if 0
172         printf("value = %p\n", value);
173         {
174                 for(i=0;i<requestLen;i++)
175                 {
176                         printf("%02x ", ((uint8_t*)request)[i]);
177                         if( i % 16 == 15 )      printf("\n");
178                 }
179                 printf("\n");
180         }
181         #endif
182         
183         // Send it off
184         if( send(gSocket, request, requestLen, 0) != requestLen ) {
185                 fprintf(stderr, "SendRequest: send() failed\n");
186                 perror("SendRequest - send");
187                 free( request );
188                 return -1;
189         }
190         
191         // Wait for a response
192         requestLen = recv(gSocket, request, requestLen, 0);
193         if( requestLen < 0 ) {
194                 fprintf(stderr, "SendRequest: revc() failed\n");
195                 perror("SendRequest - recv");
196                 free( request );
197                 return -1;
198         }
199         
200         // Parse response out
201         if( request->NParams != NumInput ) {
202                 fprintf(stderr, "SendRequest: Unexpected number of values retured (%i, exp %i)\n",
203                         request->NParams, NumInput
204                         );
205                 free( request );
206                 return -1;
207         }
208         
209         // Free memory
210         free( request );
211         
212         return 0;
213 }

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