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*/ 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "sysdeps.h" 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h> 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h> 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h> 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <errno.h> 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PORT 8000 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define MAX_COUNTER 30 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define INITIAL_DELAY 1000 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DELAY 5000 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int counter = 0; 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttimer_func( void* _timer ) 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysTimer timer = _timer; 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysTime now = sys_time_ms(); 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ++counter; 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf( "tick %d/%d a %.2fs\n", counter, MAX_COUNTER, now/1000. ); 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (counter < MAX_COUNTER) 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_timer_set( timer, now + DELAY, timer_func, timer ); 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_timer_destroy( timer ); 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct { 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysChannel channel; 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char in_buff[ 128 ]; 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int in_pos; 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char out_buff[ 128 ]; 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int out_pos; 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int out_size; 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} ClientRec, *Client; 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic Client 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectclient_alloc( SysChannel channel ) 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Client client = calloc( sizeof(*client), 1 ); 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client->channel = channel; 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return client; 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectclient_free( Client client ) 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_channel_close( client->channel ); 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client->channel = NULL; 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free( client ); 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectclient_append( Client client, const char* str, int len ); 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectclient_handle_line( Client client, const char* cmd ) 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char temp[256]; 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn, mm = 0; 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (nn = 0; cmd[nn] != 0; nn++) { 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int c = cmd[nn]; 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (c >= 32 && c <= 127) 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project temp[mm++] = c; 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (c == '\n') { 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strcat( temp+mm, "<LF>" ); 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mm += 4; 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (c == '\r') { 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strcat( temp+mm, "<CR>" ); 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mm += 4; 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sprintf( temp+mm, "\\x%02x", c ); 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mm += strlen( temp+mm ); 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project temp[mm] = 0; 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf( "%p: << %s\n", client, temp ); 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( !strcmp( cmd, "quit" ) ) { 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf( "client %p quitting\n", client ); 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client_free( client ); 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client_append( client, "type 'quit' to quit\n", -1 ); 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectclient_handler( void* _client, int events ) 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Client client = _client; 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (events & SYS_EVENT_READ) { 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* read into buffer, one character at a time */ 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = sys_channel_read( client->channel, client->in_buff + client->in_pos, 1 ); 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret != 1) { 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fprintf(stderr, "client %p could not read byte, result = %d, error: %s\n", 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client, ret, strerror(errno) ); 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto ExitClient; 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (client->in_buff[client->in_pos] == '\r' || 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client->in_buff[client->in_pos] == '\n' ) { 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char* cmd = client->in_buff; 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client->in_buff[client->in_pos] = 0; 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* eat leading cr and lf, maybe left-overs from previous line */ 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (*cmd == '\r' || *cmd =='\n') 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cmd++; 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client_handle_line( client, cmd ); 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client->in_pos = 0; 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client->in_pos += 1; 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (events & SYS_EVENT_WRITE) { 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write from output buffer, one char at a time */ 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = sys_channel_write( client->channel, client->out_buff + client->out_pos, 1 ); 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret != 1) { 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fprintf(stderr, "client %p could not write byte, result = %d, error: %s\n", 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client, ret, strerror(errno) ); 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto ExitClient; 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client->out_pos += 1; 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (client->out_pos == client->out_size) { 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client->out_size = 0; 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client->out_pos = 0; 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* we don't need to write */ 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_channel_on( client->channel, SYS_EVENT_READ, client_handler, client ); 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectExitClient: 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf( "client %p exiting\n", client ); 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client_free( client ); 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectclient_append( Client client, const char* str, int len ) 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int avail; 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len < 0) 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = strlen(str); 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project avail = sizeof(client->out_buff) - client->out_size; 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len > avail) 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = avail; 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy( client->out_buff + client->out_size, str, len ); 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (client->out_size == 0) { 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_channel_on( client->channel, SYS_EVENT_READ | SYS_EVENT_WRITE, client_handler, client ); 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client->out_size += len; 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectaccept_func( void* _server, int events ) 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysChannel server = _server; 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysChannel handler; 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Client client; 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf( "connection accepted for server channel, getting handler socket\n" ); 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project handler = sys_channel_create_tcp_handler( server ); 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf( "got one. creating client\n" ); 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client = client_alloc( handler ); 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project events=events; 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_channel_on( handler, SYS_EVENT_READ, client_handler, client ); 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project client_append( client, "Welcome !\n", -1 ); 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint main( void ) 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysTimer timer; 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SysChannel server_channel; 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* initialize event subsystem */ 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_main_init(); 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* create timer and register it */ 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project timer = sys_timer_create(); 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_timer_set( timer, sys_time_ms() + INITIAL_DELAY, timer_func, timer ); 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project server_channel = sys_channel_create_tcp_server( PORT ); 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf( "listening on port %d with %p\n", PORT, server_channel ); 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_channel_on( server_channel, SYS_EVENT_READ, accept_func, server_channel ); 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("entering event loop\n"); 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sys_main_loop(); 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("exiting event loop\n" ); 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 216