Home | History | Annotate | Download | only in telephony
      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 "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 
     23 static int  counter = 0;
     24 
     25 static void
     26 timer_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 
     39 typedef 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 
     49 static Client
     50 client_alloc( SysChannel  channel )
     51 {
     52     Client  client = calloc( sizeof(*client), 1 );
     53 
     54     client->channel = channel;
     55     return client;
     56 }
     57 
     58 static void
     59 client_free( Client  client )
     60 {
     61     sys_channel_close( client->channel );
     62     client->channel = NULL;
     63     free( client );
     64 }
     65 
     66 static void
     67 client_append( Client  client, const char*  str, int len );
     68 
     69 static void
     70 client_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 
    103 static void
    104 client_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 
    151 ExitClient:
    152     printf( "client %p exiting\n", client );
    153     client_free( client );
    154 }
    155 
    156 static void
    157 client_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 
    176 static void
    177 accept_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 
    194 int  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 }
    216