console.c revision 777eb68eb60cac18f4b62e2e1b14a906875cbe7a
18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms.
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful,
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details.
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *  Android emulator control console
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *  this console is enabled automatically at emulator startup, on port 5554 by default,
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *  unless some other emulator is already running. See (android_emulation_start in android_sdl.c
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *  for details)
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *  you can telnet to the console, then use commands like 'help' or others to dynamically
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *  change emulator settings.
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "sockets.h"
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu-char.h"
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "sysemu.h"
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/android.h"
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "cpu.h"
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "hw/goldfish_device.h"
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "hw/power_supply.h"
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "shaper.h"
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "modem_driver.h"
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/gps.h"
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/globals.h"
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/bufprint.h"
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/debug.h"
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/stralloc.h"
382ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije#include "android/config/config.h"
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "tcpdump.h"
405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "net.h"
41e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner#include "monitor.h"
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h>
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdarg.h>
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h>
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <unistd.h>
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <fcntl.h>
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/hw-events.h"
5034f2974ce7ec7c71beb47b5daf9089d5c8c40c79David 'Digit' Turner#include "user-events.h"
5171bb14f826775867d16e7d382cfdc48e6ca46ccbVladimir Chtchetkine#include "android/keycode-array.h"
5271bb14f826775867d16e7d382cfdc48e6ca46ccbVladimir Chtchetkine#include "android/charmap.h"
53e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine#include "android/display-core.h"
54e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine#include "android/framebuffer-core.h"
559411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine#include "android/user-events-core.h"
56777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine#include "android/protocol/ui-commands-api.h"
57777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine#include "android/protocol/core-commands-impl.h"
58777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine#include "android/protocol/ui-commands-proxy.h"
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(CONFIG_SLIRP)
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "libslirp.h"
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  DEBUG  1
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 1
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define  D_ACTIVE   VERBOSE_CHECK(console)
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define  D_ACTIVE   DEBUG
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if DEBUG
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define  D(x)   do { if (D_ACTIVE) ( printf x , fflush(stdout) ); } while (0)
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define  D(x)   do{}while(0)
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct ControlGlobalRec_*  ControlGlobal;
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct ControlClientRec_*  ControlClient;
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct {
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int           host_port;
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int           host_udp;
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned int  guest_ip;
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int           guest_port;
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} RedirRec, *Redir;
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
90e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turnertypedef int Socket;
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct ControlClientRec_
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct ControlClientRec_*  next;       /* next client in list           */
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Socket                     sock;       /* socket used for communication */
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ControlGlobal              global;
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char                       finished;
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char                       buff[ 4096 ];
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int                        buff_len;
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} ControlClientRec;
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct ControlGlobalRec_
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* listening socket */
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Socket    listen_fd;
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* the list of current clients */
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ControlClient   clients;
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* the list of redirections currently active */
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Redir     redirs;
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int       num_redirs;
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int       max_redirs;
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} ControlGlobalRec;
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
119e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine#ifdef CONFIG_STANDALONE_CORE
120d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine/* UI client currently attached to the core. */
121d87b080495e71ada650b165a1f06616b433e6073Vladimir ChtchetkineControlClient attached_ui_client = NULL;
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
123e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine/* Core framebuffer service client. */
124e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir ChtchetkineControlClient framebuffer_client = NULL;
1259411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine
1269411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine/* User events service client. */
1279411a562e1ab772732a4d5147c9103a638837c82Vladimir ChtchetkineControlClient user_events_client = NULL;
1289411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine
1299411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine/* User events service. */
1309411a562e1ab772732a4d5147c9103a638837c82Vladimir ChtchetkineCoreUserEvents* core_ue = NULL;
1316b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine
1326b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine/* UI control service client (UI -> Core). */
1336b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir ChtchetkineControlClient ui_core_ctl_client = NULL;
1346b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine
1356b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine/* UI control service (UI -> Core. */
1366b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine// CoreUICtl* ui_core_ctl = NULL;
1376b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine
1386b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine/* UI control service client (Core-> UI). */
1396b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir ChtchetkineControlClient core_ui_ctl_client = NULL;
1406b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine
1416b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine/* UI control service (Core -> UI. */
1426b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine// CoreUICtl* core_ui_ctl = NULL;
143e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine#endif  // CONFIG_STANDALONE_CORE
144e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine
14590c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkine/* -android-avdname option value. Defined in vl-android.c */
14690c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkineextern char* android_op_avd_name;
14790c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkine
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectcontrol_global_add_redir( ControlGlobal  global,
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          int            host_port,
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          int            host_udp,
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          unsigned int   guest_ip,
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          int            guest_port )
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Redir  redir;
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (global->num_redirs >= global->max_redirs)
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  old_max = global->max_redirs;
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  new_max = old_max + (old_max >> 1) + 4;
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        Redir  new_redirs = realloc( global->redirs, new_max*sizeof(global->redirs[0]) );
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (new_redirs == NULL)
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        global->redirs     = new_redirs;
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        global->max_redirs = new_max;
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    redir = &global->redirs[ global->num_redirs++ ];
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    redir->host_port  = host_port;
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    redir->host_udp   = host_udp;
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    redir->guest_ip   = guest_ip;
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    redir->guest_port = guest_port;
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectcontrol_global_del_redir( ControlGlobal  global,
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          int            host_port,
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          int            host_udp )
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  nn;
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = 0; nn < global->num_redirs; nn++)
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        Redir  redir = &global->redirs[nn];
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( redir->host_port == host_port &&
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             redir->host_udp  == host_udp  )
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            memmove( redir, redir + 1, ((global->num_redirs - nn)-1)*sizeof(*redir) );
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            global->num_redirs -= 1;
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we didn't find it */
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
203e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner/* Detach the socket descriptor from a given ControlClient
204e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner * and return its value. This is useful either when destroying
205e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner * the client, or redirecting the socket to another service.
206e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner *
207e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner * NOTE: this does not close the socket.
208e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner */
209e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turnerstatic int
210e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turnercontrol_client_detach( ControlClient  client )
211e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner{
212e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    int  result;
213e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner
214e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    if (client->sock < 0)
215e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner        return -1;
216e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner
217e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    qemu_set_fd_handler( client->sock, NULL, NULL, NULL );
218e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    result = client->sock;
219e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    client->sock = -1;
220e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner
221e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    return result;
222e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner}
223e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner
224e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turnerstatic void  control_client_read( void*  _client );  /* forward */
225e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner
226e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner/* Reattach a control client to a given socket.
227e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner * Return the old socket descriptor for the client.
228e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner */
229e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turnerstatic int
230e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turnercontrol_client_reattach( ControlClient client, int fd )
231e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner{
232e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    int result = control_client_detach(client);
233e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    client->sock = fd;
234e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    qemu_set_fd_handler( fd, control_client_read, NULL, client );
235e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    return result;
236e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner}
237e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectcontrol_client_destroy( ControlClient  client )
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ControlGlobal  global = client->global;
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ControlClient  *pnode = &global->clients;
243e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    int            sock;
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    D(( "destroying control client %p\n", client ));
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
247e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine#ifdef CONFIG_STANDALONE_CORE
248d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine    if (client == attached_ui_client) {
249d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine        attached_ui_client = NULL;
250d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine    }
251d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine
252e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    if (client == framebuffer_client) {
253e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        CoreFramebuffer* core_fb = coredisplay_detach_fb_service();
254e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        if (core_fb != NULL) {
255e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine            corefb_destroy(core_fb);
256e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine            AFREE(core_fb);
257e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        }
258e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        framebuffer_client = NULL;
259e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    }
2609411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine
2619411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine    if (client == user_events_client) {
2629411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine        coreue_destroy(core_ue);
2639411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine        user_events_client = NULL;
2649411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine    }
2656b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine
2666b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    if (client == ui_core_ctl_client) {
267777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine        coreCmdImpl_destroy();
2686b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        ui_core_ctl_client = NULL;
2696b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    }
2706b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine
2716b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    if (client == core_ui_ctl_client) {
272777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine        uiCmdProxy_destroy();
2736b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        core_ui_ctl_client = NULL;
2746b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    }
275e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine#endif  // CONFIG_STANDALONE_CORE
276e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine
277e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    sock = control_client_detach( client );
278e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    if (sock >= 0)
279e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner        socket_close(sock);
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for ( ;; ) {
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ControlClient  node = *pnode;
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( node == NULL )
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( node == client ) {
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *pnode     = node->next;
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            node->next = NULL;
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        pnode = &node->next;
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    free( client );
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void  control_control_write( ControlClient  client, const char*  buff, int  len )
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (len < 0)
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len = strlen(buff);
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (len > 0) {
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = socket_send( client->sock, buff, len);
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ret < 0) {
308ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner            if (errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN)
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return;
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            buff += ret;
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            len  -= ret;
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3172ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thijestatic int  control_vwrite( ControlClient  client, const char*  format, va_list args )
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static char  temp[1024];
3202ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    int ret = vsnprintf( temp, sizeof(temp), format, args );
3212ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    temp[ sizeof(temp)-1 ] = 0;
3222ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    control_control_write( client, temp, -1 );
3232ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
3242ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    return ret;
3252ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije}
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3272ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thijestatic int  control_write( ControlClient  client, const char*  format, ... )
3282ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije{
3292ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    int ret;
3302ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    va_list      args;
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_start(args, format);
3322ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    ret = control_vwrite(client, format, args);
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_end(args);
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3352ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    return ret;
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic ControlClient
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectcontrol_client_create( Socket         socket,
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       ControlGlobal  global )
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ControlClient  client = calloc( sizeof(*client), 1 );
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (client) {
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        socket_set_nodelay( socket );
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        socket_set_nonblock( socket );
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        client->finished = 0;
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        client->global  = global;
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        client->sock    = socket;
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        client->next    = global->clients;
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        global->clients = client;
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        qemu_set_fd_handler( socket, control_client_read, NULL, client );
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return client;
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef const struct CommandDefRec_  *CommandDef;
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct CommandDefRec_ {
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char*  names;
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char*  abstract;
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char*  description;
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    void        (*descriptor)( ControlClient  client );
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int         (*handler)( ControlClient  client, char* args );
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    CommandDef   subcommands;   /* if handler is NULL */
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} CommandDefRec;
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const CommandDefRec   main_commands[];  /* forward */
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic CommandDef
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfind_command( char*  input, CommandDef  commands, char*  *pend, char*  *pargs )
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int    nn;
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*  args = strchr(input, ' ');
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (args != NULL) {
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (*args == ' ')
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            args++;
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (args[0] == 0)
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            args = NULL;
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = 0; commands[nn].names != NULL; nn++)
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        const char*  name = commands[nn].names;
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        const char*  sep;
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        do {
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int  len, c;
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            sep = strchr( name, '|' );
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (sep)
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                len = sep - name;
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                len = strlen(name);
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            c = input[len];
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( !memcmp( name, input, len ) && (c == ' ' || c == 0) ) {
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                *pend  = input + len;
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                *pargs = args;
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return &commands[nn];
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (sep)
4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                name = sep + 1;
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } while (sep != NULL && *name);
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* NOTE: don't touch *pend and *pargs if no command is found */
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return NULL;
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdump_help( ControlClient  client,
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           CommandDef     cmd,
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           const char*    prefix )
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (cmd->description) {
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "%s", cmd->description );
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (cmd->descriptor) {
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cmd->descriptor( client );
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "%s\r\n", cmd->abstract );
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (cmd->subcommands) {
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cmd = cmd->subcommands;
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "\r\navailable sub-commands:\r\n" );
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for ( ; cmd->names != NULL; cmd++ ) {
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            control_write( client, "   %s %-15s  %s\r\n", prefix, cmd->names, cmd->abstract );
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "\r\n" );
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectcontrol_client_do_command( ControlClient  client )
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*       line     = client->buff;
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*       args     = NULL;
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    CommandDef  commands = main_commands;
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*       cmdend   = client->buff;
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    CommandDef  cmd      = find_command( line, commands, &cmdend, &args );
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (cmd == NULL) {
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: unknown command, try 'help'\r\n" );
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (;;) {
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        CommandDef  subcmd;
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (cmd->handler) {
457d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine            if ( !cmd->handler( client, args ) ) {
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                control_write( client, "OK\r\n" );
459d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine            }
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* no handler means we should have sub-commands */
4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (cmd->subcommands == NULL) {
4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            control_write( client, "KO: internal error: buggy command table for '%.*s'\r\n",
4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                           cmdend - client->buff, client->buff );
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* we need a sub-command here */
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( !args ) {
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dump_help( client, cmd, "" );
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            control_write( client, "KO: missing sub-command\r\n" );
4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        line     = args;
4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        commands = cmd->subcommands;
4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        subcmd   = find_command( line, commands, &cmdend, &args );
4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (subcmd == NULL) {
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dump_help( client, cmd, "" );
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            control_write( client, "KO:  bad sub-command\r\n" );
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cmd = subcmd;
4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* implement the 'help' command */
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_help( ControlClient  client, char*  args )
4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*       line;
4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*       start = args;
4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*       end   = start;
4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    CommandDef  cmd = main_commands;
4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* without arguments, simply dump all commands */
4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (args == NULL) {
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "Android console command help:\r\n\r\n" );
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for ( ; cmd->names != NULL; cmd++ ) {
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            control_write( client, "    %-15s  %s\r\n", cmd->names, cmd->abstract );
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "\r\ntry 'help <command>' for command-specific help\r\n" );
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* with an argument, find the corresponding command */
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (;;) {
5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        CommandDef  subcmd;
5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        line    = args;
5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        subcmd  = find_command( line, cmd, &end, &args );
5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (subcmd == NULL) {
5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            control_write( client, "try one of these instead:\r\n\r\n" );
5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for ( ; cmd->names != NULL; cmd++ ) {
5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                control_write( client, "    %.*s %s\r\n",
5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              end - start, start, cmd->names );
5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            control_write( client, "\r\nKO: unknown command\r\n" );
5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( !args || !subcmd->subcommands ) {
5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dump_help( client, subcmd, start );
5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cmd = subcmd->subcommands;
5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectcontrol_client_read_byte( ControlClient  client, unsigned char  ch )
5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ch == '\r')
5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* filter them out */
5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if (ch == '\n')
5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        client->buff[ client->buff_len ] = 0;
5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_client_do_command( client );
5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (client->finished)
5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return;
5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        client->buff_len = 0;
5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (client->buff_len >= sizeof(client->buff)-1)
5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            client->buff_len = 0;
5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        client->buff[ client->buff_len++ ] = ch;
5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectcontrol_client_read( void*  _client )
5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ControlClient  client = _client;
5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char  buf[4096];
5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int            size;
5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    D(( "in control_client read: " ));
5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    size = socket_recv( client->sock, buf, sizeof(buf) );
5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (size < 0) {
5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        D(( "size < 0, exiting with %d: %s\n", errno, errno_str ));
569d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine        if (errno != EWOULDBLOCK && errno != EAGAIN)
570d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine            control_client_destroy( client );
5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (size == 0) {
5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* end of connection */
5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        D(( "end of connection detected !!\n" ));
5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_client_destroy( client );
5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  nn;
5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  if DEBUG
5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char  temp[16];
5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int   count = size > sizeof(temp)-1 ? sizeof(temp)-1 : size;
5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (nn = 0; nn < count; nn++) {
5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  c = buf[nn];
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (c == '\n')
5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        temp[nn] = '!';
5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else if (c < 32)
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        temp[nn] = '.';
5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else
5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    temp[nn] = (char)c;
5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        temp[nn] = 0;
5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        D(( "received %d bytes: %s\n", size, temp ));
5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  endif
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        D(( "received %.*s\n", size, buf ));
5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (nn = 0; nn < size; nn++) {
6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            control_client_read_byte( client, buf[nn] );
6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (client->finished) {
6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                control_client_destroy(client);
6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return;
6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* this function is called on each new client connection */
6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectcontrol_global_accept( void*  _global )
6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ControlGlobal       global = _global;
6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ControlClient       client;
6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Socket              fd;
6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
61980bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner    D(( "control_global_accept: just in (fd=%d)\n", global->listen_fd ));
6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(;;) {
6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fd = socket_accept( global->listen_fd, NULL );
6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (fd < 0 && errno != EINTR) {
6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            D(( "problem in accept: %d: %s\n", errno, errno_str ));
6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            perror("accept");
6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return;
6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else if (fd >= 0) {
6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        D(( "relooping in accept()\n" ));
6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socket_set_xreuseaddr( fd );
6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    D(( "control_global_accept: creating new client\n" ));
6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    client = control_client_create( fd, global );
6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (client) {
6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        D(( "control_global_accept: new client %p\n", client ));
6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "Android Console: type 'help' for a list of commands\r\n" );
6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "OK\r\n" );
6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectcontrol_global_init( ControlGlobal  global,
6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     int            control_port )
6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Socket  fd;
6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int     ret;
6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SockAddress  sockaddr;
6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset( global, 0, sizeof(*global) );
6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fd = socket_create_inet( SOCKET_STREAM );
6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (fd < 0) {
6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        perror("socket");
6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socket_set_xreuseaddr( fd );
6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sock_address_init_inet( &sockaddr, SOCK_ADDRESS_INET_LOOPBACK, control_port );
6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = socket_bind(fd, &sockaddr );
6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0) {
6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        perror("bind");
6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        socket_close( fd );
6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = socket_listen(fd, 0);
6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0) {
6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        perror("listen");
6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        socket_close( fd );
6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socket_set_nonblock(fd);
6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    global->listen_fd = fd;
6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    qemu_set_fd_handler( fd, control_global_accept, NULL, global );
6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_quit( ControlClient  client, char*  args )
6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    client->finished = 1;
6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                        N E T W O R K   S E T T I N G S                          ******/
7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_network_status( ControlClient  client, char*  args )
7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "Current network status:\r\n" );
7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "  download speed:   %8d bits/s (%.1f KB/s)\r\n",
7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   (long)qemu_net_download_speed, qemu_net_download_speed/8192. );
7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "  upload speed:     %8d bits/s (%.1f KB/s)\r\n",
7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   (long)qemu_net_upload_speed, qemu_net_upload_speed/8192. );
7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "  minimum latency:  %ld ms\r\n", qemu_net_min_latency );
7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "  maximum latency:  %ld ms\r\n", qemu_net_max_latency );
7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdump_network_speeds( ControlClient  client )
7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const NetworkSpeed*  speed = android_netspeeds;
7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char* const  format = "  %-8s %s\r\n";
7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for ( ; speed->name; speed++ ) {
7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, format, speed->name, speed->display );
7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, format, "<num>", "selects both upload and download speed" );
7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, format, "<up>:<down>", "select individual upload/download speeds" );
7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_network_speed( ControlClient  client, char*  args )
7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( !args ) {
7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: missing <speed> argument, see 'help network speed'\r\n" );
7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( android_parse_network_speed( args ) < 0 ) {
7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: invalid <speed> argument, see 'help network speed' for valid values\r\n" );
7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    netshaper_set_rate( slirp_shaper_in,  qemu_net_download_speed );
7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    netshaper_set_rate( slirp_shaper_out, qemu_net_upload_speed );
7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (android_modem) {
74971bb14f826775867d16e7d382cfdc48e6ca46ccbVladimir Chtchetkine        amodem_set_data_network_type( android_modem,
7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    android_parse_network_type( args ) );
7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdescribe_network_speed( ControlClient  client )
7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client,
7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   "'network speed <speed>' allows you to dynamically change the speed of the emulated\r\n"
7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   "network on the device, where <speed> is one of the following:\r\n\r\n" );
7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dump_network_speeds( client );
7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_network_delay( ControlClient  client, char*  args )
7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( !args ) {
7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: missing <delay> argument, see 'help network delay'\r\n" );
7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( android_parse_network_latency( args ) < 0 ) {
7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: invalid <delay> argument, see 'help network delay' for valid values\r\n" );
7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    netdelay_set_latency( slirp_delay_in, qemu_net_min_latency, qemu_net_max_latency );
7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdescribe_network_delay( ControlClient  client )
7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client,
7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   "'network delay <latency>' allows you to dynamically change the latency of the emulated\r\n"
7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   "network on the device, where <latency> is one of the following:\r\n\r\n" );
7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: TODO */
7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_network_capture_start( ControlClient  client, char*  args )
7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( !args ) {
7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: missing <file> argument, see 'help network capture start'\r\n" );
7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( qemu_tcpdump_start(args) < 0) {
7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: could not start capture: %s", strerror(errno) );
7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_network_capture_stop( ControlClient  client, char*  args )
8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* no need to return an error here */
8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    qemu_tcpdump_stop();
8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const CommandDefRec  network_capture_commands[] =
8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "start", "start network capture",
8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      "'network capture start <file>' starts a new capture of network packets\r\n"
8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      "into a specific <file>. This will stop any capture already in progress.\r\n"
8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      "the capture file can later be analyzed by tools like WireShark. It uses\r\n"
8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      "the libpcap file format.\r\n\r\n"
8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      "you can stop the capture anytime with 'network capture stop'\r\n", NULL,
8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      do_network_capture_start, NULL },
8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "stop", "stop network capture",
8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      "'network capture stop' stops a currently running packet capture, if any.\r\n"
8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      "you can start one with 'network capture start <file>'\r\n", NULL,
8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      do_network_capture_stop, NULL },
8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { NULL, NULL, NULL, NULL, NULL, NULL }
8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const CommandDefRec  network_commands[] =
8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "status", "dump network status", NULL, NULL,
8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       do_network_status, NULL },
8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "speed", "change network speed", NULL, describe_network_speed,
8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      do_network_speed, NULL },
8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "delay", "change network latency", NULL, describe_network_delay,
8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       do_network_delay, NULL },
8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "capture", "dump network packets to file",
8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      "allows to start/stop capture of network packets to a file for later analysis\r\n", NULL,
8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      NULL, network_capture_commands },
8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { NULL, NULL, NULL, NULL, NULL, NULL }
8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                       P O R T   R E D I R E C T I O N S                         ******/
8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_redir_list( ControlClient  client, char*  args )
8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ControlGlobal  global = client->global;
8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (global->num_redirs == 0)
8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "no active redirections\r\n" );
8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  nn;
8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (nn = 0; nn < global->num_redirs; nn++) {
8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            Redir  redir = &global->redirs[nn];
8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            control_write( client, "%s:%-5d => %-5d\r\n",
8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          redir->host_udp ? "udp" : "tcp",
8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          redir->host_port,
8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          redir->guest_port );
8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* parse a protocol:port specification */
8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectredir_parse_proto_port( char*  args, int  *pport, int  *pproto )
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  proto = -1;
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  len   = 0;
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*  end;
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( !memcmp( args, "tcp:", 4 ) ) {
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        proto = 0;
8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len   = 4;
8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if ( !memcmp( args, "udp:", 4 ) ) {
8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        proto = 1;
8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len   = 4;
8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    args   += len;
8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *pproto = proto;
8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *pport  = strtol( args, &end, 10 );
8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (end == args)
8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    len += end - args;
9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return len;
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectredir_parse_guest_port( char*  arg, int  *pport )
9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*  end;
9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *pport = strtoul( arg, &end, 10 );
9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (end == arg)
9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return end - arg;
9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic Redir
9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectredir_find( ControlGlobal  global, int  port, int  isudp )
9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  nn;
9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = 0; nn < global->num_redirs; nn++) {
9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        Redir  redir = &global->redirs[nn];
9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (redir->host_port == port && redir->host_udp == isudp)
9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return redir;
9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return NULL;
9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_redir_add( ControlClient  client, char*  args )
9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int       len, host_proto, host_port, guest_port;
9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t  guest_ip;
9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Redir     redir;
9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( !args )
9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto BadFormat;
9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!slirp_is_inited()) {
9415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        control_write( client, "KO: network emulation disabled\r\n");
9425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    len = redir_parse_proto_port( args, &host_port, &host_proto );
9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (len == 0 || args[len] != ':')
9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto BadFormat;
9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    args += len + 1;
9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    len = redir_parse_guest_port( args, &guest_port );
9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (len == 0 || args[len] != 0)
9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto BadFormat;
9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    redir = redir_find( client->global, host_port, host_proto );
9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( redir != NULL ) {
9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: host port already active, use 'redir del' to remove first\r\n" );
9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9607d9a2705e7ae6d8c4b1d9d5b4e2a67ab88c19044David Turner    if (inet_strtoip("10.0.2.15", &guest_ip) < 0) {
9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: unexpected internal failure when resolving 10.0.2.15\r\n" );
9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    D(("pattern hport=%d gport=%d proto=%d\n", host_port, guest_port, host_proto ));
9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( control_global_add_redir( client->global, host_port, host_proto,
9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                   guest_ip, guest_port ) < 0 )
9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: not enough memory to allocate redirection\r\n" );
9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (slirp_redir(host_proto, host_port, guest_ip, guest_port) < 0) {
9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: can't setup redirection, port probably used by another program on host\r\n" );
9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_global_del_redir( client->global, host_port, host_proto );
9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectBadFormat:
9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "KO: bad redirection format, try (tcp|udp):hostport:guestport\r\n", -1 );
9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_redir_del( ControlClient  client, char*  args )
9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int    len, proto, port;
9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Redir  redir;
9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( !args )
9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto BadFormat;
9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    len = redir_parse_proto_port( args, &port, &proto );
9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( len == 0 || args[len] != 0 )
9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto BadFormat;
9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    redir = redir_find( client->global, port, proto );
10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (redir == NULL) {
10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: can't remove unknown redirection (%s:%d)\r\n",
10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        proto ? "udp" : "tcp", port );
10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    slirp_unredir( redir->host_udp, redir->host_port );
10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_global_del_redir( client->global, port, proto );\
10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectBadFormat:
10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "KO: bad redirection format, try (tcp|udp):hostport\r\n" );
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const CommandDefRec  redir_commands[] =
10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "list", "list current redirections",
10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "list current port redirections. use 'redir add' and 'redir del' to add and remove them\r\n", NULL,
10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_redir_list, NULL },
10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "add",  "add new redirection",
10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "add a new port redirection, arguments must be:\r\n\r\n"
10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            "  redir add <protocol>:<host-port>:<guest-port>\r\n\r\n"
10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            "where:   <protocol>     is either 'tcp' or 'udp'\r\n"
10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            "         <host-port>    a number indicating which port on the host to open\r\n"
10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            "         <guest-port>   a number indicating which port to route to on the device\r\n"
10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            "\r\nas an example, 'redir  tcp:5000:6000' will allow any packets sent to\r\n"
10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            "the host's TCP port 5000 to be routed to TCP port 6000 of the emulated device\r\n", NULL,
10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_redir_add, NULL },
10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "del",  "remove existing redirection",
10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "remove a port redirecion that was created with 'redir add', arguments must be:\r\n\r\n"
10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            "  redir  del <protocol>:<host-port>\r\n\r\n"
10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            "see the 'help redir add' for the meaning of <protocol> and <host-port>\r\n", NULL,
10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_redir_del, NULL },
10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { NULL, NULL, NULL, NULL, NULL, NULL }
10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
10461a000857bb7eef298efa787699050884f92311feJaime Lopez/*****                          C D M A   M O D E M                                    ******/
10471a000857bb7eef298efa787699050884f92311feJaime Lopez/*****                                                                                 ******/
10481a000857bb7eef298efa787699050884f92311feJaime Lopez/********************************************************************************************/
10491a000857bb7eef298efa787699050884f92311feJaime Lopez/********************************************************************************************/
10501a000857bb7eef298efa787699050884f92311feJaime Lopez
10511a000857bb7eef298efa787699050884f92311feJaime Lopezstatic const struct {
10521a000857bb7eef298efa787699050884f92311feJaime Lopez    const char *            name;
10531a000857bb7eef298efa787699050884f92311feJaime Lopez    const char *            display;
10541a000857bb7eef298efa787699050884f92311feJaime Lopez    ACdmaSubscriptionSource source;
10551a000857bb7eef298efa787699050884f92311feJaime Lopez} _cdma_subscription_sources[] = {
10561a000857bb7eef298efa787699050884f92311feJaime Lopez    { "nv",            "Read subscription from non-volatile RAM", A_SUBSCRIPTION_NVRAM },
10571a000857bb7eef298efa787699050884f92311feJaime Lopez    { "ruim",          "Read subscription from RUIM", A_SUBSCRIPTION_RUIM },
10581a000857bb7eef298efa787699050884f92311feJaime Lopez};
10591a000857bb7eef298efa787699050884f92311feJaime Lopez
10601a000857bb7eef298efa787699050884f92311feJaime Lopezstatic void
10611a000857bb7eef298efa787699050884f92311feJaime Lopezdump_subscription_sources( ControlClient client )
10621a000857bb7eef298efa787699050884f92311feJaime Lopez{
10631a000857bb7eef298efa787699050884f92311feJaime Lopez    int i;
10641a000857bb7eef298efa787699050884f92311feJaime Lopez    for (i = 0;
10651a000857bb7eef298efa787699050884f92311feJaime Lopez         i < sizeof(_cdma_subscription_sources) / sizeof(_cdma_subscription_sources[0]);
10661a000857bb7eef298efa787699050884f92311feJaime Lopez         i++) {
10671a000857bb7eef298efa787699050884f92311feJaime Lopez        control_write( client, "    %s: %s\r\n",
10681a000857bb7eef298efa787699050884f92311feJaime Lopez                       _cdma_subscription_sources[i].name,
10691a000857bb7eef298efa787699050884f92311feJaime Lopez                       _cdma_subscription_sources[i].display );
10701a000857bb7eef298efa787699050884f92311feJaime Lopez    }
10711a000857bb7eef298efa787699050884f92311feJaime Lopez}
10721a000857bb7eef298efa787699050884f92311feJaime Lopez
10731a000857bb7eef298efa787699050884f92311feJaime Lopezstatic void
10741a000857bb7eef298efa787699050884f92311feJaime Lopezdescribe_subscription_source( ControlClient client )
10751a000857bb7eef298efa787699050884f92311feJaime Lopez{
10761a000857bb7eef298efa787699050884f92311feJaime Lopez    control_write( client,
10771a000857bb7eef298efa787699050884f92311feJaime Lopez                   "'cdma ssource <ssource>' allows you to specify where to read the subscription from\r\n" );
10781a000857bb7eef298efa787699050884f92311feJaime Lopez    dump_subscription_sources( client );
10791a000857bb7eef298efa787699050884f92311feJaime Lopez}
10801a000857bb7eef298efa787699050884f92311feJaime Lopez
10811a000857bb7eef298efa787699050884f92311feJaime Lopezstatic int
10821a000857bb7eef298efa787699050884f92311feJaime Lopezdo_cdma_ssource( ControlClient  client, char*  args )
10831a000857bb7eef298efa787699050884f92311feJaime Lopez{
10841a000857bb7eef298efa787699050884f92311feJaime Lopez    int nn;
10851a000857bb7eef298efa787699050884f92311feJaime Lopez    if (!args) {
10861a000857bb7eef298efa787699050884f92311feJaime Lopez        control_write( client, "KO: missing argument, try 'cdma ssource <source>'\r\n" );
10871a000857bb7eef298efa787699050884f92311feJaime Lopez        return -1;
10881a000857bb7eef298efa787699050884f92311feJaime Lopez    }
10891a000857bb7eef298efa787699050884f92311feJaime Lopez
10901a000857bb7eef298efa787699050884f92311feJaime Lopez    for (nn = 0; ; nn++) {
10911a000857bb7eef298efa787699050884f92311feJaime Lopez        const char*         name    = _cdma_subscription_sources[nn].name;
10921a000857bb7eef298efa787699050884f92311feJaime Lopez        ACdmaSubscriptionSource ssource = _cdma_subscription_sources[nn].source;
10931a000857bb7eef298efa787699050884f92311feJaime Lopez
10941a000857bb7eef298efa787699050884f92311feJaime Lopez        if (!name)
10951a000857bb7eef298efa787699050884f92311feJaime Lopez            break;
10961a000857bb7eef298efa787699050884f92311feJaime Lopez
10971a000857bb7eef298efa787699050884f92311feJaime Lopez        if (!strcasecmp( args, name )) {
10981a000857bb7eef298efa787699050884f92311feJaime Lopez            amodem_set_cdma_subscription_source( android_modem, ssource );
10991a000857bb7eef298efa787699050884f92311feJaime Lopez            return 0;
11001a000857bb7eef298efa787699050884f92311feJaime Lopez        }
11011a000857bb7eef298efa787699050884f92311feJaime Lopez    }
11021a000857bb7eef298efa787699050884f92311feJaime Lopez    control_write( client, "KO: Don't know source %s\r\n", args );
11031a000857bb7eef298efa787699050884f92311feJaime Lopez    return -1;
11041a000857bb7eef298efa787699050884f92311feJaime Lopez}
11051a000857bb7eef298efa787699050884f92311feJaime Lopez
11061a000857bb7eef298efa787699050884f92311feJaime Lopezstatic int
11071a000857bb7eef298efa787699050884f92311feJaime Lopezdo_cdma_prl_version( ControlClient client, char * args )
11081a000857bb7eef298efa787699050884f92311feJaime Lopez{
11091a000857bb7eef298efa787699050884f92311feJaime Lopez    int version = 0;
11101a000857bb7eef298efa787699050884f92311feJaime Lopez    char *endptr;
11111a000857bb7eef298efa787699050884f92311feJaime Lopez
11121a000857bb7eef298efa787699050884f92311feJaime Lopez    if (!args) {
11131a000857bb7eef298efa787699050884f92311feJaime Lopez        control_write( client, "KO: missing argument, try 'cdma prl_version <version>'\r\n");
11141a000857bb7eef298efa787699050884f92311feJaime Lopez        return -1;
11151a000857bb7eef298efa787699050884f92311feJaime Lopez    }
11161a000857bb7eef298efa787699050884f92311feJaime Lopez
11171a000857bb7eef298efa787699050884f92311feJaime Lopez    version = strtol(args, &endptr, 0);
11181a000857bb7eef298efa787699050884f92311feJaime Lopez    if (endptr != args) {
11191a000857bb7eef298efa787699050884f92311feJaime Lopez        amodem_set_cdma_prl_version( android_modem, version );
11201a000857bb7eef298efa787699050884f92311feJaime Lopez    }
112180bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner    return 0;
11221a000857bb7eef298efa787699050884f92311feJaime Lopez}
11231a000857bb7eef298efa787699050884f92311feJaime Lopez/********************************************************************************************/
11241a000857bb7eef298efa787699050884f92311feJaime Lopez/********************************************************************************************/
11251a000857bb7eef298efa787699050884f92311feJaime Lopez/*****                                                                                 ******/
11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                           G S M   M O D E M                                     ******/
11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const struct {
11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char*         name;
11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char*         display;
11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ARegistrationState  state;
11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} _gsm_states[] = {
11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "unregistered",  "no network available", A_REGISTRATION_UNREGISTERED },
11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "home",          "on local network, non-roaming", A_REGISTRATION_HOME },
11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "roaming",       "on roaming network", A_REGISTRATION_ROAMING },
11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "searching",     "searching networks", A_REGISTRATION_SEARCHING },
11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "denied",        "emergency calls only", A_REGISTRATION_DENIED },
11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "off",           "same as 'unregistered'", A_REGISTRATION_UNREGISTERED },
11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "on",            "same as 'home'", A_REGISTRATION_HOME },
11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { NULL, NULL, A_REGISTRATION_UNREGISTERED }
11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const char*
11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectgsm_state_to_string( ARegistrationState  state )
11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  nn;
11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = 0; _gsm_states[nn].name != NULL; nn++) {
11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (state == _gsm_states[nn].state)
11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return _gsm_states[nn].name;
11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return "<unknown>";
11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_gsm_status( ControlClient  client, char*  args )
11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (args) {
11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: no argument required\r\n" );
11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!android_modem) {
11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: modem emulation not running\r\n" );
11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "gsm voice state: %s\r\n",
11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   gsm_state_to_string(
11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       amodem_get_voice_registration(android_modem) ) );
11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "gsm data state:  %s\r\n",
11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   gsm_state_to_string(
11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       amodem_get_data_registration(android_modem) ) );
11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecthelp_gsm_data( ControlClient  client )
11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  nn;
11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client,
11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            "the 'gsm data <state>' allows you to change the state of your GPRS connection\r\n"
11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            "valid values for <state> are the following:\r\n\r\n" );
11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = 0; ; nn++) {
11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        const char*         name    = _gsm_states[nn].name;
11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        const char*         display = _gsm_states[nn].display;
11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!name)
11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "  %-15s %s\r\n", name, display );
11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "\r\n" );
11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_gsm_data( ControlClient  client, char*  args )
12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  nn;
12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!args) {
12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: missing argument, try 'gsm data <state>'\r\n" );
12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = 0; ; nn++) {
12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        const char*         name    = _gsm_states[nn].name;
12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ARegistrationState  state   = _gsm_states[nn].state;
12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!name)
12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( !strcmp( args, name ) ) {
12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!android_modem) {
12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                control_write( client, "KO: modem emulation not running\r\n" );
12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return -1;
12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            amodem_set_data_registration( android_modem, state );
12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            qemu_net_disable = (state != A_REGISTRATION_HOME    &&
12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                state != A_REGISTRATION_ROAMING );
12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "KO: bad GSM data state name, try 'help gsm data' for list of valid values\r\n" );
12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecthelp_gsm_voice( ControlClient  client )
12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  nn;
12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client,
12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            "the 'gsm voice <state>' allows you to change the state of your GPRS connection\r\n"
12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            "valid values for <state> are the following:\r\n\r\n" );
12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = 0; ; nn++) {
12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        const char*         name    = _gsm_states[nn].name;
12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        const char*         display = _gsm_states[nn].display;
12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!name)
12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "  %-15s %s\r\n", name, display );
12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "\r\n" );
12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_gsm_voice( ControlClient  client, char*  args )
12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  nn;
12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!args) {
12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: missing argument, try 'gsm voice <state>'\r\n" );
12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = 0; ; nn++) {
12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        const char*         name    = _gsm_states[nn].name;
12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ARegistrationState  state   = _gsm_states[nn].state;
12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!name)
12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( !strcmp( args, name ) ) {
12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!android_modem) {
12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                control_write( client, "KO: modem emulation not running\r\n" );
12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return -1;
12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            amodem_set_voice_registration( android_modem, state );
12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "KO: bad GSM data state name, try 'help gsm voice' for list of valid values\r\n" );
12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectgsm_check_number( char*  args )
12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  nn;
12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = 0; args[nn] != 0; nn++) {
12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  c = args[nn];
12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( !isdigit(c) && c != '+' && c != '#' ) {
12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (nn == 0)
12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_gsm_call( ControlClient  client, char*  args )
13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* check that we have a phone number made of digits */
13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!args) {
13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: missing argument, try 'gsm call <phonenumber>'\r\n" );
13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (gsm_check_number(args)) {
13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: bad phone number format, use digits, # and + only\r\n" );
13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!android_modem) {
13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: modem emulation not running\r\n" );
13148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    amodem_add_inbound_call( android_modem, args );
13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_gsm_cancel( ControlClient  client, char*  args )
13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!args) {
13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: missing argument, try 'gsm call <phonenumber>'\r\n" );
13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (gsm_check_number(args)) {
13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: bad phone number format, use digits, # and + only\r\n" );
13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!android_modem) {
13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: modem emulation not running\r\n" );
13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( amodem_disconnect_call( android_modem, args ) < 0 ) {
13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: could not cancel this number\r\n" );
13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const char*
13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectcall_state_to_string( ACallState  state )
13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (state) {
13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case A_CALL_ACTIVE:   return "active";
13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case A_CALL_HELD:     return "held";
13498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case A_CALL_ALERTING: return "ringing";
13508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case A_CALL_WAITING:  return "waiting";
13518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case A_CALL_INCOMING: return "incoming";
13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default: return "unknown";
13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_gsm_list( ControlClient  client, char*  args )
13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* check that we have a phone number made of digits */
13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   count = amodem_get_call_count( android_modem );
13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   nn;
13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = 0; nn < count; nn++) {
13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ACall        call = amodem_get_call( android_modem, nn );
13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        const char*  dir;
13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (call == NULL)
13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            continue;
13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (call->dir == A_CALL_OUTBOUND)
13708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dir = "outbound to ";
13718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else
13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dir = "inbound from";
13738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "%s %-10s : %s\r\n", dir,
13758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       call->number, call_state_to_string(call->state) );
13768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
13788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
13818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_gsm_busy( ControlClient  client, char*  args )
13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ACall  call;
13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!args) {
13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: missing argument, try 'gsm busy <phonenumber>'\r\n" );
13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    call = amodem_find_call_by_number( android_modem, args );
13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (call == NULL || call->dir != A_CALL_OUTBOUND) {
13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: no current outbound call to number '%s' (call %p)\r\n", args, call );
13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( amodem_disconnect_call( android_modem, args ) < 0 ) {
13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: could not cancel this number\r\n" );
13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_gsm_hold( ControlClient  client, char*  args )
14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ACall  call;
14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!args) {
14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: missing argument, try 'gsm out hold <phonenumber>'\r\n" );
14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
14098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    call = amodem_find_call_by_number( android_modem, args );
14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (call == NULL) {
14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: no current call to/from number '%s'\r\n", args );
14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( amodem_update_call( android_modem, args, A_CALL_HELD ) < 0 ) {
14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: could put this call on hold\r\n" );
14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
14188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_gsm_accept( ControlClient  client, char*  args )
14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ACall  call;
14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!args) {
14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: missing argument, try 'gsm accept <phonenumber>'\r\n" );
14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    call = amodem_find_call_by_number( android_modem, args );
14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (call == NULL) {
14348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: no current call to/from number '%s'\r\n", args );
14358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
14368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( amodem_update_call( android_modem, args, A_CALL_ACTIVE ) < 0 ) {
14388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: could not activate this call\r\n" );
14398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
14428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14444c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstockstatic int
14454c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstockdo_gsm_signal( ControlClient  client, char*  args )
14464c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock{
14474c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      enum { SIGNAL_RSSI = 0, SIGNAL_BER, NUM_SIGNAL_PARAMS };
14484c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      char*   p = args;
14494c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      int     top_param = -1;
14504c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      int     params[ NUM_SIGNAL_PARAMS ];
14514c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock
14524c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      static  int  last_ber = 99;
14534c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock
14544c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      if (!p)
14554c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock          p = "";
14564c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock
14574c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      /* tokenize */
14584c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      while (*p) {
14594c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock          char*   end;
14604c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock          int  val = strtol( p, &end, 10 );
14614c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock
14624c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock          if (end == p) {
14634c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock              control_write( client, "KO: argument '%s' is not a number\n", p );
14644c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock              return -1;
14654c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock          }
14664c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock
14674c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock          params[++top_param] = val;
14684c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock          if (top_param + 1 == NUM_SIGNAL_PARAMS)
14694c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock              break;
14704c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock
14714c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock          p = end;
14724c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock          while (*p && (p[0] == ' ' || p[0] == '\t'))
14734c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock              p += 1;
14744c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      }
14754c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock
14764c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      /* sanity check */
14774c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      if (top_param < SIGNAL_RSSI) {
14784c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock          control_write( client, "KO: not enough arguments: see 'help gsm signal' for details\r\n" );
14794c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock          return -1;
14804c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      }
14814c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock
14824c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      int rssi = params[SIGNAL_RSSI];
14834c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      if ((rssi < 0 || rssi > 31) && rssi != 99) {
14844c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock          control_write( client, "KO: invalid RSSI - must be 0..31 or 99\r\n");
14854c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock          return -1;
14864c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      }
14874c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock
14884c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      /* check ber is 0..7 or 99 */
14894c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      if (top_param >= SIGNAL_BER) {
14904c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock          int ber = params[SIGNAL_BER];
14914c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock          if ((ber < 0 || ber > 7) && ber != 99) {
14924c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock              control_write( client, "KO: invalid BER - must be 0..7 or 99\r\n");
14934c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock              return -1;
14944c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock          }
14954c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock          last_ber = ber;
14964c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      }
14974c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock
14984c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      amodem_set_signal_strength( android_modem, rssi, last_ber );
14994c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock
15004c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock      return 0;
15014c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock  }
15024c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock
15038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
15058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const CommandDefRec  gsm_in_commands[] =
15068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "new", "create a new 'waiting' inbound call",
15088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'gsm in create <phonenumber>' creates a new inbound phone call, placed in\r\n"
15098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "the 'waiting' state by default, until the system answers/holds/closes it\r\n", NULL
15108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_gsm_in_create, NULL },
15118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "hold", "change the state of an oubtound call to 'held'",
15138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "change the state of an outbound call to 'held'. this is only possible\r\n"
15148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "if the call in the 'waiting' or 'active' state\r\n", NULL,
15158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_gsm_out_hold, NULL },
15168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "accept", "change the state of an outbound call to 'active'",
15188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "change the state of an outbound call to 'active'. this is only possible\r\n"
15198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "if the call is in the 'waiting' or 'held' state\r\n", NULL,
15208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_gsm_out_accept, NULL },
15218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { NULL, NULL, NULL, NULL, NULL, NULL }
15238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
15248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
15258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15271a000857bb7eef298efa787699050884f92311feJaime Lopezstatic const CommandDefRec  cdma_commands[] =
15281a000857bb7eef298efa787699050884f92311feJaime Lopez{
15291a000857bb7eef298efa787699050884f92311feJaime Lopez    { "ssource", "Set the current CDMA subscription source",
15301a000857bb7eef298efa787699050884f92311feJaime Lopez      NULL, describe_subscription_source,
15311a000857bb7eef298efa787699050884f92311feJaime Lopez      do_cdma_ssource, NULL },
153280bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner    { "prl_version", "Dump the current PRL version",
153380bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner      NULL, NULL,
153480bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner      do_cdma_prl_version, NULL },
15351a000857bb7eef298efa787699050884f92311feJaime Lopez};
15361a000857bb7eef298efa787699050884f92311feJaime Lopez
15378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const CommandDefRec  gsm_commands[] =
15388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "list", "list current phone calls",
15408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'gsm list' lists all inbound and outbound calls and their state\r\n", NULL,
15418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_gsm_list, NULL },
15428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "call", "create inbound phone call",
15448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'gsm call <phonenumber>' allows you to simulate a new inbound call\r\n", NULL,
15458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_gsm_call, NULL },
15468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "busy", "close waiting outbound call as busy",
15488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'gsm busy <remoteNumber>' closes an outbound call, reporting\r\n"
15498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "the remote phone as busy. only possible if the call is 'waiting'.\r\n", NULL,
15508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_gsm_busy, NULL },
15518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "hold", "change the state of an oubtound call to 'held'",
15538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'gsm hold <remoteNumber>' change the state of a call to 'held'. this is only possible\r\n"
15548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "if the call in the 'waiting' or 'active' state\r\n", NULL,
15558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_gsm_hold, NULL },
15568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "accept", "change the state of an outbound call to 'active'",
15588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'gsm accept <remoteNumber>' change the state of a call to 'active'. this is only possible\r\n"
15598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "if the call is in the 'waiting' or 'held' state\r\n", NULL,
15608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_gsm_accept, NULL },
15618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "cancel", "disconnect an inbound or outbound phone call",
15638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'gsm cancel <phonenumber>' allows you to simulate the end of an inbound or outbound call\r\n", NULL,
15648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_gsm_cancel, NULL },
15658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "data", "modify data connection state", NULL, help_gsm_data,
15678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_gsm_data, NULL },
15688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "voice", "modify voice connection state", NULL, help_gsm_voice,
15708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_gsm_voice, NULL },
15718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "status", "display GSM status",
15738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'gsm status' displays the current state of the GSM emulation\r\n", NULL,
15748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_gsm_status, NULL },
15758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15764c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock    { "signal", "set sets the rssi and ber",
15774c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock    "'gsm signal <rssi> [<ber>]' changes the reported strength and error rate on next (15s) update.\r\n"
15784c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock    "rssi range is 0..31 and 99 for unknown\r\n"
15794c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock    "ber range is 0..7 percent and 99 for unknown\r\n",
15804c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock    NULL, do_gsm_signal, NULL },
15814c6b10a4f385c04dbd7226e10a86a1f5cbd34f2aTim Baverstock
15828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { NULL, NULL, NULL, NULL, NULL, NULL }
15838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
15848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
15868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
15878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
15888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                           S M S   C O M M A N D                                 ******/
15898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
15908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
15918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
15928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
15948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_sms_send( ControlClient  client, char*  args )
15958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*          p;
15978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int            textlen;
15988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SmsAddressRec  sender;
15998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SmsPDU*        pdus;
16008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int            nn;
16018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* check that we have a phone number made of digits */
16038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!args) {
16048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    MissingArgument:
16058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: missing argument, try 'sms send <phonenumber> <text message>'\r\n" );
16068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
16078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p = strchr( args, ' ' );
16098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!p) {
16108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto MissingArgument;
16118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( sms_address_from_str( &sender, args, p - args ) < 0 ) {
16148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: bad phone number format, must be [+](0-9)*\r\n" );
16158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
16168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* un-secape message text into proper utf-8 (conversion happens in-site) */
16208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p      += 1;
16218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    textlen = strlen(p);
16228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    textlen = sms_utf8_from_message_str( p, textlen, (unsigned char*)p, textlen );
16238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (textlen < 0) {
16248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "message must be utf8 and can use the following escapes:\r\n"
16258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       "    \\n      for a newline\r\n"
16268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       "    \\xNN    where NN are two hexadecimal numbers\r\n"
16278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       "    \\uNNNN  where NNNN are four hexadecimal numbers\r\n"
16288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       "    \\\\     to send a '\\' character\r\n\r\n"
16298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       "    anything else is an error\r\n"
16308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       "KO: badly formatted text\r\n" );
16318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
16328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!android_modem) {
16358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: modem emulation not running\r\n" );
16368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
16378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* create a list of SMS PDUs, then send them */
16408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pdus = smspdu_create_deliver_utf8( (cbytes_t)p, textlen, &sender, NULL );
16418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (pdus == NULL) {
16428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: internal error when creating SMS-DELIVER PDUs\n" );
16438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
16448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = 0; pdus[nn] != NULL; nn++)
16478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        amodem_receive_sms( android_modem, pdus[nn] );
16488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    smspdu_free_list( pdus );
16508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
16518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
16548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_sms_sendpdu( ControlClient  client, char*  args )
16558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SmsPDU  pdu;
16578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* check that we have a phone number made of digits */
16598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!args) {
16608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: missing argument, try 'sms sendpdu <hexstring>'\r\n" );
16618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
16628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!android_modem) {
16658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: modem emulation not running\r\n" );
16668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
16678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pdu = smspdu_create_from_hex( args, strlen(args) );
16708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (pdu == NULL) {
16718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: badly formatted <hexstring>\r\n" );
16728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
16738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    amodem_receive_sms( android_modem, pdu );
16768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    smspdu_free( pdu );
16778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
16788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const CommandDefRec  sms_commands[] =
16818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "send", "send inbound SMS text message",
16838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'sms send <phonenumber> <message>' allows you to simulate a new inbound sms message\r\n", NULL,
16848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_sms_send, NULL },
16858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "pdu", "send inbound SMS PDU",
16878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'sms pdu <hexstring>' allows you to simulate a new inbound sms PDU\r\n"
16888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "(used internally when one emulator sends SMS messages to another instance).\r\n"
16898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "you probably don't want to play with this at all\r\n", NULL,
16908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_sms_sendpdu, NULL },
16918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { NULL, NULL, NULL, NULL, NULL, NULL }
16938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
16948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
16968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_control_write(void* data, const char* string)
16978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write((ControlClient)data, string);
16998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
17028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_power_display( ControlClient client, char*  args )
17038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
17048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    goldfish_battery_display(do_control_write, client);
17058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
17068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
17098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_ac_state( ControlClient  client, char*  args )
17108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
17118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (args) {
17128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (strcasecmp(args, "on") == 0) {
17138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goldfish_battery_set_prop(1, POWER_SUPPLY_PROP_ONLINE, 1);
17148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
17158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (strcasecmp(args, "off") == 0) {
17178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goldfish_battery_set_prop(1, POWER_SUPPLY_PROP_ONLINE, 0);
17188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
17198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "KO: Usage: \"ac on\" or \"ac off\"\n" );
17238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
17248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
17278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_battery_status( ControlClient  client, char*  args )
17288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
17298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (args) {
17308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (strcasecmp(args, "unknown") == 0) {
17318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_STATUS_UNKNOWN);
17328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
17338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (strcasecmp(args, "charging") == 0) {
17358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_STATUS_CHARGING);
17368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
17378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (strcasecmp(args, "discharging") == 0) {
17398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_STATUS_DISCHARGING);
17408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
17418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (strcasecmp(args, "not-charging") == 0) {
17438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_STATUS_NOT_CHARGING);
17448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
17458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (strcasecmp(args, "full") == 0) {
17478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_STATUS_FULL);
17488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
17498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "KO: Usage: \"status unknown|charging|discharging|not-charging|full\"\n" );
17538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
17548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
17578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_battery_present( ControlClient  client, char*  args )
17588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
17598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (args) {
17608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (strcasecmp(args, "true") == 0) {
17618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_PRESENT, 1);
17628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
17638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (strcasecmp(args, "false") == 0) {
17658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_PRESENT, 0);
17668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
17678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "KO: Usage: \"present true\" or \"present false\"\n" );
17718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
17728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
17758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_battery_health( ControlClient  client, char*  args )
17768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
17778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (args) {
17788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (strcasecmp(args, "unknown") == 0) {
17798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_HEALTH_UNKNOWN);
17808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
17818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (strcasecmp(args, "good") == 0) {
17838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_HEALTH_GOOD);
17848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
17858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (strcasecmp(args, "overheat") == 0) {
17878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_HEALTH_OVERHEAT);
17888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
17898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (strcasecmp(args, "dead") == 0) {
17918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_HEALTH_DEAD);
17928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
17938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (strcasecmp(args, "overvoltage") == 0) {
17958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_HEALTH_OVERVOLTAGE);
17968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
17978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (strcasecmp(args, "failure") == 0) {
17998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_HEALTH_UNSPEC_FAILURE);
18008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
18018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "KO: Usage: \"health unknown|good|overheat|dead|overvoltage|failure\"\n" );
18058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
18068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
18078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
18098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_battery_capacity( ControlClient  client, char*  args )
18108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
18118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (args) {
18128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int capacity;
18138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (sscanf(args, "%d", &capacity) == 1 && capacity >= 0 && capacity <= 100) {
18158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_CAPACITY, capacity);
18168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
18178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "KO: Usage: \"capacity <percentage>\"\n" );
18218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
18228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
18238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const CommandDefRec  power_commands[] =
18268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
18278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "display", "display battery and charger state",
18288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "display battery and charger state\r\n", NULL,
18298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_power_display, NULL },
18308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "ac", "set AC charging state",
18328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'ac on|off' allows you to set the AC charging state to on or off\r\n", NULL,
18338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_ac_state, NULL },
18348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "status", "set battery status",
18368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'status unknown|charging|discharging|not-charging|full' allows you to set battery status\r\n", NULL,
18378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_battery_status, NULL },
18388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "present", "set battery present state",
18408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'present true|false' allows you to set battery present state to true or false\r\n", NULL,
18418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_battery_present, NULL },
18428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "health", "set battery health state",
18448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'health unknown|good|overheat|dead|overvoltage|failure' allows you to set battery health state\r\n", NULL,
18458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_battery_health, NULL },
18468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "capacity", "set battery capacity state",
18488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'capacity <percentage>' allows you to set battery capacity to a value 0 - 100\r\n", NULL,
18498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_battery_capacity, NULL },
18508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { NULL, NULL, NULL, NULL, NULL, NULL }
18528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
18538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
18558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
18568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
18578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                         E  V  E  N  T   C O M M A N D S                         ******/
18588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
18598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
18608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
18618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
18648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_event_send( ControlClient  client, char*  args )
18658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
18668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*   p;
18678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!args) {
18698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: Usage: event send <type>:<code>:<value> ...\r\n" );
18708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
18718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p = args;
18748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (*p) {
18758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char*  q;
18768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int    type, code, value, ret;
18778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p += strspn( args, " \t" );  /* skip spaces */
18798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (*p == 0)
18808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
18818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q  = p + strcspn( p, " \t" );
18838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (q == p)
18858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
18868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = android_event_from_str( p, &type, &code, &value );
18888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ret < 0) {
18898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ret == -1) {
18908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                control_write( client,
18918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                               "KO: invalid event type in '%.*s', try 'event list types' for valid values\r\n",
18928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                               q-p, p );
18938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else if (ret == -2) {
18948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                control_write( client,
18958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                               "KO: invalid event code in '%.*s', try 'event list codes <type>' for valid values\r\n",
18968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                               q-p, p );
18978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
18988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                control_write( client,
18998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                               "KO: invalid event value in '%.*s', must be an integer\r\n",
19008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                               q-p, p);
19018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
19028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
19038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
19048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
190534f2974ce7ec7c71beb47b5daf9089d5c8c40c79David 'Digit' Turner        user_event_generic( type, code, value );
19068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p = q;
19078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
19098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
19108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
19128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_event_types( ControlClient  client, char*  args )
19138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
19148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  count = android_event_get_type_count();
19158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  nn;
19168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "event <type> can be an integer or one of the following aliases\r\n" );
19188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = 0; nn < count; nn++) {
19198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char  tmp[16];
19208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char* p = tmp;
19218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char* end = p + sizeof(tmp);
19228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int   count2 = android_event_get_code_count( nn );;
19238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p = android_event_bufprint_type_str( p, end, nn );
19258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "    %-8s", tmp );
19278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (count2 > 0)
19288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            control_write( client, "  (%d code aliases)", count2 );
19298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "\r\n" );
19318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
19338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
19348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
19368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_event_codes( ControlClient  client, char*  args )
19378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
19388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  count;
19398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  nn, type, dummy;
19408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!args) {
19428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: argument missing, try 'event codes <type>'\r\n" );
19438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
19448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( android_event_from_str( args, &type, &dummy, &dummy ) < 0 ) {
19478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: bad argument, see 'event types' for valid values\r\n" );
19488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
19498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    count = android_event_get_code_count( type );
19528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (count == 0) {
19538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "no code aliases defined for this type\r\n" );
19548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
19558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "type '%s' accepts the following <code> aliases:\r\n",
19568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       args );
19578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (nn = 0; nn < count; nn++) {
19588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            char  temp[20], *p = temp, *end = p + sizeof(temp);
19598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            android_event_bufprint_code_str( p, end, type, nn );
19608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            control_write( client, "    %-12s\r\n", temp );
19618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
19628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
19658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
19668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic __inline__ int
19688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectutf8_next( unsigned char* *pp, unsigned char*  end )
19698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
19708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char*  p      = *pp;
19718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int             result = -1;
19728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (p < end) {
19748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  c= *p++;
19758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (c >= 128) {
19768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ((c & 0xe0) == 0xc0)
19778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                c &= 0x1f;
19788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else if ((c & 0xf0) == 0xe0)
19798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                c &= 0x0f;
19808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
19818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                c &= 0x07;
19828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            while (p < end && (p[0] & 0xc0) == 0x80) {
19848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                c = (c << 6) | (p[0] & 0x3f);
19858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
19868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
19878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        result = c;
19888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *pp    = p;
19898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
19918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
19928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
19948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_event_text( ControlClient  client, char*  args )
19958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
199671bb14f826775867d16e7d382cfdc48e6ca46ccbVladimir Chtchetkine    AKeycodeBuffer keycodes;
19978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char*  p   = (unsigned char*) args;
19988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char*  end = p + strlen(args);
19998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int             textlen;
200071bb14f826775867d16e7d382cfdc48e6ca46ccbVladimir Chtchetkine    const AKeyCharmap* charmap;
20018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!args) {
20038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: argument missing, try 'event text <message>'\r\n" );
20048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
20058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
200671bb14f826775867d16e7d382cfdc48e6ca46ccbVladimir Chtchetkine
20070158ea3220978ecc0fa1738e4a0bdae83fa36175David 'Digit' Turner    /* Get active charmap. */
20080158ea3220978ecc0fa1738e4a0bdae83fa36175David 'Digit' Turner    charmap = android_get_charmap();
200971bb14f826775867d16e7d382cfdc48e6ca46ccbVladimir Chtchetkine    if (charmap == NULL) {
201071bb14f826775867d16e7d382cfdc48e6ca46ccbVladimir Chtchetkine        control_write( client, "KO: no character map active in current device layout/config\r\n" );
20118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
20128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
201471bb14f826775867d16e7d382cfdc48e6ca46ccbVladimir Chtchetkine    keycodes.keycode_count = 0;
201571bb14f826775867d16e7d382cfdc48e6ca46ccbVladimir Chtchetkine
20168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* un-secape message text into proper utf-8 (conversion happens in-site) */
20178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    textlen = strlen((char*)p);
20188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    textlen = sms_utf8_from_message_str( args, textlen, (unsigned char*)p, textlen );
20198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (textlen < 0) {
20208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "message must be utf8 and can use the following escapes:\r\n"
20218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       "    \\n      for a newline\r\n"
20228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       "    \\xNN    where NN are two hexadecimal numbers\r\n"
20238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       "    \\uNNNN  where NNNN are four hexadecimal numbers\r\n"
20248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       "    \\\\     to send a '\\' character\r\n\r\n"
20258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       "    anything else is an error\r\n"
20268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       "KO: badly formatted text\r\n" );
20278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
20288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    end = p + textlen;
20318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (p < end) {
20328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  c = utf8_next( &p, end );
20338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (c <= 0)
20348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
20358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
203671bb14f826775867d16e7d382cfdc48e6ca46ccbVladimir Chtchetkine        android_charmap_reverse_map_unicode( NULL, (unsigned)c, 1, &keycodes );
203771bb14f826775867d16e7d382cfdc48e6ca46ccbVladimir Chtchetkine        android_charmap_reverse_map_unicode( NULL, (unsigned)c, 0, &keycodes );
203871bb14f826775867d16e7d382cfdc48e6ca46ccbVladimir Chtchetkine        android_keycodes_flush( &keycodes );
20398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
20428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
20438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const CommandDefRec  event_commands[] =
20458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
20468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "send", "send a series of events to the kernel",
20478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'event send <type>:<code>:<value> ...' allows your to send one or more hardware events\r\n"
20488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "to the Android kernel. you can use text names or integers for <type> and <code>\r\n", NULL,
20498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do_event_send, NULL },
20508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "types", "list all <type> aliases",
20528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'event types' list all <type> string aliases supported by the 'event' subcommands\r\n",
20538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NULL, do_event_types, NULL },
20548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "codes", "list all <code> aliases for a given <type>",
20568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'event codes <type>' lists all <code> string aliases for a given event <type>\r\n",
20578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NULL, do_event_codes, NULL },
20588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "text", "simulate keystrokes from a given text",
20608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'event text <message>' allows you to simulate keypresses to generate a given text\r\n"
20618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "message. <message> must be an utf-8 string. Unicode points will be reverse-mapped\r\n"
20628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "according to the current device keyboard. unsupported characters will be discarded\r\n"
20638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "silently\r\n", NULL, do_event_text, NULL },
20648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { NULL, NULL, NULL, NULL, NULL, NULL }
20668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
20678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20682ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije#if CONFIG_ANDROID_SNAPSHOTS
20692ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
20702ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
20712ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije/********************************************************************************************/
20722ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije/********************************************************************************************/
20732ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije/*****                                                                                 ******/
20742ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije/*****                      S N A P S H O T   C O M M A N D S                          ******/
20752ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije/*****                                                                                 ******/
20762ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije/********************************************************************************************/
20772ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije/********************************************************************************************/
20782ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
20792ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thijestatic int
20802ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thijecontrol_write_out_cb(void* opaque, const char* fmt, va_list ap)
20812ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije{
20822ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    ControlClient client = opaque;
20832ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    int ret = control_vwrite(client, fmt, ap);
20842ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    return ret;
20852ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije}
20862ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
20872ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thijestatic int
20882ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thijecontrol_write_err_cb(void* opaque, const char* fmt, va_list ap)
20892ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije{
20902ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    int ret = 0;
20912ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    ControlClient client = opaque;
20922ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    ret += control_write(client, "KO: ");
20932ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    ret += control_vwrite(client, fmt, ap);
20942ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    return ret;
20952ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije}
20962ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
20972ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thijestatic int
20982ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thijedo_snapshot_list( ControlClient  client, char*  args )
20992ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije{
21002ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    int ret;
21012ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    OutputChannel *out = output_channel_alloc(client, control_write_out_cb);
21022ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    OutputChannel *err = output_channel_alloc(client, control_write_err_cb);
21032ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    do_info_snapshots_oc(out, err);
21042ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    ret = output_channel_written(err);
21052ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    output_channel_free(out);
21062ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    output_channel_free(err);
21072ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
21082ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    return ret > 0;
21092ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije}
21102ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
21112ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thijestatic int
21122ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thijedo_snapshot_save( ControlClient  client, char*  args )
21132ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije{
21142ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    int ret;
21152ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    OutputChannel *err = output_channel_alloc(client, control_write_err_cb);
21162ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    do_savevm_oc(err, args);
21172ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    ret = output_channel_written(err);
21182ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    output_channel_free(err);
21192ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
21202ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    return ret > 0; // no output on error channel indicates success
21212ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije}
21222ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
21232ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thijestatic int
21242ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thijedo_snapshot_load( ControlClient  client, char*  args )
21252ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije{
21262ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    int ret;
21272ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    OutputChannel *err = output_channel_alloc(client, control_write_err_cb);
21282ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    do_loadvm_oc(err, args);
21292ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    ret = output_channel_written(err);
21302ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    output_channel_free(err);
21312ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
21322ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    return ret > 0;
21332ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije}
21342ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
21352ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thijestatic int
21362ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thijedo_snapshot_del( ControlClient  client, char*  args )
21372ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije{
21382ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    int ret;
21392ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    OutputChannel *err = output_channel_alloc(client, control_write_err_cb);
21402ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    do_delvm_oc(err, args);
21412ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    ret = output_channel_written(err);
21422ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    output_channel_free(err);
21432ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
21442ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    return ret > 0;
21452ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije}
21462ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
21472ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thijestatic const CommandDefRec  snapshot_commands[] =
21482ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije{
21492ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    { "list", "list available state snapshots",
21502ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    "'avd snapshot list' will show a list of all state snapshots that can be loaded\r\n",
21512ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    NULL, do_snapshot_list, NULL },
21522ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
21532ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    { "save", "save state snapshot",
21542ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    "'avd snapshot save <name>' will save the current (run-time) state to a snapshot with the given name\r\n",
21552ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    NULL, do_snapshot_save, NULL },
21562ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
21572ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    { "load", "load state snapshot",
21582ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    "'avd snapshot load <name>' will load the state snapshot of the given name\r\n",
21592ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    NULL, do_snapshot_load, NULL },
21602ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
21612ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    { "del", "delete state snapshot",
21622ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    "'avd snapshot del <name>' will delete the state snapshot with the given name\r\n",
21632ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    NULL, do_snapshot_del, NULL },
21642ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
21652ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    { NULL, NULL, NULL, NULL, NULL, NULL }
21662ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije};
21672ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
21682ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
21692ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije#endif
21702ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
21718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
21738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
21748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
21758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                               V M   C O M M A N D S                             ******/
21768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
21778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
21788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
21798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
21818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_avd_stop( ControlClient  client, char*  args )
21828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
21838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!vm_running) {
21848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: virtual device already stopped\r\n" );
21858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
21868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
21878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    vm_stop(EXCP_INTERRUPT);
21888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
21898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
21908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
21928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_avd_start( ControlClient  client, char*  args )
21938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
21948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (vm_running) {
21958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: virtual device already running\r\n" );
21968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
21978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
21988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    vm_start();
21998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
22008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
22038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_avd_status( ControlClient  client, char*  args )
22048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    control_write( client, "virtual device is %s\r\n", vm_running ? "running" : "stopped" );
22068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
22078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
22108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_avd_name( ControlClient  client, char*  args )
22118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
221290c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkine    control_write( client, "%s\r\n", android_op_avd_name);
22138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
22148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const CommandDefRec  vm_commands[] =
22178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "stop", "stop the virtual device",
22198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'avd stop' stops the virtual device immediately, use 'avd start' to continue execution\r\n",
22208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NULL, do_avd_stop, NULL },
22218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "start", "start/restart the virtual device",
22238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'avd start' will start or continue the virtual device, use 'avd stop' to stop it\r\n",
22248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NULL, do_avd_start, NULL },
22258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "status", "query virtual device status",
22272ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    "'avd status' will indicate whether the virtual device is running or not\r\n",
22288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NULL, do_avd_status, NULL },
22298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "name", "query virtual device name",
22318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'avd name' will return the name of this virtual device\r\n",
22328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NULL, do_avd_name, NULL },
22338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22342ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije#if CONFIG_ANDROID_SNAPSHOTS
22352ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    { "snapshot", "state snapshot commands",
22362ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    "allows you to save and restore the virtual device state in snapshots\r\n",
22372ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    NULL, NULL, snapshot_commands },
22382ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije#endif
22392ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije
22408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { NULL, NULL, NULL, NULL, NULL, NULL }
22418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
22428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
22448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
22458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
22468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                             G E O   C O M M A N D S                             ******/
22478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
22488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
22498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
22508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
22528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_geo_nmea( ControlClient  client, char*  args )
22538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!args) {
22558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: NMEA sentence missing, try 'help geo nmea'\r\n" );
22568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
22578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
22588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!android_gps_cs) {
22598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: no GPS emulation in this virtual device\r\n" );
22608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
22618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
22628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    android_gps_send_nmea( args );
22638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
22648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
22678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_geo_fix( ControlClient  client, char*  args )
22688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22694afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock    // GEO_SAT2 provides bug backwards compatibility.
22704afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock    enum { GEO_LONG = 0, GEO_LAT, GEO_ALT, GEO_SAT, GEO_SAT2, NUM_GEO_PARAMS };
22718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*   p = args;
22724afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock    int     top_param = -1;
22734afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock    double  params[ NUM_GEO_PARAMS ];
2274657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner    int     n_satellites = 1;
22758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static  int     last_time = 0;
22778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static  double  last_altitude = 0.;
22788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!p)
22808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p = "";
22818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* tokenize */
22838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (*p) {
22848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char*   end;
22858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        double  val = strtod( p, &end );
22868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (end == p) {
22888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            control_write( client, "KO: argument '%s' is not a number\n", p );
22898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
22908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
22918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22924afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock        params[++top_param] = val;
22934afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock        if (top_param + 1 == NUM_GEO_PARAMS)
22948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
22958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p = end;
22978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (*p && (p[0] == ' ' || p[0] == '\t'))
22988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p += 1;
22998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
23008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* sanity check */
23024afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock    if (top_param < GEO_LAT) {
23038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: not enough arguments: see 'help geo fix' for details\r\n" );
23048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
23058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
23068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23074afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock    /* check number of satellites, must be integer between 1 and 12 */
23084afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock    if (top_param >= GEO_SAT) {
23094afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock        int sat_index = (top_param >= GEO_SAT2) ? GEO_SAT2 : GEO_SAT;
23104afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock        n_satellites = (int) params[sat_index];
23114afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock        if (n_satellites != params[sat_index]
23124afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock            || n_satellites < 1 || n_satellites > 12) {
2313657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner            control_write( client, "KO: invalid number of satellites. Must be an integer between 1 and 12\r\n");
2314657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner            return -1;
2315657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner        }
2316657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner    }
2317657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner
23188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* generate an NMEA sentence for this fix */
23198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
23208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        STRALLOC_DEFINE(s);
23218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        double   val;
23228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int      deg, min;
23238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char     hemi;
23248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2325657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner        /* format overview:
2326657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner         *    time of fix      123519     12:35:19 UTC
2327657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner         *    latitude         4807.038   48 degrees, 07.038 minutes
2328657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner         *    north/south      N or S
2329657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner         *    longitude        01131.000  11 degrees, 31. minutes
2330657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner         *    east/west        E or W
2331657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner         *    fix quality      1          standard GPS fix
2332657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner         *    satellites       1 to 12    number of satellites being tracked
2333657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner         *    HDOP             <dontcare> horizontal dilution
2334657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner         *    altitude         546.       altitude above sea-level
2335657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner         *    altitude units   M          to indicate meters
2336657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner         *    diff             <dontcare> height of sea-level above ellipsoid
2337657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner         *    diff units       M          to indicate meters (should be <dontcare>)
2338657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner         *    dgps age         <dontcare> time in seconds since last DGPS fix
2339657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner         *    dgps sid         <dontcare> DGPS station id
2340657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner         */
2341657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner
23428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* first, the time */
23438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        stralloc_add_format( s, "$GPGGA,%06d", last_time );
23448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        last_time ++;
23458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* then the latitude */
23478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        hemi = 'N';
23484afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock        val  = params[GEO_LAT];
23498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (val < 0) {
23508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            hemi = 'S';
23518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            val  = -val;
23528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
23538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        deg = (int) val;
2354657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner        val = 60*(val - deg);
2355657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner        min = (int) val;
2356631f2555ed2b50a07ea19eaefa495a028ab1991aDavid 'Digit' Turner        val = 10000*(val - min);
2357657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner        stralloc_add_format( s, ",%02d%02d.%04d,%c", deg, min, (int)val, hemi );
23588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* the longitude */
23608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        hemi = 'E';
23614afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock        val  = params[GEO_LONG];
23628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (val < 0) {
23638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            hemi = 'W';
23648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            val  = -val;
23658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
23668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        deg = (int) val;
2367657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner        val = 60*(val - deg);
2368657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner        min = (int) val;
2369631f2555ed2b50a07ea19eaefa495a028ab1991aDavid 'Digit' Turner        val = 10000*(val - min);
2370657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner        stralloc_add_format( s, ",%02d%02d.%04d,%c", deg, min, (int)val, hemi );
23718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2372657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner        /* bogus fix quality, satellite count and dilution */
2373657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner        stralloc_add_format( s, ",1,%02d,", n_satellites );
23748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2375657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner        /* optional altitude + bogus diff */
23764afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock        if (top_param >= GEO_ALT) {
23774afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock            stralloc_add_format( s, ",%.1g,M,0.,M", params[GEO_ALT] );
23784afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock            last_altitude = params[GEO_ALT];
23798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
2380657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner            stralloc_add_str( s, ",,,," );
23818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
23828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* bogus rest and checksum */
23838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        stralloc_add_str( s, ",,,*47" );
23848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* send it, then free */
23868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        android_gps_send_nmea( stralloc_cstr(s) );
23878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        stralloc_reset( s );
23888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
23898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
23908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
23918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const CommandDefRec  geo_commands[] =
23938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
23948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "nmea", "send an GPS NMEA sentence",
23958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'geo nema <sentence>' sends a NMEA 0183 sentence to the emulated device, as\r\n"
23968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "if it came from an emulated GPS modem. <sentence> must begin with '$GP'. only\r\n"
23978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'$GPGGA' and '$GPRCM' sentences are supported at the moment.\r\n",
23988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NULL, do_geo_nmea, NULL },
23998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "fix", "send a simple GPS fix",
24014afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock    "'geo fix <longitude> <latitude> [<altitude> [<satellites>]]'\r\n"
24024afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock    " allows you to send a simple GPS fix to the emulated system.\r\n"
24034afdaf1285ecdcbcfeac6d3e9be0b9b0de0e2b07Tim Baverstock    " The parameters are:\r\n\r\n"
24048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "  <longitude>   longitude, in decimal degrees\r\n"
24058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "  <latitude>    latitude, in decimal degrees\r\n"
24068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "  <altitude>    optional altitude in meters\r\n"
2407657a3521a1f4d354b57f0e524b1cd57bed177bb0David 'Digit' Turner    "  <satellites>  number of satellites being tracked (1-12)\r\n"
24088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "\r\n",
24098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NULL, do_geo_fix, NULL },
24108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { NULL, NULL, NULL, NULL, NULL, NULL }
24128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
24138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
24168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
24178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
24188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                           M A I N   C O M M A N D S                             ******/
24198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
24208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
24218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
24228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
24248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_window_scale( ControlClient  client, char*  args )
24258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
24268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    double  scale;
24278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int     is_dpi = 0;
24288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*   end;
24298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!args) {
24318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        control_write( client, "KO: argument missing, try 'window scale <scale>'\r\n" );
24328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
24338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
24348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    scale = strtol( args, &end, 10 );
24368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (end > args && !memcmp( end, "dpi", 4 )) {
24378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        is_dpi = 1;
24388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
24398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
24408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        scale = strtod( args, &end );
24418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (end == args || end[0]) {
24428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            control_write( client, "KO: argument <scale> must be a real number, or an integer followed by 'dpi'\r\n" );
24438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
24448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
24458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
24468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2447777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine    uicmd_set_window_scale( scale, is_dpi );
24488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
24498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
24508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const CommandDefRec  window_commands[] =
24528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
24538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "scale", "change the window scale",
24548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "'window scale <scale>' allows you to change the scale of the emulator window at runtime\r\n"
24558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "<scale> must be either a real number between 0.1 and 3.0, or an integer followed by\r\n"
24568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "the 'dpi' prefix (as in '120dpi')\r\n",
24578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NULL, do_window_scale, NULL },
24588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { NULL, NULL, NULL, NULL, NULL, NULL }
24608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
24618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
24638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
24648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
2465e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner/*****                           Q E M U   C O M M A N D S                             ******/
2466e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner/*****                                                                                 ******/
2467e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner/********************************************************************************************/
2468e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner/********************************************************************************************/
2469e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner
2470e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turnerstatic int
2471e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turnerdo_qemu_monitor( ControlClient client, char* args )
2472e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner{
2473e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    char             socketname[32];
2474e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    int              fd;
2475e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    CharDriverState* cs;
2476e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner
2477e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    if (args != NULL) {
2478e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner        control_write( client, "KO: no argument for 'qemu monitor'\r\n" );
2479e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner        return -1;
2480e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    }
2481e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    /* Detach the client socket, and re-attach it to a monitor */
2482e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    fd = control_client_detach(client);
2483e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    snprintf(socketname, sizeof socketname, "tcp:socket=%d", fd);
2484e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    cs = qemu_chr_open("monitor", socketname, NULL);
2485e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    if (cs == NULL) {
2486e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner        control_client_reattach(client, fd);
2487e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner        control_write( client, "KO: internal error: could not detach from console !\r\n" );
2488e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner        return -1;
2489e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    }
2490e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    monitor_init(cs, MONITOR_USE_READLINE|MONITOR_QUIT_DOESNT_EXIT);
2491e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    control_client_destroy(client);
2492e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    return 0;
2493e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner}
2494e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner
2495e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine#ifdef CONFIG_STANDALONE_CORE
2496d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine/* UI settings, passed to the core via -ui-settings command line parameter. */
2497d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkineextern char* android_op_ui_settings;
2498d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine
2499d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkinestatic int
2500d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkinedo_attach_ui( ControlClient client, char* args )
2501d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine{
2502d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine    // Make sure that there are no UI already attached to this console.
2503d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine    if (attached_ui_client != NULL) {
2504d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine        control_write( client, "KO: Another UI is attached to this core!\r\n" );
2505d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine        control_client_destroy(client);
2506d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine        return -1;
2507d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine    }
2508d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine
2509d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine    attached_ui_client = client;
2510d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine
2511d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine    if (android_op_ui_settings != NULL) {
2512d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine        // Reply "OK" with the saved -ui-settings property.
2513d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine        char reply_buf[4096];
2514d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine        snprintf(reply_buf, sizeof(reply_buf), "OK: %s\r\n", android_op_ui_settings);
2515d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine        control_write( client, reply_buf);
2516d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine    } else {
2517d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine        control_write( client, "OK\r\n");
2518d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine    }
2519d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine
2520d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine    return 0;
2521d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine}
2522d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine
2523e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine/* Core display instance. */
2524e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkineextern CoreDisplay core_display;
2525e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine
2526e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkinestatic int
2527e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkinedo_create_framebuffer_service( ControlClient client, char* args )
2528e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine{
2529e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    CoreFramebuffer* core_fb;
2530e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    const char* protocol = "-raw";   // Default framebuffer exchange protocol.
2531e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine
2532e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    // Protocol type is defined by the arguments passed with the stream switch
2533e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    // command.
2534e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    if (args != NULL && *args != '\0') {
2535e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        size_t token_len;
2536e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        const char* param_end = strchr(args, ' ');
2537e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        if (param_end == NULL) {
2538e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine            param_end = args + strlen(args);
2539e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        }
2540e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        token_len = param_end - args;
2541e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        protocol = args;
2542e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine
2543e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        // Make sure that this is one of the supported protocols.
2544e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        if (strncmp(protocol, "-raw", token_len) &&
2545e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine            strncmp(protocol, "-shared", token_len)) {
2546e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine            derror("Invalid framebuffer parameter %s\n", protocol);
2547e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine            control_write( client, "KO: Invalid parameter\r\n" );
2548e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine            control_client_destroy(client);
2549e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine            return -1;
2550e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        }
2551e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    }
2552e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine
2553e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    // Make sure that there are no framebuffer client already existing.
2554e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    if (framebuffer_client != NULL) {
2555e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        control_write( client, "KO: Another framebuffer service is already existing!\r\n" );
2556e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        control_client_destroy(client);
2557e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        return -1;
2558e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    }
2559e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine
25608acf4e2237c2969647f47008344e44918bb30acbVladimir Chtchetkine    core_fb = corefb_create(client->sock, protocol, coredisplay_get_framebuffer());
2561e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    if (!coredisplay_attach_fb_service(core_fb)) {
25628acf4e2237c2969647f47008344e44918bb30acbVladimir Chtchetkine        char reply_buf[4096];
2563e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        framebuffer_client = client;
25648acf4e2237c2969647f47008344e44918bb30acbVladimir Chtchetkine        // Reply "OK" with the framebuffer's bits per pixel
25658acf4e2237c2969647f47008344e44918bb30acbVladimir Chtchetkine        snprintf(reply_buf, sizeof(reply_buf), "OK: -bitsperpixel=%d\r\n",
25668acf4e2237c2969647f47008344e44918bb30acbVladimir Chtchetkine                 corefb_get_bits_per_pixel(core_fb));
25678acf4e2237c2969647f47008344e44918bb30acbVladimir Chtchetkine        control_write( client, reply_buf);
2568e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    } else {
2569e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        control_write( client, "KO\r\n" );
2570e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        control_client_destroy(client);
2571e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        return -1;
2572e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    }
2573e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine
2574e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    return 0;
2575e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine}
25769411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine
25776ee1c4edbd30b7c7aff9d6e13793207278aa1660Vladimir Chtchetkinevoid
25786ee1c4edbd30b7c7aff9d6e13793207278aa1660Vladimir Chtchetkinedestroy_control_fb_client(void)
25796ee1c4edbd30b7c7aff9d6e13793207278aa1660Vladimir Chtchetkine{
25806ee1c4edbd30b7c7aff9d6e13793207278aa1660Vladimir Chtchetkine    if (framebuffer_client != NULL) {
25816ee1c4edbd30b7c7aff9d6e13793207278aa1660Vladimir Chtchetkine        control_client_destroy(framebuffer_client);
25826ee1c4edbd30b7c7aff9d6e13793207278aa1660Vladimir Chtchetkine    }
25836ee1c4edbd30b7c7aff9d6e13793207278aa1660Vladimir Chtchetkine}
25846ee1c4edbd30b7c7aff9d6e13793207278aa1660Vladimir Chtchetkine
25859411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkinestatic int
25869411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkinedo_create_user_events_service( ControlClient client, char* args )
25879411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine{
25886b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    // Make sure that there are no user events client already existing.
25899411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine    if (user_events_client != NULL) {
25909411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine        control_write( client, "KO: Another user events service is already existing!\r\n" );
25919411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine        control_client_destroy(client);
25929411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine        return -1;
25939411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine    }
25949411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine
25959411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine    core_ue = coreue_create(client->sock);
25969411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine    if (core_ue != NULL) {
25979411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine        char reply_buf[4096];
25989411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine        user_events_client = client;
25999411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine        snprintf(reply_buf, sizeof(reply_buf), "OK\r\n");
26009411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine        control_write( client, reply_buf);
26019411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine    } else {
26029411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine        control_write( client, "KO\r\n" );
26039411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine        control_client_destroy(client);
26049411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine        return -1;
26059411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine    }
26069411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine
26079411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine    return 0;
26089411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine}
26096ee1c4edbd30b7c7aff9d6e13793207278aa1660Vladimir Chtchetkine
26106ee1c4edbd30b7c7aff9d6e13793207278aa1660Vladimir Chtchetkinevoid
26116ee1c4edbd30b7c7aff9d6e13793207278aa1660Vladimir Chtchetkinedestroy_control_ue_client(void)
26126ee1c4edbd30b7c7aff9d6e13793207278aa1660Vladimir Chtchetkine{
26136ee1c4edbd30b7c7aff9d6e13793207278aa1660Vladimir Chtchetkine    if (user_events_client != NULL) {
26146ee1c4edbd30b7c7aff9d6e13793207278aa1660Vladimir Chtchetkine        control_client_destroy(user_events_client);
26156ee1c4edbd30b7c7aff9d6e13793207278aa1660Vladimir Chtchetkine    }
26166ee1c4edbd30b7c7aff9d6e13793207278aa1660Vladimir Chtchetkine}
26176b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine
26186b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkinestatic int
26196b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkinedo_create_ui_core_ctl_service( ControlClient client, char* args )
26206b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine{
26216b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    // Make sure that there are no ui control client already existing.
26226b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    if (ui_core_ctl_client != NULL) {
26236b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        control_write( client, "KO: Another UI control service is already existing!\r\n" );
26246b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        control_client_destroy(client);
26256b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        return -1;
26266b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    }
26276b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine
2628777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine    if (!coreCmdImpl_create(client->sock)) {
26296b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        char reply_buf[4096];
26306b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        ui_core_ctl_client = client;
26316b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        snprintf(reply_buf, sizeof(reply_buf), "OK\r\n");
26326b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        control_write( client, reply_buf);
26336b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    } else {
26346b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        control_write( client, "KO\r\n" );
26356b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        control_client_destroy(client);
26366b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        return -1;
26376b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    }
26386b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine
26396b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    return 0;
26406b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine}
26416b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine
26426b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkinevoid
26436b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkinedestroy_ui_core_ctl_client(void)
26446b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine{
26456b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    if (ui_core_ctl_client != NULL) {
26466b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        control_client_destroy(ui_core_ctl_client);
26476b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    }
26486b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine}
26496b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine
2650777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkinevoid
2651777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkinedestroy_corecmd_client(void)
2652777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine{
2653777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine    if (ui_core_ctl_client != NULL) {
2654777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine        control_client_destroy(ui_core_ctl_client);
2655777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine    }
2656777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine}
2657777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine
26586b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkinestatic int
26596b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkinedo_create_core_ui_ctl_service( ControlClient client, char* args )
26606b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine{
26616b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    // Make sure that there are no ui control client already existing.
26626b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    if (core_ui_ctl_client != NULL) {
26636b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        control_write( client, "KO: Another UI control service is already existing!\r\n" );
26646b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        control_client_destroy(client);
26656b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        return -1;
26666b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    }
26676b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine
2668777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine    if (!uiCmdProxy_create(client->sock)) {
26696b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        char reply_buf[4096];
26706b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        core_ui_ctl_client = client;
26716b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        snprintf(reply_buf, sizeof(reply_buf), "OK\r\n");
26726b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        control_write( client, reply_buf);
26736b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    } else {
26746b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        control_write( client, "KO\r\n" );
26756b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        control_client_destroy(client);
26766b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        return -1;
26776b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    }
26786b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine
26796b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    return 0;
26806b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine}
26816b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine
26826b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkinevoid
26836b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkinedestroy_core_ui_ctl_client(void)
26846b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine{
26856b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    if (core_ui_ctl_client != NULL) {
26866b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine        control_client_destroy(core_ui_ctl_client);
26876b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    }
26886b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine}
2689777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine
2690777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkinevoid
2691777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkinedestroy_uicmd_client(void)
2692777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine{
2693777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine    if (core_ui_ctl_client != NULL) {
2694777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine        control_client_destroy(core_ui_ctl_client);
2695777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine    }
2696777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine}
2697777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine
2698e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine#endif  // CONFIG_STANDALONE_CORE
2699e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine
2700e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turnerstatic const CommandDefRec  qemu_commands[] =
2701e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner{
2702e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    { "monitor", "enter QEMU monitor",
2703e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    "Enter the QEMU virtual machine monitor\r\n",
2704e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    NULL, do_qemu_monitor, NULL },
2705e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner
2706e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine#ifdef CONFIG_STANDALONE_CORE
2707a473d81826d44905bc0d7ec8c9b39aef1cf87fb7Vladimir Chtchetkine    { "attach-UI", "attach UI to the core",
2708d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine    "Attach UI to the core\r\n",
2709d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine    NULL, do_attach_ui, NULL },
2710d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine
2711e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    { "framebuffer", "create framebuffer service",
2712e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    "Create framebuffer service\r\n",
2713e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine    NULL, do_create_framebuffer_service, NULL },
27149411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine
2715a473d81826d44905bc0d7ec8c9b39aef1cf87fb7Vladimir Chtchetkine    { "user-events", "create user events service",
27169411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine    "Create user events service\r\n",
27179411a562e1ab772732a4d5147c9103a638837c82Vladimir Chtchetkine    NULL, do_create_user_events_service, NULL },
27186b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine
2719a473d81826d44905bc0d7ec8c9b39aef1cf87fb7Vladimir Chtchetkine    { "ui-core-control", "create UI control service",
27206b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    "Create UI control service\r\n",
27216b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    NULL, do_create_ui_core_ctl_service, NULL },
27226b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine
2723a473d81826d44905bc0d7ec8c9b39aef1cf87fb7Vladimir Chtchetkine    { "core-ui-control", "create UI control service",
27246b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    "Create UI control service\r\n",
27256b985d708d64008eee69fe0c3f03c6e3c61e7f73Vladimir Chtchetkine    NULL, do_create_core_ui_ctl_service, NULL },
2726e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine#endif  // CONFIG_STANDALONE_CORE
2727e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine
2728e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    { NULL, NULL, NULL, NULL, NULL, NULL }
2729e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner};
2730e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner
2731e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner
2732e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner/********************************************************************************************/
2733e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner/********************************************************************************************/
2734e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner/*****                                                                                 ******/
27358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                           M A I N   C O M M A N D S                             ******/
27368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                                 ******/
27378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
27388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************************/
27398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
27418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_kill( ControlClient  client, char*  args )
27428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2743d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine    control_write( client, "OK: killing emulator, bye bye\r\n" );
2744d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine    exit(0);
27458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
27468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const CommandDefRec   main_commands[] =
27488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
27498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "help|h|?", "print a list of commands", NULL, NULL, do_help, NULL },
27508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "event", "simulate hardware events",
27528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "allows you to send fake hardware events to the kernel\r\n", NULL,
27538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NULL, event_commands },
27548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "geo", "Geo-location commands",
27568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      "allows you to change Geo-related settings, or to send GPS NMEA sentences\r\n", NULL,
27578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      NULL, geo_commands },
27588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "gsm", "GSM related commands",
27608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      "allows you to change GSM-related settings, or to make a new inbound phone call\r\n", NULL,
27618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      NULL, gsm_commands },
27628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27631a000857bb7eef298efa787699050884f92311feJaime Lopez    { "cdma", "CDMA related commands",
27641a000857bb7eef298efa787699050884f92311feJaime Lopez      "allows you to change CDMA-related settings\r\n", NULL,
27651a000857bb7eef298efa787699050884f92311feJaime Lopez      NULL, cdma_commands },
27661a000857bb7eef298efa787699050884f92311feJaime Lopez
27678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "kill", "kill the emulator instance", NULL, NULL,
2768d87b080495e71ada650b165a1f06616b433e6073Vladimir Chtchetkine      do_kill, NULL },
27698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "network", "manage network settings",
27718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      "allows you to manage the settings related to the network data connection of the\r\n"
27728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      "emulated device.\r\n", NULL,
27738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      NULL, network_commands },
27748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "power", "power related commands",
27768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      "allows to change battery and AC power status\r\n", NULL,
27778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      NULL, power_commands },
27788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "quit|exit", "quit control session", NULL, NULL,
27808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      do_quit, NULL },
27818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "redir",    "manage port redirections",
27838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      "allows you to add, list and remove UDP and/or PORT redirection from the host to the device\r\n"
27848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      "as an example, 'redir  tcp:5000:6000' will route any packet sent to the host's TCP port 5000\r\n"
27858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      "to TCP port 6000 of the emulated device\r\n", NULL,
27868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      NULL, redir_commands },
27878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "sms", "SMS related commands",
27898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      "allows you to simulate an inbound SMS\r\n", NULL,
27908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      NULL, sms_commands },
27918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27922ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    { "avd", "control virtual device execution",
27932ff39a367738422c0ca1313cac8ff380e1fdd498Ot ten Thije    "allows you to control (e.g. start/stop) the execution of the virtual device\r\n", NULL,
27948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NULL, vm_commands },
27958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { "window", "manage emulator window",
27978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    "allows you to modify the emulator window\r\n", NULL,
27988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NULL, window_commands },
27998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2800e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    { "qemu", "QEMU-specific commands",
2801e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    "allows to connect to the QEMU virtual machine monitor\r\n", NULL,
2802e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner    NULL, qemu_commands },
2803e92bc56ef89ab8b51c4c89d4d9779b64e9491b9bDavid 'Digit' Turner
28048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { NULL, NULL, NULL, NULL, NULL, NULL }
28058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
28068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
28078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
28088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic ControlGlobalRec  _g_global;
28098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
28108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
28118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectcontrol_console_start( int  port )
28128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
28138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return control_global_init( &_g_global, port );
28148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2815