• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
client_alloc(SysChannel channel)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
client_free(Client client)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
dump_line(const char * line,const char * prefix)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
client_handle_line(Client client,const char * cmd)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
client_handler(void * _client,int events)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
client_append(Client client,const char * str,int len)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
accept_func(void * _server,int events)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 
main(void)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