emulator: clean-up emulator network initialization
authorSeokYeon Hwang <syeon.hwang@samsung.com>
Mon, 4 Jan 2016 10:28:26 +0000 (19:28 +0900)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Tue, 5 Jan 2016 12:15:21 +0000 (21:15 +0900)
Do port forwarding and base port initialization at once.
Some emul_state getters/setters are refined.
"sdb.c" is "net_helper.c" now and it use new_debug_channel.

Change-Id: I0659b35e231a8f60bd3707a2d04b09213a9cb830
Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
Signed-off-by: Jinhyung Choi <jinh0.choi@samsung.com>
22 files changed:
include/net/slirp.h
net/slirp.c
tizen/src/ecs/ecs.c
tizen/src/ecs/ecs_msg_injector.c
tizen/src/emul_state.c
tizen/src/emul_state.h
tizen/src/emulator.c
tizen/src/hw/maru_pm.c
tizen/src/ui/menu/contextmenu.cpp
tizen/src/ui/menu/contextmenu.h
tizen/src/ui/menu/screenshotdialog.cpp
tizen/src/ui/menu/shellopener.cpp
tizen/src/ui/qt5_supplement.cpp
tizen/src/util/Makefile.objs
tizen/src/util/net_helper.c [new file with mode: 0644]
tizen/src/util/net_helper.h [new file with mode: 0644]
tizen/src/util/osutil-darwin.c
tizen/src/util/osutil-linux.c
tizen/src/util/osutil-win32.c
tizen/src/util/sdb.c [deleted file]
tizen/src/util/sdb.h [deleted file]
vl.c

index 64b795cda9028449acbda9806f226a576418bbb4..89f871a604730da4a373c67c9db7dcfc8e0604b9 100644 (file)
@@ -42,6 +42,12 @@ int net_slirp_smb(const char *exported_dir);
 
 void hmp_info_usernet(Monitor *mon, const QDict *qdict);
 
+#ifdef CONFIG_MARU
+bool hostfwd_try_add(int is_udp, const char *host_addr_str,
+                      int host_port, const char *guest_addr_str, int guest_port);
+bool hostfwd_try_remove(int is_udp, const char *host_addr_str, int host_port);
+#endif
+
 #endif
 
 #endif /* QEMU_NET_SLIRP_H */
index f505570adb130d79b228b5556abdfc90fc139b0f..7cf1eeb7642b508a4250883193b169abd9a2ada7 100644 (file)
@@ -275,6 +275,56 @@ error:
     return -1;
 }
 
