f9526b3a18e126c139a62370993f70b67ffb97a4
[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 UDP Connection
47         gSocket = socket(AF_INET, SOCK_DGRAM, 0);
48         if (gSocket == INVALID_SOCKET)
49         {
50                 fprintf(stderr, "Could not create socket.\n");
51                 #if __WIN32__
52                 WSACleanup();
53                 #endif
54                 exit(0);
55         }
56         
57         // Set server address
58         memset((void *)&server, '\0', sizeof(struct sockaddr_in));
59         server.sin_family = AF_INET;
60         server.sin_port = htons(SERVER_PORT);
61         server.sin_addr.s_addr = htonl(0x7F00001);
62         
63         // Set client address
64         memset((void *)&client, '\0', sizeof(struct sockaddr_in));
65         client.sin_family = AF_INET;
66         client.sin_port = htons(0);
67         client.sin_addr.s_addr = htonl(0x7F00001);
68         
69         // Bind
70         if( bind(gSocket, (struct sockaddr *)&client, sizeof(struct sockaddr_in)) == -1 )
71         {
72                 fprintf(stderr, "Cannot bind address to socket.\n");
73                 #if __WIN32__
74                 closesocket(gSocket);
75                 WSACleanup();
76                 #else
77                 close(gSocket);
78                 #endif
79                 exit(0);
80         }
81         return 0;
82 }
83
84 int SendRequest(int RequestID, int NumOutput, tOutValue **Output, int NumInput, tInValue **Input)
85 {
86         tRequestHeader  *request;
87         tRequestValue   *value;
88         char    *data;
89          int    requestLen;
90          int    i;
91         
92         // See ../syscalls.h for details of request format
93         requestLen = sizeof(tRequestHeader) + (NumOutput + NumInput) * sizeof(tRequestValue);
94         
95         // Get total param length
96         for( i = 0; i < NumOutput; i ++ )
97                 requestLen += Output[i]->Length;
98         
99         // Allocate request
100         request = malloc( requestLen );
101         value = request->Params;
102         data = (char*)&request->Params[ NumOutput + NumInput ];
103         
104         // Set header
105         request->ClientID = siSyscall_ClientID;
106         request->CallID = RequestID;    // Syscall
107         request->NParams = NumOutput;
108         request->NReturn = NumInput;
109         
110         // Set parameters
111         for( i = 0; i < NumOutput; i ++ )
112         {
113                 switch(Output[i]->Type)
114                 {
115                 case 'i':       value->Type = ARG_TYPE_INT32;   break;
116                 case 'I':       value->Type = ARG_TYPE_INT64;   break;
117                 case 'd':       value->Type = ARG_TYPE_DATA;    break;
118                 default:
119                         return -1;
120                 }
121                 value->Length = Output[i]->Length;
122                 
123                 memcpy(data, Output[i]->Data, Output[i]->Length);
124                 
125                 data += Output[i]->Length;
126         }
127         
128         // Set return values
129         for( i = 0; i < NumInput; i ++ )
130         {
131                 switch(Input[i]->Type)
132                 {
133                 case 'i':       value->Type = ARG_TYPE_INT32;   break;
134                 case 'I':       value->Type = ARG_TYPE_INT64;   break;
135                 case 'd':       value->Type = ARG_TYPE_DATA;    break;
136                 default:
137                         return -1;
138                 }
139                 value->Length = Input[i]->Length;
140         }
141         
142         // Send it off
143         send(gSocket, request, requestLen, 0);
144         
145         // Wait for a response
146         recv(gSocket, request, requestLen, 0);
147         
148         // Parse response out
149         
150         return 0;
151 }

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