diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | 55f4e4a5ec657a017e3bf75299ad71fd1c968dd3 (patch) | |
tree | 550ce922ea0e125ac6a9738210ce2939bf2fe901 /telephony/simulator.c | |
parent | 413f05aaf54fa08c0ae7e997327a4f4a473c0a8d (diff) | |
download | external_qemu-55f4e4a5ec657a017e3bf75299ad71fd1c968dd3.zip external_qemu-55f4e4a5ec657a017e3bf75299ad71fd1c968dd3.tar.gz external_qemu-55f4e4a5ec657a017e3bf75299ad71fd1c968dd3.tar.bz2 |
Initial Contribution
Diffstat (limited to 'telephony/simulator.c')
-rw-r--r-- | telephony/simulator.c | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/telephony/simulator.c b/telephony/simulator.c new file mode 100644 index 0000000..43f267a --- /dev/null +++ b/telephony/simulator.c @@ -0,0 +1,195 @@ +/* Copyright (C) 2007-2008 The Android Open Source Project +** +** This software is licensed under the terms of the GNU General Public +** License version 2, as published by the Free Software Foundation, and +** may be copied, distributed, and modified under those terms. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +*/ +#include "android_modem.h" +#include "sysdeps.h" +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> + +#define DEFAULT_PORT 6703 + +static AModem modem; + +typedef struct { + SysChannel channel; + char in_buff[ 128 ]; + int in_pos; + + char out_buff[ 128 ]; + int out_pos; + int out_size; +} ClientRec, *Client; + +static Client +client_alloc( SysChannel channel ) +{ + Client client = calloc( sizeof(*client), 1 ); + + client->channel = channel; + return client; +} + +static void +client_free( Client client ) +{ + sys_channel_close( client->channel ); + client->channel = NULL; + free( client ); +} + +static void +client_append( Client client, const char* str, int len ); + +static void +dump_line( const char* line, const char* prefix ) +{ + if (prefix) + printf( "%s", prefix ); + + for ( ; *line; line++ ) { + int c = line[0]; + + if (c >= 32 && c < 127) + printf( "%c", c ); + else if (c == '\r') + printf( "<CR>" ); + else if (c == '\n') + printf( "<LF>" ); + else + printf( "\\x%02x", c ); + } + printf( "\n" ); +} + +static void +client_handle_line( Client client, const char* cmd ) +{ + const char* answer; + + dump_line( cmd, "<< " ); + answer = amodem_send( modem, cmd ); + if (answer == NULL) /* not an AT command, ignored */ { + printf( "-- NO ANSWER\n" ); + return; + } + + dump_line( answer, ">> " ); + client_append( client, answer, -1 ); + client_append( client, "\r", 1 ); +} + +static void +client_handler( void* _client, int events ) +{ + Client client = _client; + + if (events & SYS_EVENT_READ) { + int ret; + /* read into buffer, one character at a time */ + ret = sys_channel_read( client->channel, client->in_buff + client->in_pos, 1 ); + if (ret != 1) { + fprintf(stderr, "client %p could not read byte, result = %d, error: %s\n", + client, ret, strerror(errno) ); + goto ExitClient; + } + if (client->in_buff[client->in_pos] == '\r' || + client->in_buff[client->in_pos] == '\n' ) { + const char* cmd = client->in_buff; + client->in_buff[client->in_pos] = 0; + + if (client->in_pos > 0) { + client_handle_line( client, cmd ); + client->in_pos = 0; + } + } else + client->in_pos += 1; + } + + if (events & SYS_EVENT_WRITE) { + int ret; + /* write from output buffer, one char at a time */ + ret = sys_channel_write( client->channel, client->out_buff + client->out_pos, 1 ); + if (ret != 1) { + fprintf(stderr, "client %p could not write byte, result = %d, error: %s\n", + client, ret, strerror(errno) ); + goto ExitClient; + } + client->out_pos += 1; + if (client->out_pos == client->out_size) { + client->out_size = 0; + client->out_pos = 0; + /* we don't need to write */ + sys_channel_on( client->channel, SYS_EVENT_READ, client_handler, client ); + } + } + return; + +ExitClient: + printf( "client %p exiting\n", client ); + client_free( client ); +} + + +static void +client_append( Client client, const char* str, int len ) +{ + int avail; + + if (len < 0) + len = strlen(str); + + avail = sizeof(client->out_buff) - client->out_size; + if (len > avail) + len = avail; + + memcpy( client->out_buff + client->out_size, str, len ); + if (client->out_size == 0) { + sys_channel_on( client->channel, SYS_EVENT_READ | SYS_EVENT_WRITE, client_handler, client ); + } + client->out_size += len; +} + + +static void +accept_func( void* _server, int events ) +{ + SysChannel server = _server; + SysChannel handler; + Client client; + + printf( "connection accepted for server channel, getting handler socket\n" ); + handler = sys_channel_create_tcp_handler( server ); + client = client_alloc( handler ); + printf( "got one. created client %p\n", client ); + + events=events; + sys_channel_on( handler, SYS_EVENT_READ, client_handler, client ); +} + + +int main( void ) +{ + int port = DEFAULT_PORT; + SysChannel server; + + sys_main_init(); + modem = amodem_create( NULL, NULL ); + + server = sys_channel_create_tcp_server( port ); + printf( "GSM simulator listening on local port %d\n", port ); + + sys_channel_on( server, SYS_EVENT_READ, accept_func, server ); + sys_main_loop(); + printf( "GSM simulator exiting\n" ); + return 0; +} |