aboutsummaryrefslogtreecommitdiffstats
path: root/telephony/simulator.c
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
commit55f4e4a5ec657a017e3bf75299ad71fd1c968dd3 (patch)
tree550ce922ea0e125ac6a9738210ce2939bf2fe901 /telephony/simulator.c
parent413f05aaf54fa08c0ae7e997327a4f4a473c0a8d (diff)
downloadexternal_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.c195
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;
+}