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 "android_modem.h"
     13 #include "sysdeps.h"
     14 #include <stdio.h>
     15 #include <stdlib.h>
     16 #include <errno.h>
     17 #include <string.h>
     18 
     19 #define  DEFAULT_PORT  6703
     20 
     21 static AModem  modem;
     22 
     23 typedef struct {
     24     SysChannel   channel;
     25     char         in_buff[ 128 ];
     26     int          in_pos;
     27 
     28     char         out_buff[ 128 ];
     29     int          out_pos;
     30     int          out_size;
     31 } ClientRec, *Client;
     32 
     33 static Client
     34 client_alloc( SysChannel  channel )
     35 {
     36     Client  client = calloc( sizeof(*client), 1 );
     37 
     38     client->channel = channel;
     39     return client;
     40 }
     41 
     42 static void
     43 client_free( Client  client )
     44 {
     45     sys_channel_close( client->channel );
     46     client->channel = NULL;
     47     free( client );
     48 }
     49 
     50 static void
     51 client_append( Client  client, const char*  str, int len );
     52 
     53 static void
     54 dump_line( const char*  line, const char*  prefix )
     55 {
     56     if (prefix)
     57         printf( "%s", prefix );
     58 
     59     for ( ; *line; line++ ) {
     60         int  c = line[0];
     61 
     62         if (c >= 32 && c < 127)
     63             printf( "%c", c );
     64         else if (c == '\r')
     65             printf( "<CR>" );
     66         else if (c == '\n')
     67             printf( "<LF>" );
     68         else
     69             printf( "\\x%02x", c );
     70     }
     71     printf( "\n" );
     72 }
     73 
     74 static void
     75 client_handle_line( Client  client, const char*  cmd )
     76 {
     77     const char*  answer;
     78 
     79     dump_line( cmd, "<< " );
     80     answer = amodem_send( modem, cmd );
     81     if (answer == NULL)  /* not an AT command, ignored */ {
     82         printf( "-- NO ANSWER\n" );
     83         return;
     84     }
     85 
     86     dump_line( answer, ">> " );
     87     client_append( client, answer, -1 );
     88     client_append( client, "\r", 1 );
     89 }
     90 
     91 static void
     92 client_handler( void* _client, int  events )
     93 {
     94     Client  client = _client;
     95 
     96     if (events & SYS_EVENT_READ) {
     97         int  ret;
     98         /* read into buffer, one character at a time */
     99         ret = sys_channel_read( client->channel, client->in_buff + client->in_pos, 1 );
    100         if (ret != 1) {
    101             fprintf(stderr, "client %p could not read byte, result = %d, error: %s\n",
    102                     client, ret, strerror(errno) );
    103             goto ExitClient;
    104         }
    105         if (client->in_buff[client->in_pos] == '\r' ||
    106             client->in_buff[client->in_pos] == '\n' ) {
    107             const char*  cmd = client->in_buff;
    108             client->in_buff[client->in_pos] = 0;
    109 
    110             if (client->in_pos > 0) {
    111                 client_handle_line( client, cmd );
    112                 client->in_pos = 0;
    113             }
    114         } else
    115             client->in_pos += 1;
    116     }
    117 
    118     if (events & SYS_EVENT_WRITE) {
    119         int  ret;
    120         /* write from output buffer, one char at a time */
    121         ret = sys_channel_write( client->channel, client->out_buff + client->out_pos, 1 );
    122         if (ret != 1) {
    123             fprintf(stderr, "client %p could not write byte, result = %d, error: %s\n",
    124                     client, ret, strerror(errno) );
    125             goto ExitClient;
    126         }
    127         client->out_pos += 1;
    128         if (client->out_pos == client->out_size) {
    129             client->out_size = 0;
    130             client->out_pos  = 0;
    131             /* we don't need to write */
    132             sys_channel_on( client->channel, SYS_EVENT_READ, client_handler, client );
    133         }
    134     }
    135     return;
    136 
    137 ExitClient:
    138     printf( "client %p exiting\n", client );
    139     client_free( client );
    140 }
    141 
    142 
    143 static void
    144 client_append( Client  client, const char*  str, int len )
    145 {
    146     int  avail;
    147 
    148     if (len < 0)
    149         len = strlen(str);
    150 
    151     avail = sizeof(client->out_buff) - client->out_size;
    152     if (len > avail)
    153         len = avail;
    154 
    155     memcpy( client->out_buff + client->out_size, str, len );
    156     if (client->out_size == 0) {
    157         sys_channel_on( client->channel, SYS_EVENT_READ | SYS_EVENT_WRITE, client_handler, client );
    158     }
    159     client->out_size += len;
    160 }
    161 
    162 
    163 static void
    164 accept_func( void*  _server, int  events )
    165 {
    166     SysChannel  server  = _server;
    167     SysChannel  handler;
    168     Client      client;
    169 
    170     printf( "connection accepted for server channel, getting handler socket\n" );
    171     handler = sys_channel_create_tcp_handler( server );
    172     client  = client_alloc( handler );
    173     printf( "got one. created client %p\n", client );
    174 
    175     events=events;
    176     sys_channel_on( handler, SYS_EVENT_READ, client_handler, client );
    177 }
    178 
    179 
    180 int  main( void )
    181 {
    182     int  port = DEFAULT_PORT;
    183     SysChannel  server;
    184 
    185     sys_main_init();
    186     modem = amodem_create( NULL, NULL );
    187 
    188     server = sys_channel_create_tcp_server( port );
    189     printf( "GSM simulator listening on local port %d\n", port );
    190 
    191     sys_channel_on( server, SYS_EVENT_READ, accept_func, server );
    192     sys_main_loop();
    193     printf( "GSM simulator exiting\n" );
    194     return 0;
    195 }
    196