blob: a0cd66f6e6659e3291d63b46bb0721ac486039e3 [file] [log] [blame]
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001/* 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 "sysdeps.h"
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <errno.h>
17
18#define PORT 8000
19#define MAX_COUNTER 30
20#define INITIAL_DELAY 1000
21#define DELAY 5000
22
23static int counter = 0;
24
25static void
26timer_func( void* _timer )
27{
28 SysTimer timer = _timer;
29 SysTime now = sys_time_ms();
30
31 ++counter;
32 printf( "tick %d/%d a %.2fs\n", counter, MAX_COUNTER, now/1000. );
33 if (counter < MAX_COUNTER)
34 sys_timer_set( timer, now + DELAY, timer_func, timer );
35 else
36 sys_timer_destroy( timer );
37}
38
39typedef struct {
40 SysChannel channel;
41 char in_buff[ 128 ];
42 int in_pos;
43
44 char out_buff[ 128 ];
45 int out_pos;
46 int out_size;
47} ClientRec, *Client;
48
49static Client
50client_alloc( SysChannel channel )
51{
52 Client client = calloc( sizeof(*client), 1 );
53
54 client->channel = channel;
55 return client;
56}
57
58static void
59client_free( Client client )
60{
61 sys_channel_close( client->channel );
62 client->channel = NULL;
63 free( client );
64}
65
66static void
67client_append( Client client, const char* str, int len );
68
69static void
70client_handle_line( Client client, const char* cmd )
71{
72 char temp[256];
73 int nn, mm = 0;
74
75 for (nn = 0; cmd[nn] != 0; nn++) {
76 int c = cmd[nn];
77 if (c >= 32 && c <= 127)
78 temp[mm++] = c;
79 else if (c == '\n') {
80 strcat( temp+mm, "<LF>" );
81 mm += 4;
82 }
83 else if (c == '\r') {
84 strcat( temp+mm, "<CR>" );
85 mm += 4;
86 }
87 else {
88 sprintf( temp+mm, "\\x%02x", c );
89 mm += strlen( temp+mm );
90 }
91 }
92 temp[mm] = 0;
93 printf( "%p: << %s\n", client, temp );
94
95 if ( !strcmp( cmd, "quit" ) ) {
96 printf( "client %p quitting\n", client );
97 client_free( client );
98 return;
99 }
100 client_append( client, "type 'quit' to quit\n", -1 );
101}
102
103static void
104client_handler( void* _client, int events )
105{
106 Client client = _client;
107
108 if (events & SYS_EVENT_READ) {
109 int ret;
110 /* read into buffer, one character at a time */
111 ret = sys_channel_read( client->channel, client->in_buff + client->in_pos, 1 );
112 if (ret != 1) {
113 fprintf(stderr, "client %p could not read byte, result = %d, error: %s\n",
114 client, ret, strerror(errno) );
115 goto ExitClient;
116 }
117 if (client->in_buff[client->in_pos] == '\r' ||
118 client->in_buff[client->in_pos] == '\n' ) {
119 const char* cmd = client->in_buff;
120 client->in_buff[client->in_pos] = 0;
121
122 /* eat leading cr and lf, maybe left-overs from previous line */
123 while (*cmd == '\r' || *cmd =='\n')
124 cmd++;
125
126 client_handle_line( client, cmd );
127 client->in_pos = 0;
128 } else
129 client->in_pos += 1;
130 }
131
132 if (events & SYS_EVENT_WRITE) {
133 int ret;
134 /* write from output buffer, one char at a time */
135 ret = sys_channel_write( client->channel, client->out_buff + client->out_pos, 1 );
136 if (ret != 1) {
137 fprintf(stderr, "client %p could not write byte, result = %d, error: %s\n",
138 client, ret, strerror(errno) );
139 goto ExitClient;
140 }
141 client->out_pos += 1;
142 if (client->out_pos == client->out_size) {
143 client->out_size = 0;
144 client->out_pos = 0;
145 /* we don't need to write */
146 sys_channel_on( client->channel, SYS_EVENT_READ, client_handler, client );
147 }
148 }
149 return;
150
151ExitClient:
152 printf( "client %p exiting\n", client );
153 client_free( client );
154}
155
156static void
157client_append( Client client, const char* str, int len )
158{
159 int avail;
160
161 if (len < 0)
162 len = strlen(str);
163
164 avail = sizeof(client->out_buff) - client->out_size;
165 if (len > avail)
166 len = avail;
167
168 memcpy( client->out_buff + client->out_size, str, len );
169 if (client->out_size == 0) {
170 sys_channel_on( client->channel, SYS_EVENT_READ | SYS_EVENT_WRITE, client_handler, client );
171 }
172 client->out_size += len;
173}
174
175
176static void
177accept_func( void* _server, int events )
178{
179 SysChannel server = _server;
180 SysChannel handler;
181 Client client;
182
183 printf( "connection accepted for server channel, getting handler socket\n" );
184 handler = sys_channel_create_tcp_handler( server );
185 printf( "got one. creating client\n" );
186 client = client_alloc( handler );
187
188 events=events;
189 sys_channel_on( handler, SYS_EVENT_READ, client_handler, client );
190 client_append( client, "Welcome !\n", -1 );
191}
192
193
194int main( void )
195{
196 SysTimer timer;
197 SysChannel server_channel;
198
199 /* initialize event subsystem */
200 sys_main_init();
201
202 /* create timer and register it */
203 timer = sys_timer_create();
204 sys_timer_set( timer, sys_time_ms() + INITIAL_DELAY, timer_func, timer );
205
206 server_channel = sys_channel_create_tcp_server( PORT );
207 printf( "listening on port %d with %p\n", PORT, server_channel );
208
209 sys_channel_on( server_channel, SYS_EVENT_READ, accept_func, server_channel );
210
211 printf("entering event loop\n");
212 sys_main_loop();
213 printf("exiting event loop\n" );
214 return 0;
215}