1 /* Copyright (C) 2007-2008 The Android Open Source Project
2 **
3 ** This software is licensed under the terms of the GNU General Public
4 ** License version 2, as published by the Free Software Foundation, and
5 ** may be copied, distributed, and modified under those terms.
6 **
7 ** This program is distributed in the hope that it will be useful,
8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 ** GNU General Public License for more details.
11 */
12 #include "sockets.h"
13 #include "sysdeps.h"
14 #include "qemu-timer.h"
15 #include "qemu-char.h"
16 #ifdef _WIN32
17 #include <winsock2.h>
18 #else
19 #include <sys/socket.h>
20 #include <sys/select.h>
21 #include <sys/types.h>
22 #include <netinet/in.h>
23 #include <netinet/tcp.h>
24 #include <netdb.h>
25 #endif
26
27 #define DEBUG 0
28
29 #define D_ACTIVE DEBUG
30
31 #if DEBUG
32 #define D(...) do { if (D_ACTIVE) fprintf(stderr, __VA_ARGS__); } while (0)
33 #else
34 #define D(...) ((void)0)
35 #endif
36
37 /** TIME
38 **/
39
40 SysTime
sys_time_ms(void)41 sys_time_ms( void )
42 {
43 return qemu_get_clock( rt_clock );
44 }
45
46 /** TIMERS
47 **/
48
49 typedef struct SysTimerRec_ {
50 QEMUTimer* timer;
51 QEMUTimerCB* callback;
52 void* opaque;
53 SysTimer next;
54 } SysTimerRec;
55
56 #define MAX_TIMERS 32
57
58 static SysTimerRec _s_timers0[ MAX_TIMERS ];
59 static SysTimer _s_free_timers;
60
61 static void
sys_init_timers(void)62 sys_init_timers( void )
63 {
64 int nn;
65 for (nn = 0; nn < MAX_TIMERS-1; nn++)
66 _s_timers0[nn].next = _s_timers0 + (nn+1);
67
68 _s_free_timers = _s_timers0;
69 }
70
71 static SysTimer
sys_timer_alloc(void)72 sys_timer_alloc( void )
73 {
74 SysTimer timer = _s_free_timers;
75
76 if (timer != NULL) {
77 _s_free_timers = timer->next;
78 timer->next = NULL;
79 timer->timer = NULL;
80 }
81 return timer;
82 }
83
84
85 static void
sys_timer_free(SysTimer timer)86 sys_timer_free( SysTimer timer )
87 {
88 if (timer->timer) {
89 qemu_del_timer( timer->timer );
90 qemu_free_timer( timer->timer );
91 timer->timer = NULL;
92 }
93 timer->next = _s_free_timers;
94 _s_free_timers = timer;
95 }
96
97
sys_timer_create(void)98 SysTimer sys_timer_create( void )
99 {
100 SysTimer timer = sys_timer_alloc();
101 return timer;
102 }
103
104 void
sys_timer_set(SysTimer timer,SysTime when,SysCallback _callback,void * opaque)105 sys_timer_set( SysTimer timer, SysTime when, SysCallback _callback, void* opaque )
106 {
107 QEMUTimerCB* callback = (QEMUTimerCB*)_callback;
108
109 if (callback == NULL) { /* unsetting the timer */
110 if (timer->timer) {
111 qemu_del_timer( timer->timer );
112 qemu_free_timer( timer->timer );
113 timer->timer = NULL;
114 }
115 timer->callback = callback;
116 timer->opaque = NULL;
117 return;
118 }
119
120 if ( timer->timer ) {
121 if ( timer->callback == callback && timer->opaque == opaque )
122 goto ReuseTimer;
123
124 /* need to replace the timer */
125 qemu_free_timer( timer->timer );
126 }
127
128 timer->timer = qemu_new_timer( rt_clock, callback, opaque );
129 timer->callback = callback;
130 timer->opaque = opaque;
131
132 ReuseTimer:
133 qemu_mod_timer( timer->timer, when );
134 }
135
136 void
sys_timer_unset(SysTimer timer)137 sys_timer_unset( SysTimer timer )
138 {
139 if (timer->timer) {
140 qemu_del_timer( timer->timer );
141 }
142 }
143
144 void
sys_timer_destroy(SysTimer timer)145 sys_timer_destroy( SysTimer timer )
146 {
147 sys_timer_free( timer );
148 }
149
150
151 /** CHANNELS
152 **/
153
154 typedef struct SysChannelRec_ {
155 int fd;
156 SysChannelCallback callback;
157 void* opaque;
158 SysChannel next;
159 } SysChannelRec;
160
161 #define MAX_CHANNELS 16
162
163 static SysChannelRec _s_channels0[ MAX_CHANNELS ];
164 static SysChannel _s_free_channels;
165
166 static void
sys_init_channels(void)167 sys_init_channels( void )
168 {
169 int nn;
170
171 for ( nn = 0; nn < MAX_CHANNELS-1; nn++ ) {
172 _s_channels0[nn].next = _s_channels0 + (nn+1);
173 }
174 _s_free_channels = _s_channels0;
175 }
176
177 static SysChannel
sys_channel_alloc()178 sys_channel_alloc( )
179 {
180 SysChannel channel = _s_free_channels;
181 if (channel != NULL) {
182 _s_free_channels = channel->next;
183 channel->next = NULL;
184 channel->fd = -1;
185 channel->callback = NULL;
186 channel->opaque = NULL;
187 }
188 return channel;
189 }
190
191 static void
sys_channel_free(SysChannel channel)192 sys_channel_free( SysChannel channel )
193 {
194 if (channel->fd >= 0) {
195 socket_close( channel->fd );
196 channel->fd = -1;
197 }
198 channel->next = _s_free_channels;
199 _s_free_channels = channel;
200 }
201
202
203 static void
sys_channel_read_handler(void * _channel)204 sys_channel_read_handler( void* _channel )
205 {
206 SysChannel channel = _channel;
207 D( "%s: read event for channel %p:%d\n", __FUNCTION__,
208 channel, channel->fd );
209 channel->callback( channel->opaque, SYS_EVENT_READ );
210 }
211
212 static void
sys_channel_write_handler(void * _channel)213 sys_channel_write_handler( void* _channel )
214 {
215 SysChannel channel = _channel;
216 D( "%s: write event for channel %p:%d\n", __FUNCTION__, channel, channel->fd );
217 channel->callback( channel->opaque, SYS_EVENT_WRITE );
218 }
219
220 void
sys_channel_on(SysChannel channel,int events,SysChannelCallback event_callback,void * event_opaque)221 sys_channel_on( SysChannel channel,
222 int events,
223 SysChannelCallback event_callback,
224 void* event_opaque )
225 {
226 IOHandler* read_handler = NULL;
227 IOHandler* write_handler = NULL;
228
229 if (events & SYS_EVENT_READ) {
230 read_handler = sys_channel_read_handler;
231 }
232 if (events & SYS_EVENT_WRITE) {
233 write_handler = sys_channel_write_handler;
234 }
235 channel->callback = event_callback;
236 channel->opaque = event_opaque;
237 qemu_set_fd_handler( channel->fd, read_handler, write_handler, channel );
238 }
239
240 int
sys_channel_read(SysChannel channel,void * buffer,int size)241 sys_channel_read( SysChannel channel, void* buffer, int size )
242 {
243 int len = size;
244 char* buf = (char*) buffer;
245
246 while (len > 0) {
247 int ret = socket_recv(channel->fd, buf, len);
248 if (ret < 0) {
249 if (errno == EINTR)
250 continue;
251 if (errno == EWOULDBLOCK)
252 break;
253 D( "%s: after reading %d bytes, recv() returned error %d: %s\n",
254 __FUNCTION__, size - len, errno, errno_str);
255 return -1;
256 } else if (ret == 0) {
257 break;
258 } else {
259 buf += ret;
260 len -= ret;
261 }
262 }
263 return size - len;
264 }
265
266
267 int
sys_channel_write(SysChannel channel,const void * buffer,int size)268 sys_channel_write( SysChannel channel, const void* buffer, int size )
269 {
270 int len = size;
271 const char* buf = (const char*) buffer;
272
273 while (len > 0) {
274 int ret = socket_send(channel->fd, buf, len);
275 if (ret < 0) {
276 if (errno == EINTR)
277 continue;
278 if (errno == EWOULDBLOCK)
279 break;
280 D( "%s: send() returned error %d: %s\n",
281 __FUNCTION__, errno, errno_str);
282 return -1;
283 } else if (ret == 0) {
284 break;
285 } else {
286 buf += ret;
287 len -= ret;
288 }
289 }
290 return size - len;
291 }
292
sys_channel_close(SysChannel channel)293 void sys_channel_close( SysChannel channel )
294 {
295 qemu_set_fd_handler( channel->fd, NULL, NULL, NULL );
296 sys_channel_free( channel );
297 }
298
sys_main_init(void)299 void sys_main_init( void )
300 {
301 sys_init_channels();
302 sys_init_timers();
303 }
304
305
sys_main_loop(void)306 int sys_main_loop( void )
307 {
308 /* no looping, qemu has its own event loop */
309 return 0;
310 }
311
312
313
314
315 SysChannel
sys_channel_create_tcp_server(int port)316 sys_channel_create_tcp_server( int port )
317 {
318 SysChannel channel = sys_channel_alloc();
319
320 channel->fd = socket_anyaddr_server( port, SOCKET_STREAM );
321 if (channel->fd < 0) {
322 D( "%s: failed to created network socket on TCP:%d\n",
323 __FUNCTION__, port );
324 sys_channel_free( channel );
325 return NULL;
326 }
327
328 D( "%s: server channel %p:%d now listening on port %d\n",
329 __FUNCTION__, channel, channel->fd, port );
330
331 return channel;
332 }
333
334
335 SysChannel
sys_channel_create_tcp_handler(SysChannel server_channel)336 sys_channel_create_tcp_handler( SysChannel server_channel )
337 {
338 SysChannel channel = sys_channel_alloc();
339
340 D( "%s: creating handler from server channel %p:%d\n", __FUNCTION__,
341 server_channel, server_channel->fd );
342
343 channel->fd = socket_accept_any( server_channel->fd );
344 if (channel->fd < 0) {
345 perror( "accept" );
346 sys_channel_free( channel );
347 return NULL;
348 }
349
350 /* disable Nagle algorithm */
351 socket_set_nodelay( channel->fd );
352
353 D( "%s: handler %p:%d created from server %p:%d\n", __FUNCTION__,
354 server_channel, server_channel->fd, channel, channel->fd );
355
356 return channel;
357 }
358
359
360 SysChannel
sys_channel_create_tcp_client(const char * hostname,int port)361 sys_channel_create_tcp_client( const char* hostname, int port )
362 {
363 SysChannel channel = sys_channel_alloc();
364
365 channel->fd = socket_network_client( hostname, port, SOCKET_STREAM );
366 if (channel->fd < 0) {
367 sys_channel_free(channel);
368 return NULL;
369 };
370
371 /* set to non-blocking and disable Nagle algorithm */
372 socket_set_nonblock( channel->fd );
373 socket_set_nodelay( channel->fd );
374
375 return channel;
376 }
377
378