18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms. 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful, 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details. 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 12cc330d4169441727fecf1da08aee806fc021c4e2David 'Digit' Turner#include "android/sockets.h" 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "sysdeps.h" 14a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner#include "qemu-common.h" 157a78db75ad42aea283f5073f51891464104a9fc3David 'Digit' Turner#include "qemu/timer.h" 16e7216d82dbaa19892ad62b07402d512234559a6eDavid 'Digit' Turner#include "sysemu/char.h" 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <winsock2.h> 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/socket.h> 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/select.h> 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/types.h> 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <netinet/in.h> 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <netinet/tcp.h> 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <netdb.h> 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 283e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner#define DEBUG 0 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define D_ACTIVE DEBUG 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if DEBUG 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define D(...) do { if (D_ACTIVE) fprintf(stderr, __VA_ARGS__); } while (0) 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define D(...) ((void)0) 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** TIME 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/ 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSysTime 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_time_ms( void ) 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 44dcda949f769a11b197f4784fe299a448d87e6e14David 'Digit' Turner return qemu_clock_get_ms(QEMU_CLOCK_REALTIME); 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** TIMERS 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/ 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct SysTimerRec_ { 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QEMUTimer* timer; 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QEMUTimerCB* callback; 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void* opaque; 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysTimer next; 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} SysTimerRec; 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define MAX_TIMERS 32 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SysTimerRec _s_timers0[ MAX_TIMERS ]; 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SysTimer _s_free_timers; 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_init_timers( void ) 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn; 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (nn = 0; nn < MAX_TIMERS-1; nn++) 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project _s_timers0[nn].next = _s_timers0 + (nn+1); 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project _s_free_timers = _s_timers0; 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SysTimer 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_timer_alloc( void ) 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysTimer timer = _s_free_timers; 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (timer != NULL) { 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project _s_free_timers = timer->next; 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project timer->next = NULL; 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project timer->timer = NULL; 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return timer; 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_timer_free( SysTimer timer ) 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (timer->timer) { 90dcda949f769a11b197f4784fe299a448d87e6e14David 'Digit' Turner timer_del( timer->timer ); 91dcda949f769a11b197f4784fe299a448d87e6e14David 'Digit' Turner timer_free( timer->timer ); 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project timer->timer = NULL; 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project timer->next = _s_free_timers; 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project _s_free_timers = timer; 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSysTimer sys_timer_create( void ) 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysTimer timer = sys_timer_alloc(); 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return timer; 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_timer_set( SysTimer timer, SysTime when, SysCallback _callback, void* opaque ) 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QEMUTimerCB* callback = (QEMUTimerCB*)_callback; 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (callback == NULL) { /* unsetting the timer */ 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (timer->timer) { 112dcda949f769a11b197f4784fe299a448d87e6e14David 'Digit' Turner timer_del( timer->timer ); 113dcda949f769a11b197f4784fe299a448d87e6e14David 'Digit' Turner timer_free( timer->timer ); 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project timer->timer = NULL; 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project timer->callback = callback; 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project timer->opaque = NULL; 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( timer->timer ) { 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( timer->callback == callback && timer->opaque == opaque ) 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto ReuseTimer; 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* need to replace the timer */ 126dcda949f769a11b197f4784fe299a448d87e6e14David 'Digit' Turner timer_free( timer->timer ); 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 129dcda949f769a11b197f4784fe299a448d87e6e14David 'Digit' Turner timer->timer = timer_new(QEMU_CLOCK_REALTIME, SCALE_MS, callback, opaque ); 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project timer->callback = callback; 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project timer->opaque = opaque; 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectReuseTimer: 134dcda949f769a11b197f4784fe299a448d87e6e14David 'Digit' Turner timer_mod( timer->timer, when ); 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_timer_unset( SysTimer timer ) 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (timer->timer) { 141dcda949f769a11b197f4784fe299a448d87e6e14David 'Digit' Turner timer_del( timer->timer ); 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_timer_destroy( SysTimer timer ) 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_timer_free( timer ); 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** CHANNELS 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/ 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct SysChannelRec_ { 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fd; 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysChannelCallback callback; 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void* opaque; 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysChannel next; 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} SysChannelRec; 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define MAX_CHANNELS 16 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SysChannelRec _s_channels0[ MAX_CHANNELS ]; 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SysChannel _s_free_channels; 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_init_channels( void ) 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn; 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for ( nn = 0; nn < MAX_CHANNELS-1; nn++ ) { 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project _s_channels0[nn].next = _s_channels0 + (nn+1); 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project _s_free_channels = _s_channels0; 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SysChannel 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_channel_alloc( ) 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysChannel channel = _s_free_channels; 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (channel != NULL) { 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project _s_free_channels = channel->next; 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project channel->next = NULL; 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project channel->fd = -1; 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project channel->callback = NULL; 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project channel->opaque = NULL; 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return channel; 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_channel_free( SysChannel channel ) 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (channel->fd >= 0) { 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_close( channel->fd ); 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project channel->fd = -1; 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project channel->next = _s_free_channels; 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project _s_free_channels = channel; 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_channel_read_handler( void* _channel ) 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysChannel channel = _channel; 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D( "%s: read event for channel %p:%d\n", __FUNCTION__, 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project channel, channel->fd ); 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project channel->callback( channel->opaque, SYS_EVENT_READ ); 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_channel_write_handler( void* _channel ) 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysChannel channel = _channel; 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D( "%s: write event for channel %p:%d\n", __FUNCTION__, channel, channel->fd ); 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project channel->callback( channel->opaque, SYS_EVENT_WRITE ); 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_channel_on( SysChannel channel, 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int events, 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysChannelCallback event_callback, 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void* event_opaque ) 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project IOHandler* read_handler = NULL; 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project IOHandler* write_handler = NULL; 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (events & SYS_EVENT_READ) { 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project read_handler = sys_channel_read_handler; 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (events & SYS_EVENT_WRITE) { 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project write_handler = sys_channel_write_handler; 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project channel->callback = event_callback; 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project channel->opaque = event_opaque; 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_set_fd_handler( channel->fd, read_handler, write_handler, channel ); 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_channel_read( SysChannel channel, void* buffer, int size ) 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len = size; 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* buf = (char*) buffer; 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (len > 0) { 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret = socket_recv(channel->fd, buf, len); 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) { 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (errno == EINTR) 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 252ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner if (errno == EWOULDBLOCK || errno == EAGAIN) 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D( "%s: after reading %d bytes, recv() returned error %d: %s\n", 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project __FUNCTION__, size - len, errno, errno_str); 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (ret == 0) { 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf += ret; 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len -= ret; 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return size - len; 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_channel_write( SysChannel channel, const void* buffer, int size ) 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len = size; 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char* buf = (const char*) buffer; 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (len > 0) { 2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret = socket_send(channel->fd, buf, len); 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) { 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (errno == EINTR) 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 279ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner if (errno == EWOULDBLOCK || errno == EAGAIN) 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D( "%s: send() returned error %d: %s\n", 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project __FUNCTION__, errno, errno_str); 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (ret == 0) { 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf += ret; 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len -= ret; 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return size - len; 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid sys_channel_close( SysChannel channel ) 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_set_fd_handler( channel->fd, NULL, NULL, NULL ); 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_channel_free( channel ); 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid sys_main_init( void ) 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_init_channels(); 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_init_timers(); 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint sys_main_loop( void ) 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* no looping, qemu has its own event loop */ 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSysChannel 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_channel_create_tcp_server( int port ) 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysChannel channel = sys_channel_alloc(); 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project channel->fd = socket_anyaddr_server( port, SOCKET_STREAM ); 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (channel->fd < 0) { 3235973c775c853e26f684de58ad28c267281aaffd6David 'Digit' Turner D( "%s: failed to created network socket on TCP:%d\n", 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project __FUNCTION__, port ); 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_channel_free( channel ); 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D( "%s: server channel %p:%d now listening on port %d\n", 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project __FUNCTION__, channel, channel->fd, port ); 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return channel; 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSysChannel 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_channel_create_tcp_handler( SysChannel server_channel ) 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysChannel channel = sys_channel_alloc(); 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D( "%s: creating handler from server channel %p:%d\n", __FUNCTION__, 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project server_channel, server_channel->fd ); 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project channel->fd = socket_accept_any( server_channel->fd ); 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (channel->fd < 0) { 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project perror( "accept" ); 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_channel_free( channel ); 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* disable Nagle algorithm */ 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_set_nodelay( channel->fd ); 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project D( "%s: handler %p:%d created from server %p:%d\n", __FUNCTION__, 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project server_channel, server_channel->fd, channel, channel->fd ); 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return channel; 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSysChannel 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsys_channel_create_tcp_client( const char* hostname, int port ) 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysChannel channel = sys_channel_alloc(); 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project channel->fd = socket_network_client( hostname, port, SOCKET_STREAM ); 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (channel->fd < 0) { 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_channel_free(channel); 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project }; 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* set to non-blocking and disable Nagle algorithm */ 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_set_nonblock( channel->fd ); 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_set_nodelay( channel->fd ); 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return channel; 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 379