/* ** simple program to connect to Android telnet console ** instead of typing commands into a telnet client */ #include #include #include #include #include #include #include #include #include #include #include #include /* ** commands supported by the Android console */ typedef enum { GSM_CALL, GSM_ACCEPT, GSM_BUSY, GSM_CANCEL, GSM_DATA, GSM_HOLD, GSM_LIST, GSM_STATUS } gsm_operation_t; typedef enum { NET_DELAY, NET_SPEED } net_operation_t; typedef enum { POWER_DISPLAY, POWER_AC, POWER_STATUS, POWER_PRESENT, POWER_HEALTH, POWER_CAPACITY } power_operation_t; typedef enum { SMS_SEND, SMS_PDU } sms_operation_t; #define LOG_RECV 1 #define LOG_SEND 2 typedef struct { int logging; /* flag to turn on logging */ FILE *logfile; /* logfile descriptor */ } logger_t; typedef struct { int sock; int port; int addrlen; int family; char *address; logger_t log; struct sockaddr *addr; } connection_t; connection_t con; static int receive_count = 0; static int send_count = 1; /* some stuff is received on the original connect */ static int gethost(char *address, struct sockaddr_in *in) { long num; struct hostent *h; num = inet_addr(address); if (num > 0) { in->sin_addr.s_addr = num; return 0; } h = gethostbyname(address); if (h) { in->sin_addr = *(struct in_addr *)h->h_addr_list[0]; return 0; } return 1; /* error */ } static void logger(connection_t *d, char *input, int numbytes, int flag) { char buf[128]; char *p; sprintf(buf, "%s.%d %s:", d->address, d->port, flag == LOG_RECV ? "receives" : "sends"); p = input; if (d->log.logging == 1) { fprintf(d->log.logfile, "%s\n%s\n(%d bytes)\n", buf, p, numbytes); fflush(d->log.logfile); } } void do_cmd(char *cmd) { int len; connection_t *dp = &con; send_count++; /* send command */ len = strlen(cmd); if (dp->family == SOCK_STREAM) { if (send(dp->sock, cmd, len, 0) < 0) { perror("send"); return; } } logger(dp, cmd, len, LOG_SEND); while(send_count > receive_count); } void do_geo(char *ops) { char buf[80]; sprintf(buf, "geo fix %s\r",ops); do_cmd(buf); } void do_network(net_operation_t op, char *ops) { char buf[80]; switch (op) { case NET_DELAY: sprintf(buf, "network delay %s\r",ops); break; case NET_SPEED: sprintf(buf, "network speed %s\r",ops); break; } do_cmd(buf); } void do_power(power_operation_t op, char *ops) { char buf[80]; switch (op) { case POWER_DISPLAY: sprintf(buf, "power display\r"); break; case POWER_AC: sprintf(buf, "power ac %s\r",ops); /* on or off */ break; case POWER_STATUS: sprintf(buf, "power status %s\r",ops); break; case POWER_PRESENT: sprintf(buf, "power present %s\r",ops); /* true or false */ break; case POWER_HEALTH: sprintf(buf, "power health %s\r",ops); break; case POWER_CAPACITY: sprintf(buf, "power capacity %s\r",ops); /* percentage */ break; } do_cmd(buf); } void do_sms(sms_operation_t op, char *ops) { char buf[255]; switch (op) { case SMS_SEND: sprintf(buf, "sms send %s\r",ops); break; case SMS_PDU: sprintf(buf, "sms pdu %s\r",ops); /* some kind of hex string ? */ break; } do_cmd(buf); } void do_gsm(gsm_operation_t op, char *arg) { char buf[80]; switch (op) { case GSM_CALL: sprintf(buf, "gsm call %s\r",arg); break; case GSM_ACCEPT: sprintf(buf, "gsm accept %s\r",arg); break; case GSM_BUSY: sprintf(buf, "gsm busy %s\r",arg); break; case GSM_CANCEL: sprintf(buf, "gsm cancel %s\r",arg); break; case GSM_DATA: sprintf(buf, "gsm data %s\r",arg); break; case GSM_HOLD: sprintf(buf, "gsm hold %s\r",arg); break; case GSM_LIST: sprintf(buf, "gsm list %s\r",arg); break; case GSM_STATUS: sprintf(buf, "gsm status\r"); break; } do_cmd(buf); } static void *receive(void *arg) { connection_t *d = arg; int rc; char buf[8192]; for (;;) { if (d->family == SOCK_STREAM) { rc = recv(d->sock, buf, sizeof buf - 1, 0); if (rc == -1) { perror("recv"); break; } else if (rc == 0) break; buf[rc] = 0; logger(d, buf, rc, LOG_RECV); } receive_count++; } return NULL; /* will never return */ } void ac_quit() { shutdown(con.sock, SHUT_RDWR); close(con.sock); if (con.log.logfile != NULL) { fclose(con.log.logfile); } } int ac_init(char *machine, int port) { int rc; pthread_t receivet; struct sockaddr_in addr; con.log.logfile = NULL; con.family = SOCK_STREAM; con.port = port; con.address = machine; con.log.logging = 1; con.log.logfile = fopen("android_console.log", "w+"); if (gethost(con.address, &addr) != 0) { herror(con.address); return 1; } con.addr = (struct sockaddr *) &addr; con.addrlen = sizeof(addr); addr.sin_family = AF_INET; addr.sin_port = htons(port); con.sock = socket(AF_INET, con.family, 0); if (con.sock < 0) { perror("socket"); return 1; } if (con.family == SOCK_STREAM) { if (connect(con.sock, con.addr, con.addrlen) < 0) { perror("connect"); return 1; } } if ((rc = pthread_create(&receivet, NULL, receive, &con )) != 0) { fprintf(stderr, "pthread_create: %s\n", strerror(rc)); return 1; } while (send_count > receive_count); return 0; } #ifdef MAIN int main(int argc, char *argv[]) { ac_init("localhost", 5554); do_gsm(GSM_CALL, "6128035577\n"); sleep(5); do_gsm(GSM_HOLD, "6128035577\n"); sleep(5); do_gsm(GSM_CANCEL, "6128035577\n"); ac_quit(); } #endif