In Part 2 of this series on Android System Verification I provided the basics on how to use the Android emulator console to connect to the built in telnet server and send commands to the emulator. These commands represent hardware events related to power, network, gsm, geo, and sms. In this installment I will describe how to automate this connection by using a C program to send the emulator commands.
After sending commands via telnet it was clear that typing commands is not a good way to do verification and something that must be automated. It's probably the equivalent of typing commands at the Incisive Simulator prompt to set signal values and read signal values.
Unfortunately, telnet is not the easiest thing to automate by scripting because it requires more than just piping input into a terminal or running shell script. I could think of various ways to try to get telnet to start and pipe input to it using the shell or something like expect.
Here is a possible script:
telnet localhost 5554 << EOF
I even thought of trying an xterm in slave mode using xterm -S. But what I came to realize is there is no easy way to do this. Even if such a script did work (which it did not for me), it's not very convenient to create a verification flow that would somehow generate commands and put them into a script in a reactive way. After trying a few different ideas, I gave up on this approach. If anybody out there has any interesting ideas to automate the telnet connection please share them.
In the end I settled on the approach of using a C program to open the socket just as the telnet client would and send the commands over the socket. This provides the needed control and it's easy to take the C program and connect it to the verification environment.
To get started I figured out how to write a C program that will connect to the telnet server and have a C API that is similar to the commands I could type using the manual connection.
Here is the approach:
Use socket() and connect() to establish the connection to the emulator console
Create a C API for a set of emulator commands
Test the sending of commands as well as the reception of the command results using a stand-alone C program
Once the program is working remove the main() and turn it into a .so file and use it as a bridge between Specman and the emulator console
The first task was to figure out what kind of socket to use and the appropriate parameters to connect to a telnet server. One good reference I use often is Advanced Programming in the UNIX Environment. There are many other examples you can find by searching.
Once the socket was setup, I figured out how to use send() to send a command and capture the output coming back from the Android console using a recv() call. To make things easier I decided to decouple the send and receive by putting the receive operation in a separate thread.
In the end I ended up with an API that can setup the connection, send the supported emulator commands, and close the connection.
int ac_init(); /* returns 0 if everything is OK */
void ac_quit(); /* close the connection */
/* Do various kinds of commands */
void do_gsm(gsm_operation_t op, char *ops)
void do_sms(sms_operation_t op, char *ops)
void do_network(net_operation_t op, char *ops)
void do_geo(char *ops)
void do_power(power_operation_t op, char *ops)
Since this is just for demonstration purposes I skipped the return values on the command API and just used perror(). I also created a log file with a history of the commands that can be turned on in case things go wrong and to learn about the traffic that is going back and forth.
The command API has enumerated types to provide the sub-commands for each operation. For example, the gsm operations can be any of:
The ops argument provides the specific details in string form, such as the phone number in the case of making a call.
Using this API we can write a simple C program to make a call:
int main(int argc, char *argv)
The full source code is available.
To compile it as a stand-alone program use:
% gcc -g -o android_console android_console.c -lpthread -DMAIN
The code is for demonstration only. It assumes the emulator is running on the same machine using the default port. I'm sure there are many improvements that can be made so feel free to send contributions.
Amazingly enough I couldn't find any tips or clues about how other people have developed any kind of automated test environment using the Android emulator. It seems like a common task to be done, but maybe nobody has had time to share it.
Now we are ready to use the C code as a bridge to connect a Specman verification environment so we can start to generate as many interesting sequences as possible using randomization and constraints. This is where we will pick up next time.