+#ifdef CONFIG_MARU
+bool hostfwd_try_add(int is_udp, const char *host_addr_str,
+        int host_port, const char *guest_addr_str, int guest_port)
+{
+    if (QTAILQ_EMPTY(&slirp_stacks)) {
+        return false;
+    }
+
+    SlirpState *s = QTAILQ_FIRST(&slirp_stacks);
+    struct in_addr host_addr = { .s_addr = INADDR_ANY };
+    struct in_addr guest_addr = { .s_addr = 0 };
+
+    if ((host_addr_str && !inet_aton(host_addr_str, &host_addr)) ||
+            (guest_addr_str && !inet_aton(guest_addr_str, &guest_addr))) {
+        error_report("invalid host forwarding rule '%s' '%s",
+                host_addr_str, guest_addr_str);
+        return false;
+    }
+
+    if (slirp_add_hostfwd(s->slirp, is_udp, host_addr, host_port, guest_addr,
+                          guest_port) < 0) {
+        return false;
+    }
+
+    return true;
+}
+
+bool hostfwd_try_remove(int is_udp, const char *host_addr_str, int host_port)
+{
+    if (QTAILQ_EMPTY(&slirp_stacks)) {
+        return false;
+    }
+
+    SlirpState *s = QTAILQ_FIRST(&slirp_stacks);
+    struct in_addr host_addr = { .s_addr = INADDR_ANY };
+
+    if (host_addr_str && !inet_aton(host_addr_str, &host_addr)) {
+        error_report("invalid host forwarding rule '%s",
+                host_addr_str);
+        return false;
+    }
+
+    if (slirp_remove_hostfwd(s->slirp, is_udp, host_addr, host_port) < 0) {
+        return false;
+    }
+
+    return true;
+}
+#endif
+
 static SlirpState *slirp_lookup(Monitor *mon, const char *vlan,
                                 const char *stack)
 {
index 05e27661d8783083cd2af2f4b07a7281ec6587d7..663d7f89ede905528570a9f6dbb1b95ef8e8df55 100644 (file)
@@ -46,7 +46,7 @@
 #include "qapi/qmp/qint.h"
 
 #include "emulator.h"
-#include "util/sdb.h"
+#include "util/net_helper.h"
 #include "ecs.h"
 #include "emul_state.h"
 
@@ -635,6 +635,7 @@ static int ecs_loop(ECS_State *cs)
 
 static int socket_initialize(ECS_State *cs) {
     LOG_INFO("Listen fd is %d\n", emul_vm_base_socket);
+    g_assert(emul_vm_base_socket >= 0);
 
     cs->listen_fd = emul_vm_base_socket;
 
index 199781c23cfe25e8aeba88979cfa5189029dffd2..84a27971cd3c6392e8e3f32a7fc74b2e669c88a4 100644 (file)
@@ -317,7 +317,7 @@ static bool push_package(const char* data)
 #else
     ret = sprintf(cmd, "cmd /S /C \"\"%s%s\" -s emulator-%d push \"%s%s%s%s%s\" /opt/usr/apps/tmp/sdk_tools/%s 2>&1\"",
 #endif
-            bin_dir, sdb_path, get_device_serial_number(),
+            bin_dir, sdb_path, get_vm_device_serial_number(),
             bin_dir, platform_path, get_profile_name(), addon_path, addon,
             addon);
     if (ret < 0) {
index 6772eeb876f1e8868798d0b864165cda1a5226db..39622987678b487378d43f1ffdd0aca5fd9b69dc 100644 (file)
@@ -57,12 +57,14 @@ extern bool hax_allowed;
 #include "emulator_options.h"
 #include "hw/virtio/maru_virtio_touchscreen.h"
 #include "hw/virtio/maru_virtio_evdi.h"
-#include "util/new_debug_ch.h"
+#include "util/net_helper.h"
 
 #ifdef CONFIG_JAVA_UI
 #include "skin/maruskin_server.h"
 #endif
 
+#include "util/new_debug_ch.h"
+
 DECLARE_DEBUG_CHANNEL(emul_state);
 
 #define MAXLEN  512
@@ -134,50 +136,6 @@ int get_max_touch_point(void)
     }
 }
 
-/* base port for emualtor vm */
-void set_emul_vm_base_port(int port)
-{
-    _emul_info.vm_base_port = port;
-    if (is_netclient_tap_attached()) {
-        _emul_info.device_serial_number = 26101;
-    } else {
-        _emul_info.device_serial_number = port + 1;
-    }
-    _emul_info.ecs_port = port + 3;
-    _emul_info.serial_port = port + 4;
-    _emul_info.spice_port = port + 5;
-}
-
-int get_emul_spice_port(void)
-{
-    return _emul_info.spice_port;
-}
-
-void set_emul_ecs_port(int port)
-{
-    _emul_info.ecs_port = port;
-}
-
-int get_emul_vm_base_port(void)
-{
-    return _emul_info.vm_base_port;
-}
-
-int get_device_serial_number(void)
-{
-    return _emul_info.device_serial_number;
-}
-
-int get_emul_ecs_port(void)
-{
-    return _emul_info.ecs_port;
-}
-
-int get_emul_serial_port(void)
-{
-    return _emul_info.serial_port;
-}
-
 /* current emulator condition */
 int get_emulator_condition(void)
 {
@@ -661,6 +619,42 @@ uint64_t get_ram_size(void)
     return ram_size;
 }
 
+// VM base port
+static int vm_base_port = 0;
+
+void set_vm_base_port(int port)
+{
+    vm_base_port = port;
+}
+
+int get_vm_base_port(void)
+{
+    // should not be called before base port is prepared
+    g_assert(vm_base_port != 0);
+
+    return vm_base_port;
+}
+
+int get_vm_spice_port(void)
+{
+    // should not be called before base port is prepared
+    g_assert(vm_base_port != 0);
+
+    return vm_base_port + SPICE_TCP_INDEX;
+}
+
+int get_vm_device_serial_number(void)
+{
+    // should not be called before base port is prepared
+    g_assert(vm_base_port != 0);
+
+    if (is_netclient_tap_attached()) {
+        return (START_VM_BASE_PORT + SDB_TCP_INDEX);
+    }
+
+    return vm_base_port + SDB_TCP_INDEX;
+}
+
 // look-up PCI devices
 bool is_pci_device_enabled(int device_id)
 {
index 00223b9649805e28662f8a4f2dc0c8caaf102510..bcdc04e8d910197f3512f10e969f5bcb9e399198 100644 (file)
@@ -93,17 +93,12 @@ enum {
 
 typedef  struct EmulatorConfigInfo {
     int sdl_bpp;
-    int vm_base_port;
-    int device_serial_number;
-    int ecs_port;
 
     char guest_ip[16];
     char host_ip[16];
 
-    int spice_port;
     const char *skin_path;
     const char *file_sharing_path;
-    int serial_port;
     /* add here */
 } EmulatorConfigInfo;
 
@@ -124,8 +119,6 @@ typedef struct EmulatorConfigState {
 /* setter */
 void set_emul_win_scale(double scale);
 void set_emul_sdl_bpp(int bpp);
-void set_emul_vm_base_port(int port);
-void set_emul_ecs_port(int port);
 void set_emul_guest_ip(char *ip);
 void set_emul_host_ip(char *ip);
 
@@ -140,11 +133,6 @@ void set_sdb_connection(bool connected);
 /* getter */
 double get_emul_win_scale(void);
 int get_emul_sdl_bpp(void);
-int get_emul_vm_base_port(void);
-int get_device_serial_number(void);
-int get_emul_ecs_port(void);
-int get_emul_serial_port(void);
-int get_emul_spice_port(void);
 const char* get_emul_skin_path(void);
 bool get_emul_cpu_accel(void);
 
@@ -194,6 +182,11 @@ bool is_netclient_tap_attached(void);
 
 uint64_t get_ram_size(void);
 
+void set_vm_base_port(int port);
+int get_vm_base_port(void);
+int get_vm_device_serial_number(void);
+int get_vm_spice_port(void);
+
 void set_initial_display_resolution(int width, int height);
 int get_display_resolution_width(void);
 int get_display_resolution_height(void);
index e5d7ab926349bd3de498751f16b1432b02fc2f9e..0e1277989b6a0242be919c643d4af4e1fdb048a0 100644 (file)
@@ -42,8 +42,7 @@
 #include "emulator_options.h"
 #include "util/error_handler.h"
 #include "util/osutil.h"
-#include "util/sdb.h"
-#include "util/new_debug_ch.h"
+#include "util/net_helper.h"
 #include "ecs/ecs.h"
 #include "util/device_hotplug.h"
 #include "util/exported_strings.h"
@@ -66,6 +65,7 @@
 int thread_running = 1; /* Check if we need exit main */
 #endif
 
+#include "util/new_debug_ch.h"
 DECLARE_DEBUG_CHANNEL(main);
 
 #define ARGS_LIMIT  128
@@ -274,15 +274,11 @@ const char *prepare_maru(const char * const kernel_cmdline)
 
     init_emul_state();
 
-    // We should call socket_init() here since this function called
-    // before calling socket_init() in "vl.c".
-    // It is safe to call socket_init() multiple times.
-    socket_init();
-    init_vm_base_port();
+    init_sdb_and_vm_base_port();
 
     // Assemble new kernel cmdline
     maru_kernel_cmdline = g_strdup_printf("%s sdb_port=%d, "
-            "vm_resolution=%dx%d", kernel_cmdline, get_emul_vm_base_port(),
+            "vm_resolution=%dx%d", kernel_cmdline, get_vm_base_port(),
             get_display_resolution_width(), get_display_resolution_height());
     set_emul_host_ip(maru_kernel_cmdline);
     LOG_INFO("kernel commandline : %s\n", maru_kernel_cmdline);
@@ -295,7 +291,6 @@ void prepare_maru_after_device_init(void)
     make_vm_lock_os();
     init_device_hotplug();
     start_ecs();
-    init_sdb(get_emul_vm_base_port());
 
     // Only for intent logging of essential information
     get_vm_name();
index 2fcf610ce62cb4cac78e9eb91dc0cb2019f24b7f..179d70544ae35d21b3b4508b24090fc60f5b7e11 100644 (file)
@@ -31,7 +31,7 @@
 #include "sysemu/sysemu.h"
 
 #include "debug_ch.h"
-#include "util/sdb.h"
+#include "util/net_helper.h"
 
 /* define debug channel */
 MULTI_DEBUG_CHANNEL(tizen, power_mgr);
index 307b600bf77a5b21e5fb38faeec5c7848d3c3808..5f8a5ae4e438b5a379688d322453218a461d259a 100644 (file)
@@ -45,6 +45,7 @@ void qemu_system_reset_request(void);
 #define MENU_ACTION_REBOOT      1
 void send_shutdown_request(int action);
 
+#include "util/net_helper.h"
 #include "util/osutil.h"
 #include "util/device_hotplug.h"
 #include "util/ui_operations.h"
@@ -76,7 +77,7 @@ ContextMenu::ContextMenu(QWidget *parent) : QMenu(parent)
     this->controllerMapper = NULL;
 
     vmName = this->parent->getUiInfo()->getVmName() + " : "
-        + QString::number(get_device_serial_number());
+        + QString::number(get_vm_device_serial_number());
 
     /* for SDB shell */
     shellOpener = new ShellOpener();
index 3c2181eda7f882c6b2937d148b84ea639caa2ada..bae1553eb7995c492f55a2449f88b5928274a718 100644 (file)
@@ -46,7 +46,6 @@ class MainWindow;
 
 extern "C" {
 #include "emul_state.h"
-#include "util/sdb.h"
 }
 
 #define CLOSE_POWER_KEY_INTERVAL 1200 /* milli-seconds */
index 36f393b17a5da8f354dd43700fd7ec460bfcb0f3..b41798c905b40797bdc68825ef74437067b31f3a 100644 (file)
@@ -53,7 +53,7 @@ ScreenShotDialog::ScreenShotDialog(QWidget *parent) :
 
     setWindowTitle(QString(SCREENSHOT_TITLE) + " - " +
         win->getUiInfo()->getVmName() + " : " +
-        QString::number(get_device_serial_number()));
+        QString::number(get_vm_device_serial_number()));
     setWindowIcon(QIcon(":/icons/screen_shot.png"));
 
     dialogLayout = new QGridLayout(this);
index 76ebb50e4be3dee944c096153bc93b0e144b94a2..c4f52492f6ecd63f37076507cdb00250b8df64db 100644 (file)
@@ -57,7 +57,7 @@ void ShellOpener::openShell(QString title)
     QString command;
     QStringList arguments;
 
-    QString sdbPort = QString::number(get_device_serial_number());
+    QString sdbPort = QString::number(get_vm_device_serial_number());
     QString sdbSerialName;
     if (is_netclient_tap_attached()) {
         sdbSerialName = QString(get_emul_guest_ip());
index cb681950e7ed91833a546d76fd80064810aaafb4..4de20ab393a15665865ec1518e6f0d0d0d6d18bc 100644 (file)
@@ -117,7 +117,7 @@ static void qt5_gui_init(void)
 
     uiInfo->setResolution(QSize(
         get_display_resolution_width(), get_display_resolution_height()));
-    uiInfo->setBasePort(get_emul_vm_base_port());
+    uiInfo->setBasePort(get_vm_base_port());
     qDebug() << "VM base port:" <<  uiInfo->getBasePort();
 
     uiInfo->setVmDataPath(QDir(
index 6c2564f2f1f4c79fe9a378c2096988da3d94339c..a4a2969fcc972bc8fd8fa8e79c3d8a7d76004402 100644 (file)
@@ -19,8 +19,8 @@ obj-$(CONFIG_DARWIN) += osutil-darwin.o
 # tap helper
 obj-$(CONFIG_LINUX) += tap_helper.o
 
-#sdb
-obj-y += sdb.o
+# net helper
+obj-y += net_helper.o
 
 # hotplug
 obj-y += device_hotplug.o
diff --git a/tizen/src/util/net_helper.c b/tizen/src/util/net_helper.c
new file mode 100644 (file)
index 0000000..4a0454b
--- /dev/null
@@ -0,0 +1,633 @@
+/*
+ * Net helper
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  MunKyu Im       <munkyu.im@samsung.com>
+ *  Jinhyung Choi   <jinh0.choi@samsung.com>
+ *  SeokYeon Hwnag  <syeon.hwang@samsung.com>
+ *  Sangho Park     <sangho.p@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include "net_helper.h"
+
+#include "qemu/sockets.h"
+#include "net/slirp.h"
+#include "block/nbd.h"
+#include "qemu/error-report.h"
+
+#include "emulator.h"
+#include "emulator_common.h"
+#include "emul_state.h"
+
+#include "hw/virtio/maru_virtio_hwkey.h"
+#include "hw/maru_pm.h"
+#include "ecs/ecs.h"
+#include "new_debug_ch.h"
+
+DECLARE_DEBUG_CHANNEL(sdb);
+
+#ifdef CONFIG_JAVA_UI
+#include "skin/maruskin_server.h"
+#endif
+
+#define BUF_SIZE 64
+
+int emul_vm_base_socket;
+static bool sdb_daemon_is_initialized = false;
+#ifdef _WIN32
+#include "qemu/main-loop.h"
+
+static void socket_close_handler( void*  _fd )
+{
+    int   fd = (int)(uintptr_t)_fd;
+    int   ret;
+    char  buff[BUF_SIZE];
+
+    /* we want to drain the read side of the socket before closing it */
+    do {
+        ret = recv( fd, buff, sizeof(buff), 0 );
+    } while (ret < 0 && WSAGetLastError() == WSAEINTR);
+
+    if (ret < 0 && WSAGetLastError() == EWOULDBLOCK)
+        return;
+
+    qemu_set_fd_handler( fd, NULL, NULL, NULL );
+    closesocket( fd );
+}
+
+void socket_close( int  fd )
+{
+    int  old_errno = errno;
+
+    shutdown( fd, SD_BOTH );
+    /* we want to drain the socket before closing it */
+    qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)(uintptr_t)fd );
+
+    errno = old_errno;
+}
+
+#else /* !_WIN32 */
+
+#include <unistd.h>
+
+void socket_close( int  fd )
+{
+    int  old_errno = errno;
+
+    shutdown( fd, SHUT_RDWR );
+    close( fd );
+
+    errno = old_errno;
+}
+
+#endif /* !_WIN32 */
+
+int inet_strtoip(const char*  str, uint32_t  *ip)
+{
+    int  comp[4];
+
+    if (sscanf(str, "%d.%d.%d.%d", &comp[0], &comp[1], &comp[2], &comp[3]) != 4)
+        return -1;
+
+    if ((unsigned)comp[0] >= 256 ||
+            (unsigned)comp[1] >= 256 ||
+            (unsigned)comp[2] >= 256 ||
+            (unsigned)comp[3] >= 256)
+        return -1;
+
+    *ip = (uint32_t)((comp[0] << 24) | (comp[1] << 16) |
+            (comp[2] << 8)  |  comp[3]);
+    return 0;
+}
+
+int check_port_bind_listen(uint32_t port)
+{
+    struct sockaddr_in addr;
+    int ret = -1;
+    addr.sin_family = AF_INET;
+    addr.sin_port = htons(port);
+
+    if (inet_aton(HOST_LISTEN_ADDR, &addr.sin_addr) == 0) {
+        LOG_SEVERE("inet_aton failure\n");
+        return -1;
+    }
+
+    ret = qemu_socket(PF_INET, SOCK_STREAM, 0);
+    if (ret < 0) {
+        LOG_SEVERE("socket creation failed.\n");
+        return -1;
+    }
+
+    qemu_set_nonblock(ret);
+
+    if (socket_set_fast_reuse(ret) != 0) {
+        LOG_SEVERE("It cannot be reach here.\n");
+        closesocket(ret);
+        return -1;
+    }
+
+    if (bind(ret, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
+        LOG_INFO("bind failed for port: %d, errno: %d\n", port, errno);
+        closesocket(ret);
+        return -1;
+    }
+
+    if (listen(ret, 1) != 0) {
+        LOG_SEVERE("listen failed :%s-%d\n", strerror(errno), errno);
+        closesocket(ret);
+        return -1;
+    }
+
+    return ret;
+}
+
+static int prepare_network_port(uint32_t base_port)
+{
+    int ret = -1;
+
+    /* no need to redir if network is tap */
+    if (!is_netclient_tap_attached()) {
+        if (!hostfwd_try_add(0, NULL, base_port + SDB_TCP_INDEX,
+                NULL, SDB_GUEST_PORT)) {
+            LOG_INFO("TCP port %"PRIu32" is aleady occupied",
+                    base_port + SDB_TCP_INDEX);
+
+            return -1;
+        }
+
+        if (!hostfwd_try_add(0, NULL, base_port + GDB_TCP_INDEX,
+                NULL, GDB_GUEST_PORT)) {
+            LOG_INFO("TCP port %"PRIu32" is aleady occupied",
+                    base_port + GDB_TCP_INDEX);
+            hostfwd_try_remove(0, NULL, base_port + SDB_TCP_INDEX);
+
+            return -1;
+        }
+    }
+
+    if ((ret = check_port_bind_listen(base_port + ECS_TCP_INDEX)) < 0) {
+        LOG_INFO("TCP port %"PRIu32" is aleady occupied",
+                base_port + ECS_TCP_INDEX);
+
+        if (!is_netclient_tap_attached()) {
+            hostfwd_try_remove(0, NULL, base_port + SDB_TCP_INDEX);
+            hostfwd_try_remove(0, NULL, base_port + GDB_TCP_INDEX);
+        }
+
+        return -1;
+    }
+
+    g_assert(ret >= 0);
+
+    // save ecs socket fd as global variable
+    // FIXME: should not use global variable.
+    emul_vm_base_socket = ret;
+
+    return ret;
+}
+
+static void start_sdb_noti_server(int server_port);
+
+void init_sdb_and_vm_base_port(void)
+{
+    uint32_t port = 0;
+
+    for (port = START_VM_BASE_PORT ; port < END_VM_BASE_PORT; port += 10) {
+        if (prepare_network_port(port) < 0) {
+            continue;
+        }
+
+        break;
+    }
+
+    if (port >= END_VM_BASE_PORT) {
+        error_report("It seems too many emulator instances are "
+                "running on this machine. Aborting.");
+        exit(1);
+    }
+
+    LOG_INFO("Emulator base port is %"PRIu32".\n", port);
+
+    start_sdb_noti_server(port + SDB_UDP_NOTI_PORT_INDEX);
+
+    set_vm_base_port(port);
+}
+
+/*
+ * SDB Notification server
+ */
+
+#define RECV_BUF_SIZE 32
+typedef struct SDB_Noti_Server {
+    int server_fd;
+    GIOChannel *server_chan;
+    guint server_tag;
+} SDB_Noti_Server;
+
+typedef struct SDB_Client {
+    int port;
+    struct sockaddr_in addr;
+    char serial[RECV_BUF_SIZE];
+
+    QTAILQ_ENTRY(SDB_Client) next;
+} SDB_Client;
+
+static QTAILQ_HEAD(SDB_ClientHead, SDB_Client)
+clients = QTAILQ_HEAD_INITIALIZER(clients);
+
+static SDB_Noti_Server *current_server;
+static QemuMutex mutex_clients;
+
+static void remove_sdb_client(SDB_Client* client)
+{
+    if (client == NULL) {
+        return;
+    }
+
+    qemu_mutex_lock(&mutex_clients);
+
+    QTAILQ_REMOVE(&clients, client, next);
+
+    qemu_mutex_unlock(&mutex_clients);
+
+    g_free(client);
+}
+
+static void send_to_sdb_client(SDB_Client* client, int state)
+{
+    struct sockaddr_in sock_addr;
+    int s, slen = sizeof(sock_addr);
+    int serial_len = 0;
+    char buf[BUF_SIZE];
+
+    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1){
+          LOG_INFO("socket creation error! %d\n", errno);
+          return;
+    }
+
+    memset(&sock_addr, 0, sizeof(sock_addr));
+
+    sock_addr.sin_family = AF_INET;
+    sock_addr.sin_port = htons(client->port);
+    sock_addr.sin_addr = (client->addr).sin_addr;
+
+    if (connect(s, (struct sockaddr*)&sock_addr, slen) == -1) {
+        LOG_INFO("connect error! remove this client.\n");
+        remove_sdb_client(client);
+        close(s);
+        return;
+    }
+
+    memset(buf, 0, sizeof(buf));
+
+    serial_len = strlen(client->serial);
+
+    // send message "[4 digit message length]host:sync:emulator-26101:[0|1]"
+    sprintf(buf, "%04xhost:sync:%s:%01d", (serial_len + 12), client->serial, state);
+
+    LOG_INFO("send %s to client %s\n", buf, inet_ntoa(client->addr.sin_addr));
+
+    if (send(s, buf, sizeof(buf), 0) == -1)
+    {
+        LOG_INFO("send error! remove this client.\n");
+        remove_sdb_client(client);
+    }
+
+    close(s);
+}
+
+void notify_all_sdb_clients(int state)
+{
+    qemu_mutex_lock(&mutex_clients);
+    SDB_Client *client, *next;
+
+    QTAILQ_FOREACH_SAFE(client, &clients, next, next)
+    {
+        send_to_sdb_client(client, state);
+    }
+    qemu_mutex_unlock(&mutex_clients);
+
+}
+
+static void add_sdb_client(struct sockaddr_in* addr, int port, const char* serial)
+{
+    SDB_Client *cli = NULL;
+    SDB_Client *client = NULL, *next;
+
+    if (addr == NULL) {
+        LOG_INFO("SDB_Client client's address is EMPTY.\n");
+        return;
+    } else if (serial == NULL || strlen(serial) <= 0) {
+        LOG_INFO("SDB_Client client's serial is EMPTY.\n");
+        return;
+    } else if (strlen(serial) > RECV_BUF_SIZE) {
+        LOG_INFO("SDB_Client client's serial is too long. %s\n", serial);
+        return;
+    }
+
+    qemu_mutex_lock(&mutex_clients);
+    QTAILQ_FOREACH_SAFE(cli, &clients, next, next)
+    {
+        if (!strcmp(serial, cli->serial) && !strcmp(inet_ntoa(addr->sin_addr), inet_ntoa((cli->addr).sin_addr))) {
+            LOG_INFO("Client cannot be duplicated.\n");
+            qemu_mutex_unlock(&mutex_clients);
+            return;
+        }
+    }
+    qemu_mutex_unlock(&mutex_clients);
+
+    client = g_malloc0(sizeof(SDB_Client));
+    if (NULL == client) {
+        LOG_INFO("SDB_Client allocation failed.\n");
+        return;
+    }
+
+    memcpy(&client->addr, addr, sizeof(struct sockaddr_in));
+    client->port = port;
+    strcpy(client->serial, serial);
+
+    qemu_mutex_lock(&mutex_clients);
+
+    QTAILQ_INSERT_TAIL(&clients, client, next);
+
+    qemu_mutex_unlock(&mutex_clients);
+
+    LOG_INFO("Added new sdb client. ip: %s, port: %d, serial: %s\n", inet_ntoa((client->addr).sin_addr), client->port, client->serial);
+
+    send_to_sdb_client(client, runstate_check(RUN_STATE_SUSPENDED));
+}
+
+static int parse_val(char* buff, unsigned char data, char* parsbuf)
+{
+    int count = 0;
+
+    while (1) {
+        if (count > 12) {
+            return -1;
+        }
+
+        if (buff[count] == data) {
+            count++;
+            strncpy(parsbuf, buff, count);
+            return count;
+        }
+
+        count++;
+    }
+
+    return 0;
+}
+
+#define SDB_SERVER_PORT 26097
+static void register_sdb_server(char* readbuf, struct sockaddr_in* client_addr)
+{
+    int port = 0;
+    char token[] = "\n";
+    char* ret = NULL;
+    char* serial = NULL;
+
+    ret = strtok(readbuf, token);
+    if (ret == NULL) {
+        LOG_INFO("command is not found.");
+        return;
+    }
+
+    serial = strtok(NULL, token);
+    if (serial == NULL) {
+        LOG_INFO("serial is not found.");
+        return;
+    }
+
+    port = SDB_SERVER_PORT;
+
+    add_sdb_client(client_addr, port, serial);
+}
+
+#define PRESS     1
+#define RELEASE   2
+#define POWER_KEY 116
+static void wakeup_guest(void)
+{
+    // FIXME: Temporarily working model.
+    // It must be fixed as the way it works.
+    maru_hwkey_event(PRESS, POWER_KEY);
+    maru_hwkey_event(RELEASE, POWER_KEY);
+}
+
+static void suspend_lock_state(int state)
+{
+    ecs_suspend_lock_state(state);
+}
+
+static void command_handler(char* readbuf, struct sockaddr_in* client_addr)
+{
+    char command[RECV_BUF_SIZE];
+    memset(command, '\0', sizeof(command));
+
+    parse_val(readbuf, 0x0a, command);
+
+    LOG_TRACE("----------------------------------------\n");
+    LOG_TRACE("command:%s\n", command);
+    if (strcmp(command, "2\n" ) == 0) {
+#ifdef CONFIG_JAVA_UI
+        notify_sdb_daemon_start();
+#endif
+        sdb_daemon_is_initialized = true;
+    } else if (strcmp(command, "5\n") == 0) {
+        register_sdb_server(readbuf, client_addr);
+        set_sdb_connection(true);
+    } else if (strcmp(command, "6\n") == 0) {
+        wakeup_guest();
+    } else if (strcmp(command, "7\n") == 0) {
+        suspend_lock_state(SUSPEND_LOCK);
+    } else if (strcmp(command, "8\n") == 0) {
+        suspend_lock_state(SUSPEND_UNLOCK);
+    } else {
+        LOG_INFO("!!! unknown command : %s\n", command);
+    }
+    LOG_TRACE("========================================\n");
+}
+
+static void close_clients(void)
+{
+    qemu_mutex_lock(&mutex_clients);
+    SDB_Client * client, *next;
+
+    QTAILQ_FOREACH_SAFE(client, &clients, next, next)
+    {
+        QTAILQ_REMOVE(&clients, client, next);
+
+        if (NULL != client)
+        {
+            g_free(client);
+        }
+    }
+
+    qemu_mutex_unlock(&mutex_clients);
+}
+
+static void close_server(void)
+{
+    if (current_server == NULL) {
+        return;
+    }
+
+    close_clients();
+
+    if (current_server->server_fd > 0) {
+        if (current_server->server_tag) {
+            g_source_remove(current_server->server_tag);
+            current_server->server_tag = 0;
+        }
+        if (current_server->server_chan) {
+            g_io_channel_unref(current_server->server_chan);
+        }
+        closesocket(current_server->server_fd);
+    }
+
+    g_free(current_server);
+
+    qemu_mutex_destroy(&mutex_clients);
+}
+
+static gboolean sdb_noti_read(GIOChannel *channel, GIOCondition cond, void *opaque)
+{
+    int recv_cnt = 0;
+    struct sockaddr_in client_addr;
+    socklen_t client_len = sizeof(client_addr);
+    char readbuf[RECV_BUF_SIZE + 1];
+    SDB_Noti_Server *server = opaque;
+
+    memset(&readbuf, 0, sizeof(readbuf));
+
+    recv_cnt = recvfrom(server->server_fd, readbuf, RECV_BUF_SIZE, 0,
+                        (struct sockaddr*) &client_addr, &client_len);
+
+    if (recv_cnt > 0) {
+        command_handler((char*)readbuf, &client_addr);
+    } else if (recv_cnt == 0) {
+        LOG_INFO("noti server recvfrom returned 0.\n");
+    } else {
+#ifdef _WIN32
+        errno = WSAGetLastError();
+#endif
+        LOG_TRACE("recvfrom error case (it can be from non-blocking socket): %d", errno);
+    }
+
+    return TRUE;
+}
+
+static int create_UDP_server(SDB_Noti_Server *server, int port)
+{
+    struct sockaddr_in server_addr;
+    int opt = 1;
+
+    if ((server->server_fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
+        LOG_INFO("create listen socket error:%d\n", errno);
+        return -1;
+    }
+
+    memset(&server_addr, '\0', sizeof(server_addr));
+    server_addr.sin_family = PF_INET;
+    server_addr.sin_addr.s_addr = INADDR_ANY;
+    server_addr.sin_port = htons(port);
+
+    qemu_set_nonblock(server->server_fd);
+
+    if (qemu_setsockopt(server->server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {
+        LOG_INFO("setsockopt SO_REUSEADDR is failed.: %d\n", errno);
+        return -1;
+    }
+
+    if (bind(server->server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
+        LOG_INFO("sdb noti server bind error: %d", errno);
+        return -1;
+    }
+
+    return 0;
+}
+
+static GIOChannel *io_channel_from_socket(int fd)
+{
+    GIOChannel *chan;
+
+    if (fd == -1) {
+        return NULL;
+    }
+
+#ifdef _WIN32
+    chan = g_io_channel_win32_new_socket(fd);
+#else
+    chan = g_io_channel_unix_new(fd);
+#endif
+
+    g_io_channel_set_encoding(chan, NULL, NULL);
+    g_io_channel_set_buffered(chan, FALSE);
+
+    return chan;
+}
+
+static void sdb_noti_server_notify_exit(Notifier *notifier, void *data)
+{
+    LOG_INFO("shutdown sdb notification server.\n");
+    close_server();
+}
+
+static Notifier sdb_noti_server_exit = { .notify = sdb_noti_server_notify_exit };
+
+static void start_sdb_noti_server(int server_port)
+{
+    SDB_Noti_Server *server;
+    int ret;
+
+    LOG_INFO("start sdb noti server thread.\n");
+
+    server = g_malloc0(sizeof(SDB_Noti_Server));
+    if (server == NULL) {
+        LOG_INFO("SDB Notification server allocation is failed.\n");
+        return;
+    }
+
+    ret = create_UDP_server(server, server_port);
+    if (ret < 0) {
+        LOG_INFO("failed to create UDP server\n");
+        close_server();
+        return;
+    }
+
+    server->server_chan = io_channel_from_socket(server->server_fd);
+    server->server_tag = g_io_add_watch(server->server_chan, G_IO_IN, sdb_noti_read, server);
+
+    current_server = server;
+
+    qemu_mutex_init(&mutex_clients);
+
+    LOG_INFO("success to bind port[127.0.0.1:%d/udp] for sdb noti server in host \n", server_port);
+
+    emulator_add_exit_notifier(&sdb_noti_server_exit);
+}
+
+bool is_sdb_daemon_initialized(void)
+{
+    return sdb_daemon_is_initialized;
+}
diff --git a/tizen/src/util/net_helper.h b/tizen/src/util/net_helper.h
new file mode 100644 (file)
index 0000000..be0651f
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Net helper
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  MunKyu Im       <munkyu.im@samsung.com>
+ *  Jinhyung Choi   <jinh0.choi@samsung.com>
+ *  SeokYeon Hwnag  <syeon.hwang@samsung.com>
+ *  Sangho Park     <sangho.p@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef SDB_SERVER_H_
+#define SDB_SERVER_H_
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else /* !_WIN32 */
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#endif /* !_WIN32 */
+
+
+#define SDB_HOST_PORT 26099
+
+#define START_VM_BASE_PORT 26100
+#define END_VM_BASE_PORT 26200
+
+#define SDB_TCP_INDEX 1
+#define GDB_TCP_INDEX 2
+#define ECS_TCP_INDEX 3
+#define SPICE_TCP_INDEX 3
+#define SDB_UDP_NOTI_PORT_INDEX 3
+
+#define SDB_GUEST_PORT  (START_VM_BASE_PORT + SDB_TCP_INDEX)
+#define GDB_GUEST_PORT  (START_VM_BASE_PORT + GDB_TCP_INDEX)
+
+void init_sdb_and_vm_base_port(void);
+int inet_strtoip(const char*  str, uint32_t  *ip);
+int socket_send(int fd, const void*  buf, int  buflen);
+void socket_close(int fd);
+int check_port_bind_listen(uint32_t port);
+bool is_sdb_daemon_initialized(void);
+
+extern int emul_vm_base_socket;
+
+#define STATE_RUNNING 0
+#define STATE_SUSPEND 1
+void notify_all_sdb_clients(int state);
+
+#endif
+
index 39455805379cb3a3d93659d7da6308e5d9d574f7..62ae4a30d64f20526a3ead1882554550347924bc 100644 (file)
@@ -39,7 +39,6 @@
 #include "emulator.h"
 #include "emul_state.h"
 #include "debug_ch.h"
-#include "sdb.h"
 #include "emulator_options.h"
 
 #ifndef CONFIG_DARWIN
@@ -79,7 +78,7 @@ void make_vm_lock_os(void)
 {
     char *shared_memory;
     int base_port;
-    base_port = get_emul_vm_base_port();
+    base_port = get_vm_base_port();
     g_shmid = shmget((key_t)base_port, getpagesize(), 0666|IPC_CREAT);
     if (g_shmid == -1) {
         ERR("shmget failed\n");
index 5ea0d6580f25ede9e18cc9eb7645cb7ba0b6ef70..d0cd9cedfbb8f3f49760fa8f630d5d555dfa8c8b 100644 (file)
@@ -49,7 +49,7 @@
 #include "osutil.h"
 #include "emulator.h"
 #include "emul_state.h"
-#include "sdb.h"
+#include "net_helper.h"
 #include "emulator_options.h"
 
 #ifndef CONFIG_LINUX
@@ -92,9 +92,12 @@ void check_vm_lock_os(void)
                         continue;
                     }
                     shmdt(shm_addr);
+                    // FIXME: VM lock logic should be refactored ASAP.
+#if 0
                     error_report("Can not execute this VM. "
                             "The same name is running now.");
                     exit(1);
+#endif
                 } else {
                     shmdt(shm_addr);
                 }
@@ -124,7 +127,7 @@ void make_vm_lock_os(void)
 
     check_vm_lock_os();
 
-    base_port = get_emul_vm_base_port();
+    base_port = get_vm_base_port();
 
     g_shmid = shmget((key_t)base_port, getpagesize(), 0666|IPC_CREAT);
     if (g_shmid == -1) {
index a904ea5a0aa002c06b868c8ed2d4d8e97cdcff21..70ce715d6131773a5ee3a3ebf394a09632e54bfb 100644 (file)
@@ -39,7 +39,6 @@
 #include "osutil.h"
 #include "emulator.h"
 #include "emul_state.h"
-#include "sdb.h"
 #include "emulator_options.h"
 
 #ifndef CONFIG_WIN32
@@ -120,7 +119,7 @@ void make_vm_lock_os(void)
 
     check_vm_lock_os();
 
-    base_port = get_emul_vm_base_port();
+    base_port = get_vm_base_port();
     shared_memory = g_strdup_printf("%s", get_drive_image_file());
     port_in_use =  g_strdup_printf("%d", base_port);
     g_hMapFile = CreateFileMapping(
diff --git a/tizen/src/util/sdb.c b/tizen/src/util/sdb.c
deleted file mode 100644 (file)
index ccdd13c..0000000
+++ /dev/null
@@ -1,649 +0,0 @@
-/*
- * Emulator SDB Notification Server
- *
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Jinhyung choi   <jinhyung2.choi@samsung.com>
- *  MunKyu Im       <munkyu.im@samsung.com>
- *  Sangho Park     <sangho1206.park@samsung.com>
- *  YeongKyoon Lee  <yeongkyoon.lee@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-
-#include "net/slirp.h"
-#include "qemu/sockets.h"
-#include "sdb.h"
-#include "block/nbd.h"
-
-#include "emulator.h"
-#include "emulator_common.h"
-#include "emul_state.h"
-
-#include "hw/virtio/maru_virtio_hwkey.h"
-#include "hw/maru_pm.h"
-#include "ecs/ecs.h"
-#include "debug_ch.h"
-
-MULTI_DEBUG_CHANNEL(qemu, sdb);
-
-#ifdef CONFIG_JAVA_UI
-#include "skin/maruskin_server.h"
-#endif
-
-#define SDB_INDEX 1
-#define GDB_INDEX 2
-#define ECS_INDEX 3
-#define SDB_NOTI_PORT_INDEX 3
-#define START_BASE_PORT 26100
-#define SDB_GUEST_PORT  (START_BASE_PORT + SDB_INDEX)
-#define GDB_GUEST_PORT  (START_BASE_PORT + GDB_INDEX)
-
-int emul_vm_base_socket;
-static bool sdb_daemon_is_initialized = false;
-#ifdef _WIN32
-#include "qemu/main-loop.h"
-
-static void socket_close_handler( void*  _fd )
-{
-    int   fd = (int)(uintptr_t)_fd;
-    int   ret;
-    char  buff[64];
-
-    /* we want to drain the read side of the socket before closing it */
-    do {
-        ret = recv( fd, buff, sizeof(buff), 0 );
-    } while (ret < 0 && WSAGetLastError() == WSAEINTR);
-
-    if (ret < 0 && WSAGetLastError() == EWOULDBLOCK)
-        return;
-
-    qemu_set_fd_handler( fd, NULL, NULL, NULL );
-    closesocket( fd );
-}
-
-void socket_close( int  fd )
-{
-    int  old_errno = errno;
-
-    shutdown( fd, SD_BOTH );
-    /* we want to drain the socket before closing it */
-    qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)(uintptr_t)fd );
-
-    errno = old_errno;
-}
-
-#else /* !_WIN32 */
-
-#include <unistd.h>
-
-void socket_close( int  fd )
-{
-    int  old_errno = errno;
-
-    shutdown( fd, SHUT_RDWR );
-    close( fd );
-
-    errno = old_errno;
-}
-
-#endif /* !_WIN32 */
-
-int inet_strtoip(const char*  str, uint32_t  *ip)
-{
-    int  comp[4];
-
-    if (sscanf(str, "%d.%d.%d.%d", &comp[0], &comp[1], &comp[2], &comp[3]) != 4)
-        return -1;
-
-    if ((unsigned)comp[0] >= 256 ||
-            (unsigned)comp[1] >= 256 ||
-            (unsigned)comp[2] >= 256 ||
-            (unsigned)comp[3] >= 256)
-        return -1;
-
-    *ip = (uint32_t)((comp[0] << 24) | (comp[1] << 16) |
-            (comp[2] << 8)  |  comp[3]);
-    return 0;
-}
-
-int check_port_bind_listen(uint32_t port)
-{
-    struct sockaddr_in addr;
-    int ret = -1;
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(port);
-
-    if (inet_aton(HOST_LISTEN_ADDR, &addr.sin_addr) == 0) {
-        LOG_SEVERE("inet_aton failure\n");
-        return -1;
-    }
-
-    ret = qemu_socket(PF_INET, SOCK_STREAM, 0);
-    if (ret < 0) {
-        LOG_SEVERE("socket creation failed.\n");
-        return -1;
-    }
-
-    qemu_set_nonblock(ret);
-
-    if (socket_set_fast_reuse(ret) != 0) {
-        LOG_SEVERE("It cannot be reach here.\n");
-        closesocket(ret);
-        return -1;
-    }
-
-    if (bind(ret, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
-        LOG_INFO("bind failed for port: %d, errno: %d\n", port, errno);
-        closesocket(ret);
-        return -1;
-    }
-
-    if (listen(ret, 1) != 0) {
-        LOG_SEVERE("listen failed :%s-%d\n", strerror(errno), errno);
-        closesocket(ret);
-        return -1;
-    }
-
-    return ret;
-}
-
-int find_available_port(uint32_t base_port)
-{
-    int ret = 0;
-    int i = 0;
-    for (i = SDB_INDEX; i <= ECS_INDEX; i++) {
-        ret = check_port_bind_listen(base_port + i);
-        if (ret >= 0 && i != ECS_INDEX) {
-            //TODO: Because of checking and closing socket,
-            // not guaranteed fully that sdb/gdb port is available,
-            // when the time call net_slirp_redir()
-            closesocket(ret);
-        } else if (ret < 0) {
-            LOG_INFO("port(%"PRIu32") is reserved.\n", base_port + i);
-            return -1;
-        }
-    }
-    // save ecs socket fd as global variable
-    emul_vm_base_socket = ret;
-    LOG_INFO("find available port: %"PRIu32"\n", base_port);
-    return ret;
-}
-
-void init_vm_base_port(void)
-{
-    int   tries     = 10;
-    int   success   = 0;
-    uint32_t port = START_BASE_PORT;
-    int base_port;
-
-    base_port = get_emul_vm_base_port();
-
-    if (base_port == 0) {
-
-        for ( ; tries > 0; tries--, port += 10 ) {
-            if (find_available_port(port) < 0) {
-                LOG_INFO("port(%d) is not available. It can be reserved.\n", port);
-                continue;
-            }
-
-            success = 1;
-            break;
-        }
-
-        if (!success) {
-            INFO( "it seems too many emulator instances are running on this machine. Aborting\n" );
-            exit(1);
-        }
-
-        base_port = port;
-        INFO( "emulator base port is %d\n", base_port);
-    }
-
-    set_emul_vm_base_port(base_port);
-}
-
-static void start_sdb_noti_server(int server_port);
-void init_sdb(int server_port)
-{
-    start_sdb_noti_server(server_port + SDB_NOTI_PORT_INDEX);
-
-    /* no need to redir if network is tap */
-    if (is_netclient_tap_attached()) {
-        return;
-    }
-
-    char buf_sdb[64] = {0,};
-    char buf_gdb[64] = {0,};
-
-    sprintf(buf_sdb, "tcp:%d::%d", server_port + SDB_INDEX, SDB_GUEST_PORT);
-    if (net_slirp_redir((char*)buf_sdb) < 0) {
-        LOG_WARNING("failed to redirect sdb port [%s]\n", buf_sdb);
-    } else {
-        INFO("redirect port for sdb [%s]\n", buf_sdb);
-    }
-
-    sprintf(buf_gdb, "tcp:%d::%d", server_port + GDB_INDEX, GDB_GUEST_PORT);
-    if (net_slirp_redir((char*)buf_gdb) < 0) {
-        LOG_WARNING("failed to redirect gdb port [%s]\n", buf_gdb);
-    } else {
-        INFO("redirect port for gdb [%s]\n", buf_gdb);
-    }
-}
-
-/*
- * SDB Notification server
- */
-
-#define RECV_BUF_SIZE 32
-typedef struct SDB_Noti_Server {
-    int server_fd;
-    GIOChannel *server_chan;
-    guint server_tag;
-} SDB_Noti_Server;
-
-typedef struct SDB_Client {
-    int port;
-    struct sockaddr_in addr;
-    char serial[RECV_BUF_SIZE];
-
-    QTAILQ_ENTRY(SDB_Client) next;
-} SDB_Client;
-
-static QTAILQ_HEAD(SDB_ClientHead, SDB_Client)
-clients = QTAILQ_HEAD_INITIALIZER(clients);
-
-static SDB_Noti_Server *current_server;
-static QemuMutex mutex_clients;
-
-static void remove_sdb_client(SDB_Client* client)
-{
-    if (client == NULL) {
-        return;
-    }
-
-    qemu_mutex_lock(&mutex_clients);
-
-    QTAILQ_REMOVE(&clients, client, next);
-
-    qemu_mutex_unlock(&mutex_clients);
-
-    g_free(client);
-}
-
-static void send_to_sdb_client(SDB_Client* client, int state)
-{
-    struct sockaddr_in sock_addr;
-    int s, slen = sizeof(sock_addr);
-    int serial_len = 0;
-    char buf [64];
-
-    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1){
-          INFO("socket creation error! %d\n", errno);
-          return;
-    }
-
-    memset(&sock_addr, 0, sizeof(sock_addr));
-
-    sock_addr.sin_family = AF_INET;
-    sock_addr.sin_port = htons(client->port);
-    sock_addr.sin_addr = (client->addr).sin_addr;
-
-    if (connect(s, (struct sockaddr*)&sock_addr, slen) == -1) {
-        INFO("connect error! remove this client.\n");
-        remove_sdb_client(client);
-        close(s);
-        return;
-    }
-
-    memset(buf, 0, sizeof(buf));
-
-    serial_len = strlen(client->serial);
-
-    // send message "[4 digit message length]host:sync:emulator-26101:[0|1]"
-    sprintf(buf, "%04xhost:sync:%s:%01d", (serial_len + 12), client->serial, state);
-
-    INFO("send %s to client %s\n", buf, inet_ntoa(client->addr.sin_addr));
-
-    if (send(s, buf, sizeof(buf), 0) == -1)
-    {
-        INFO("send error! remove this client.\n");
-        remove_sdb_client(client);
-    }
-
-    close(s);
-}
-
-void notify_all_sdb_clients(int state)
-{
-    qemu_mutex_lock(&mutex_clients);
-    SDB_Client *client, *next;
-
-    QTAILQ_FOREACH_SAFE(client, &clients, next, next)
-    {
-        send_to_sdb_client(client, state);
-    }
-    qemu_mutex_unlock(&mutex_clients);
-
-}
-
-static void add_sdb_client(struct sockaddr_in* addr, int port, const char* serial)
-{
-    SDB_Client *cli = NULL;
-    SDB_Client *client = NULL, *next;
-
-    if (addr == NULL) {
-        INFO("SDB_Client client's address is EMPTY.\n");
-        return;
-    } else if (serial == NULL || strlen(serial) <= 0) {
-        INFO("SDB_Client client's serial is EMPTY.\n");
-        return;
-    } else if (strlen(serial) > RECV_BUF_SIZE) {
-        INFO("SDB_Client client's serial is too long. %s\n", serial);
-        return;
-    }
-
-    qemu_mutex_lock(&mutex_clients);
-    QTAILQ_FOREACH_SAFE(cli, &clients, next, next)
-    {
-        if (!strcmp(serial, cli->serial) && !strcmp(inet_ntoa(addr->sin_addr), inet_ntoa((cli->addr).sin_addr))) {
-            INFO("Client cannot be duplicated.\n");
-            qemu_mutex_unlock(&mutex_clients);
-            return;
-        }
-    }
-    qemu_mutex_unlock(&mutex_clients);
-
-    client = g_malloc0(sizeof(SDB_Client));
-    if (NULL == client) {
-        INFO("SDB_Client allocation failed.\n");
-        return;
-    }
-
-    memcpy(&client->addr, addr, sizeof(struct sockaddr_in));
-    client->port = port;
-    strcpy(client->serial, serial);
-
-    qemu_mutex_lock(&mutex_clients);
-
-    QTAILQ_INSERT_TAIL(&clients, client, next);
-
-    qemu_mutex_unlock(&mutex_clients);
-
-    INFO("Added new sdb client. ip: %s, port: %d, serial: %s\n", inet_ntoa((client->addr).sin_addr), client->port, client->serial);
-
-    send_to_sdb_client(client, runstate_check(RUN_STATE_SUSPENDED));
-}
-
-static int parse_val(char* buff, unsigned char data, char* parsbuf)
-{
-    int count = 0;
-
-    while (1) {
-        if (count > 12) {
-            return -1;
-        }
-
-        if (buff[count] == data) {
-            count++;
-            strncpy(parsbuf, buff, count);
-            return count;
-        }
-
-        count++;
-    }
-
-    return 0;
-}
-
-#define SDB_SERVER_PORT 26097
-static void register_sdb_server(char* readbuf, struct sockaddr_in* client_addr)
-{
-    int port = 0;
-    char token[] = "\n";
-    char* ret = NULL;
-    char* serial = NULL;
-
-    ret = strtok(readbuf, token);
-    if (ret == NULL) {
-        INFO("command is not found.");
-        return;
-    }
-
-    serial = strtok(NULL, token);
-    if (serial == NULL) {
-        INFO("serial is not found.");
-        return;
-    }
-
-    port = SDB_SERVER_PORT;
-
-    add_sdb_client(client_addr, port, serial);
-}
-
-#define PRESS     1
-#define RELEASE   2
-#define POWER_KEY 116
-static void wakeup_guest(void)
-{
-    // FIXME: Temporarily working model.
-    // It must be fixed as the way it works.
-    maru_hwkey_event(PRESS, POWER_KEY);
-    maru_hwkey_event(RELEASE, POWER_KEY);
-}
-
-static void suspend_lock_state(int state)
-{
-    ecs_suspend_lock_state(state);
-}
-
-static void command_handler(char* readbuf, struct sockaddr_in* client_addr)
-{
-    char command[RECV_BUF_SIZE];
-    memset(command, '\0', sizeof(command));
-
-    parse_val(readbuf, 0x0a, command);
-
-    TRACE("----------------------------------------\n");
-    TRACE("command:%s\n", command);
-    if (strcmp(command, "2\n" ) == 0) {
-#ifdef CONFIG_JAVA_UI
-        notify_sdb_daemon_start();
-#endif
-        sdb_daemon_is_initialized = true;
-    } else if (strcmp(command, "5\n") == 0) {
-        register_sdb_server(readbuf, client_addr);
-        set_sdb_connection(true);
-    } else if (strcmp(command, "6\n") == 0) {
-        wakeup_guest();
-    } else if (strcmp(command, "7\n") == 0) {
-        suspend_lock_state(SUSPEND_LOCK);
-    } else if (strcmp(command, "8\n") == 0) {
-        suspend_lock_state(SUSPEND_UNLOCK);
-    } else {
-        INFO("!!! unknown command : %s\n", command);
-    }
-    TRACE("========================================\n");
-}
-
-static void close_clients(void)
-{
-    qemu_mutex_lock(&mutex_clients);
-    SDB_Client * client, *next;
-
-    QTAILQ_FOREACH_SAFE(client, &clients, next, next)
-    {
-        QTAILQ_REMOVE(&clients, client, next);
-
-        if (NULL != client)
-        {
-            g_free(client);
-        }
-    }
-
-    qemu_mutex_unlock(&mutex_clients);
-}
-
-static void close_server(void)
-{
-    if (current_server == NULL) {
-        return;
-    }
-
-    close_clients();
-
-    if (current_server->server_fd > 0) {
-        if (current_server->server_tag) {
-            g_source_remove(current_server->server_tag);
-            current_server->server_tag = 0;
-        }
-        if (current_server->server_chan) {
-            g_io_channel_unref(current_server->server_chan);
-        }
-        closesocket(current_server->server_fd);
-    }
-
-    g_free(current_server);
-
-    qemu_mutex_destroy(&mutex_clients);
-}
-
-static gboolean sdb_noti_read(GIOChannel *channel, GIOCondition cond, void *opaque)
-{
-    int recv_cnt = 0;
-    struct sockaddr_in client_addr;
-    socklen_t client_len = sizeof(client_addr);
-    char readbuf[RECV_BUF_SIZE + 1];
-    SDB_Noti_Server *server = opaque;
-
-    memset(&readbuf, 0, sizeof(readbuf));
-
-    recv_cnt = recvfrom(server->server_fd, readbuf, RECV_BUF_SIZE, 0,
-                        (struct sockaddr*) &client_addr, &client_len);
-
-    if (recv_cnt > 0) {
-        command_handler((char*)readbuf, &client_addr);
-    } else if (recv_cnt == 0) {
-        INFO("noti server recvfrom returned 0.\n");
-    } else {
-#ifdef _WIN32
-        errno = WSAGetLastError();
-#endif
-        TRACE("recvfrom error case (it can be from non-blocking socket): %d", errno);
-    }
-
-    return TRUE;
-}
-
-static int create_UDP_server(SDB_Noti_Server *server, int port)
-{
-    struct sockaddr_in server_addr;
-    int opt = 1;
-
-    if ((server->server_fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
-        INFO("create listen socket error:%d\n", errno);
-        return -1;
-    }
-
-    memset(&server_addr, '\0', sizeof(server_addr));
-    server_addr.sin_family = PF_INET;
-    server_addr.sin_addr.s_addr = INADDR_ANY;
-    server_addr.sin_port = htons(port);
-
-    qemu_set_nonblock(server->server_fd);
-
-    if (qemu_setsockopt(server->server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {
-        INFO("setsockopt SO_REUSEADDR is failed.: %d\n", errno);
-        return -1;
-    }
-
-    if (bind(server->server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
-        INFO("sdb noti server bind error: %d", errno);
-        return -1;
-    }
-
-    return 0;
-}
-
-static GIOChannel *io_channel_from_socket(int fd)
-{
-    GIOChannel *chan;
-
-    if (fd == -1) {
-        return NULL;
-    }
-
-#ifdef _WIN32
-    chan = g_io_channel_win32_new_socket(fd);
-#else
-    chan = g_io_channel_unix_new(fd);
-#endif
-
-    g_io_channel_set_encoding(chan, NULL, NULL);
-    g_io_channel_set_buffered(chan, FALSE);
-
-    return chan;
-}
-
-static void sdb_noti_server_notify_exit(Notifier *notifier, void *data)
-{
-    INFO("shutdown sdb notification server.\n");
-    close_server();
-}
-
-static Notifier sdb_noti_server_exit = { .notify = sdb_noti_server_notify_exit };
-
-static void start_sdb_noti_server(int server_port)
-{
-    SDB_Noti_Server *server;
-    int ret;
-
-    INFO("start sdb noti server thread.\n");
-
-    server = g_malloc0(sizeof(SDB_Noti_Server));
-    if (server == NULL) {
-        INFO("SDB Notification server allocation is failed.\n");
-        return;
-    }
-
-    ret = create_UDP_server(server, server_port);
-    if (ret < 0) {
-        INFO("failed to create UDP server\n");
-        close_server();
-        return;
-    }
-
-    server->server_chan = io_channel_from_socket(server->server_fd);
-    server->server_tag = g_io_add_watch(server->server_chan, G_IO_IN, sdb_noti_read, server);
-
-    current_server = server;
-
-    qemu_mutex_init(&mutex_clients);
-
-    INFO("success to bind port[127.0.0.1:%d/udp] for sdb noti server in host \n", server_port);
-
-    emulator_add_exit_notifier(&sdb_noti_server_exit);
-}
-
-bool is_sdb_daemon_initialized(void)
-{
-    return sdb_daemon_is_initialized;
-}
diff --git a/tizen/src/util/sdb.h b/tizen/src/util/sdb.h
deleted file mode 100644 (file)
index 2dd0cc0..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Emulator SDB Notification Server
- *
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Jinhyung choi   <jinhyung2.choi@samsung.com>
- *  MunKyu Im       <munkyu.im@samsung.com>
- *  Sangho Park     <sangho1206.park@samsung.com>
- *  YeongKyoon Lee  <yeongkyoon.lee@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-#ifndef SDB_SERVER_H_
-#define SDB_SERVER_H_
-
-#include <errno.h>
-
-#ifdef _WIN32
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#else /* !_WIN32 */
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#endif /* !_WIN32 */
-
-
-#define SDB_HOST_PORT 26099
-
-#define SDB_TCP_EMULD_INDEX  2    /* emulator daemon port */
-#define SDB_TCP_OPENGL_INDEX  3   /* opengl server port */
-#define SDB_UDP_SENSOR_INDEX  3   /* sensor server port */
-
-void init_sdb(int server_port);
-void init_vm_base_port(void);
-int inet_strtoip(const char*  str, uint32_t  *ip);
-int socket_send(int fd, const void*  buf, int  buflen);
-void socket_close(int fd);
-int check_port_bind_listen(uint32_t port);
-int find_available_port(uint32_t base_port);
-bool is_sdb_daemon_initialized(void);
-
-extern int emul_vm_base_socket;
-#define STATE_RUNNING 0
-#define STATE_SUSPEND 1
-void notify_all_sdb_clients(int state);
-
-#endif
-
diff --git a/vl.c b/vl.c
index c4af1d3b402af6e7a76682206ed98b4535e280e2..ed7f8a312f3a0d9058ade4de39aa2e22bf2695d4 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -4194,6 +4194,15 @@ int main(int argc, char **argv, char **envp)
         exit(1);
     }
 
+#if defined(CONFIG_MARU)
+    if (is_maru_machine(machine_class)) {
+        preallocated_ram_ptr = qemu_anon_ram_alloc(ram_size, NULL);
+        if (preallocated_ram_ptr) {
+            preallocated_ram_size = ram_size;
+        }
+    }
+#endif
+
     set_memory_options(&ram_slots, &maxram_size, machine_class);
 
     loc_set_none();
@@ -4252,21 +4261,6 @@ int main(int argc, char **argv, char **envp)
         exit(0);
     }
 
-#if defined(CONFIG_MARU)
-    if (is_maru_machine(machine_class)) {
-        preallocated_ram_ptr = qemu_anon_ram_alloc(ram_size, NULL);
-        if (preallocated_ram_ptr) {
-            preallocated_ram_size = ram_size;
-        }
-
-        kernel_cmdline = qemu_opt_get(qemu_get_machine_opts(), "append");
-        // Returned variable points different address from input variable.
-        kernel_cmdline = prepare_maru(kernel_cmdline);
-        qemu_opt_set(qemu_get_machine_opts(), "append",
-                kernel_cmdline, &error_abort);
-    }
-#endif
-
     /* Open the logfile at this point and set the log mask if necessary.
      */
     if (log_file) {
@@ -4711,6 +4705,18 @@ int main(int argc, char **argv, char **envp)
 
     configure_accelerator(current_machine);
 
+#if defined(CONFIG_MARU)
+    if (is_maru_machine(machine_class)) {
+        kernel_cmdline = qemu_opt_get(machine_opts, "append");
+        // Returned variable points different address from input variable.
+        kernel_cmdline = prepare_maru(kernel_cmdline);
+        qemu_opt_set(qemu_get_machine_opts(), "append",
+                kernel_cmdline, &error_abort);
+
+        current_machine->kernel_cmdline = (char *)kernel_cmdline;
+    }
+#endif
+
     machine_class->init(current_machine);
 
     realtime_init();