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