Merge branch 'tizen' into tizen_2.3
authorSeokYeon Hwang <syeon.hwang@samsung.com>
Thu, 16 Oct 2014 01:56:08 +0000 (10:56 +0900)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Thu, 16 Oct 2014 01:56:08 +0000 (10:56 +0900)
Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
Conflicts:
hw/virtio/virtio-pci.c
hw/virtio/virtio-pci.h
package/build.macos-64
package/build.ubuntu-32
package/build.ubuntu-64
package/build.windows-32
package/changelog
package/pkginfo.manifest
tizen/src/Makefile.tizen
tizen/src/Makefile.tizen.i386
tizen/src/debug_ch.c
tizen/src/debug_ch.h
tizen/src/display/maru_sdl.c
tizen/src/display/maru_sdl_processing.c
tizen/src/display/maru_shm.c
tizen/src/display/maru_shm.h
tizen/src/ecs/Makefile.tizen
tizen/src/ecs/ecs.c
tizen/src/ecs/ecs_eventcast.h
tizen/src/ecs/ecs_msg.c
tizen/src/ecs/ecs_tethering.c
tizen/src/emul_state.c
tizen/src/emul_state.h
tizen/src/emulator.c
tizen/src/eventcast/common.h
tizen/src/eventcast/msg/eventcast.proto
tizen/src/hw/maru_pm.c
tizen/src/hw/pci/maru_brillcodec.c
tizen/src/hw/virtio/maru_virtio_jack.h
tizen/src/hw/virtio/maru_virtio_nfc.c
tizen/src/hw/virtio/maru_virtio_sensor.h
tizen/src/sdb.c
tizen/src/sdb.h
tizen/src/skin/client/skins/mobile-320x480-3btn/default.dbi
tizen/src/skin/client/skins/mobile-480x800-3btn/default.dbi
tizen/src/skin/client/skins/mobile-720x1280-3btn/default.dbi
tizen/src/skin/client/skins/mobile-general-3btn/default.dbi
tizen/src/skin/client/skins/wearable-general-1btn/default.dbi
tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkin.java
tizen/src/skin/maruskin_operation.c
tizen/src/skin/maruskin_server.c
tizen/src/tethering/Makefile.tizen
tizen/src/tethering/app_tethering.h
tizen/src/tethering/common.h
tizen/src/tethering/genmsg/tethering.pb-c.c
tizen/src/tethering/genmsg/tethering.pb-c.h
tizen/src/tethering/touch.h
tizen/src/util/osutil-linux.c
tizen/src/util/osutil-win32.c
tizen/src/util/osutil.h

21 files changed:
1  2 
package/build.windows-32
tizen/src/ecs/Makefile.objs
tizen/src/ecs/ecs.h
tizen/src/ecs/ecs_eventcast.c
tizen/src/ecs/ecs_mon.c
tizen/src/ecs/ecs_msg.c
tizen/src/ecs/ecs_msg_device.c
tizen/src/ecs/ecs_msg_injector.c
tizen/src/ecs/ecs_nfc.c
tizen/src/emul_state.c
tizen/src/emul_state.h
tizen/src/hw/pci/maru_brillcodec.c
tizen/src/skin/client/skins/mobile-general-3btn/default.dbi
tizen/src/skin/client/src/org/tizen/emulator/skin/EmulatorSkin.java
tizen/src/skin/maruskin_server.c
tizen/src/util/maru_device_hotplug.c
tizen/src/util/maru_device_hotplug.h
tizen/src/util/osutil-darwin.c
tizen/src/util/osutil-linux.c
tizen/src/util/osutil.c
tizen/src/util/osutil.h

index 5725448ee6b2a6426b215083c9e164480bdb9d4c,5b6ab54afc75a6b9cc13064b0132792643b3a857..3e560fa73054678a36c246824f6207d8a992eaf3
@@@ -32,7 -32,7 +32,7 @@@ prepare(
          echo "and then set installed Python/bin path into PATH system variable on your PC!"
                exit 1
        fi
--      
++
        PURIFIED_ROOTDIR=`TEMP=\`echo "${ROOTDIR}" | cut -c-2 | sed "s/[:/]//g" | awk {'print tolower ($_)'}\`; echo \`echo "${ROOTDIR}" | sed "s/^../\/${TEMP}/"\``
        PATH=$PATH:$PURIFIED_ROOTDIR/bin:$PURIFIED_ROOTDIR/apache-ant_1.9.2/bin:$PURIFIED_ROOTDIR/SDL_1.2.15/bin:$PURIFIED_ROOTDIR/pixman_0.30.0/bin:$PURIFIED_ROOTDIR/gtk-bundle_2.24.10/bin:$PURIFIED_ROOTDIR/libcurl-4_1.0.1/bin
        export PATH
index 0000000000000000000000000000000000000000,658659cc62b7ee55e132ac2590135c9000d4dd7d..5f58026bd8e2d2d09a837ead17fd52758f5fa613
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,4 +1,6 @@@
 -obj-y += ecs_msg.o ecs.o ecs_sensor.o
+ obj-y += genmsg/ecs.pb-c.o genmsg/ecs_ids.pb-c.o ../../distrib/protobuf/protobuf-c.o
++obj-y += ecs.o ecs_msg.o ecs_msg_injector.o ecs_msg_device.o
+ obj-y += ecs_mon.o ecs-json-streamer.o
+ obj-y += ecs_eventcast.o
++obj-y += ecs_sensor.o
++obj-y += ecs_nfc.o
index 67c1f10f6447a4bdc6a65ece8c4e46c5655de375,5d7da124594dccc6979d3ffffdae1cfc014e0819..08a3d1c65908f97612812dff78e484cc4904e89a
@@@ -40,7 -40,7 +40,6 @@@
  #include "ecs-json-streamer.h"
  #include "genmsg/ecs.pb-c.h"
  #include "genmsg/ecs_ids.pb-c.h"
- #include "../osutil.h"
 -#include "../util/osutil.h"
  
  #define ECS_VERSION   "1.0"
  
index 0000000000000000000000000000000000000000,385a5f522256aae0f10d7302094765b3805d2ecc..25aec621300b62bf8e8cc5a041f3de97edb72362
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,348 +1,348 @@@
 -    send_to_ecp(&master);
+ /*
+  * Emulator Control Server - Device Tethering Handler
+  *
+  * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+  *
+  * Contact:
+  *  KiTae Kim       <kt920.kim@samsung.com>
+  *  JiHye Kim       <jihye1128.kim@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 "ui/console.h"
+ #include "ecs.h"
+ #include "ecs_eventcast.h"
+ #include "eventcast/common.h"
+ #include "eventcast/sensor.h"
+ #include "eventcast/touch.h"
+ #include "hw/virtio/maru_virtio_touchscreen.h"
+ #include "hw/virtio/maru_virtio_hwkey.h"
+ #include "util/new_debug_ch.h"
+ DECLARE_DEBUG_CHANNEL(ecs_eventcast);
+ #define MSG_BUF_SIZE  255
+ #define MSG_LEN_SIZE    4
+ #define PRESSED     1
+ #define RELEASED    2
+ static bool send_eventcast_ntf(const char *data);
+ static void send_eventcast_status_ntf(type_group group, type_action action);
+ static int eventcast_port = 0;
+ void send_eventcast_sensor_status_ecp(void)
+ {
+     LOG_INFO(">> send eventcast_event_status to ecp\n");
+     send_eventcast_status_ntf(ECS_EVENTCAST_MSG_GROUP_ECP,
+             ECS_EVENTCAST_MSG_ACTION_SENSOR_STATUS);
+ }
+ void send_eventcast_touch_status_ecp(void)
+ {
+     send_eventcast_status_ntf(ECS_EVENTCAST_MSG_GROUP_ECP,
+             ECS_EVENTCAST_MSG_ACTION_TOUCH_STATUS);
+ }
+ void send_eventcast_connection_status_ecp(void)
+ {
+     LOG_INFO(">> send eventcast_connection_status to ecp\n");
+     send_eventcast_status_ntf(ECS_EVENTCAST_MSG_GROUP_ECP,
+             ECS_EVENTCAST_MSG_ACTION_CONNECTION_STATUS);
+ }
+ #if 0
+ static void send_eventcast_port_ecp(void)
+ {
+     type_length length;
+     type_group group = ECS_EVENTCAST_MSG_GROUP_ECP;
+     type_action action = ECS_EVENTCAST_MSG_ACTION_CONNECT;
+     uint8_t *msg = NULL;
+     gchar data[12];
+     msg = g_malloc(MSG_BUF_SIZE);
+     if (!msg) {
+         return;
+     }
+     LOG_TRACE(">> send port_num: %d\n", eventcast_port);
+     g_snprintf(data, sizeof(data) - 1, "%d", eventcast_port);
+     length = strlen(data);
+     memcpy(msg, ECS_EVENTCAST_MSG_CATEGORY, 10);
+     memcpy(msg + 10, &length, sizeof(unsigned short));
+     memcpy(msg + 12, &group, sizeof(unsigned char));
+     memcpy(msg + 13, &action, sizeof(unsigned char));
+     memcpy(msg + 14, data, length);
+     LOG_TRACE(">> send eventcast_ntf to ecp. action=%d, group=%d, data=%s\n",
+         action, group, data);
+     send_eventcast_ntf((const char *)msg);
+     if (msg) {
+         g_free(msg);
+     }
+ }
+ #endif
+ static void send_eventcast_connection_info(void)
+ {
+     type_length length;
+     type_group group = ECS_EVENTCAST_MSG_GROUP_ECP;
+     type_action action = ECS_EVENTCAST_MSG_ACTION_CONNECT;
+     uint8_t *msg = NULL;
+     gchar data[64];
+     msg = g_malloc(MSG_BUF_SIZE);
+     if (!msg) {
+         LOG_SEVERE("failed to allocate memory\n");
+         return;
+     }
+     LOG_INFO(">> send port_num: %d\n", eventcast_port);
+     {
+         const char *ip = get_eventcast_connected_ipaddr();
+         int port = get_eventcast_connected_port();
+         if (!ip) {
+             LOG_SEVERE("invalid connected ip\n");
+             return;
+         }
+         if (!port) {
+             LOG_SEVERE("invalid connected port\n");
+             return;
+         }
+         g_snprintf(data, sizeof(data) - 1, "%s:%d", ip, port);
+         length = strlen(data);
+         data[length] = '\0';
+     }
+     memcpy(msg, ECS_EVENTCAST_MSG_CATEGORY, 10);
+     memcpy(msg + 10, &length, sizeof(unsigned short));
+     memcpy(msg + 12, &group, sizeof(unsigned char));
+     memcpy(msg + 13, &action, sizeof(unsigned char));
+     memcpy(msg + 14, data, length);
+     LOG_INFO(">> send connection msg to ecp. "
+         "action=%d, group=%d, data=%s length=%d\n",
+         action, group, data, length);
+     send_eventcast_ntf((const char *)msg);
+     g_free(msg);
+ }
+ static void send_eventcast_status_ntf(type_group group, type_action action)
+ {
+     type_length length = 1;
+     int status = 0;
+     uint8_t *msg = NULL;
+     gchar data[2];
+     switch (action) {
+         case ECS_EVENTCAST_MSG_ACTION_CONNECTION_STATUS:
+             status = get_eventcast_connection_status();
+             if (status == CONNECTED) {
+                 send_eventcast_connection_info();
+             }
+             break;
+         case ECS_EVENTCAST_MSG_ACTION_SENSOR_STATUS:
+             status = get_eventcast_sensor_status();
+             break;
+         case ECS_EVENTCAST_MSG_ACTION_TOUCH_STATUS:
+             status = get_eventcast_touch_status();
+             break;
+         default:
+             break;
+     }
+     msg = g_malloc(MSG_BUF_SIZE);
+     if (!msg) {
+         return;
+     }
+     g_snprintf(data, sizeof(data), "%d", status);
+     memcpy(msg, ECS_EVENTCAST_MSG_CATEGORY, 10);
+     memcpy(msg + 10, &length, sizeof(unsigned short));
+     memcpy(msg + 12, &group, sizeof(unsigned char));
+     memcpy(msg + 13, &action, sizeof(unsigned char));
+     memcpy(msg + 14, data, 1);
+     LOG_TRACE(">> send eventcast_ntf to ecp. action=%d, group=%d, data=%s\n",
+         action, group, data);
+     send_eventcast_ntf((const char *)msg);
+     if (msg) {
+         g_free(msg);
+     }
+ }
+ static bool send_eventcast_ntf(const char *data)
+ {
+     type_length length = 0;
+     type_group group = 0;
+     type_action action = 0;
+     const int catsize = 10;
+     char cat[catsize + 1];
+     memset(cat, 0, catsize + 1);
+     read_val_str(data, cat, catsize);
+     read_val_short(data + catsize, &length);
+     read_val_char(data + catsize + 2, &group);
+     read_val_char(data + catsize + 2 + 1, &action);
+     const char* ijdata = (data + catsize + 2 + 1 + 1);
+     LOG_TRACE(">> header cat = %s, length = %d, action=%d, group=%d\n", cat, length,action, group);
+     ECS__Master master = ECS__MASTER__INIT;
+     ECS__EventCastNtf ntf = ECS__EVENT_CAST_NTF__INIT;
+     ntf.category = (char*) g_malloc(catsize + 1);
+     strncpy(ntf.category, cat, 10);
+     ntf.length = length;
+     ntf.group = group;
+     ntf.action = action;
+     if (length > 0) {
+         ntf.has_data = 1;
+         ntf.data.data = g_malloc(length);
+         ntf.data.len = length;
+         memcpy(ntf.data.data, ijdata, length);
+         LOG_TRACE("data = %s, length = %hu\n", ijdata, length);
+     }
+     master.type = ECS__MASTER__TYPE__EVENTCAST_NTF;
+     master.eventcast_ntf = &ntf;
++    pb_to_all_clients(&master);
+     if (ntf.data.data && ntf.data.len > 0) {
+         g_free(ntf.data.data);
+     }
+     if (ntf.category) {
+         g_free(ntf.category);
+     }
+     return true;
+ }
+ void send_eventcast_sensor_data(const char *data, int len)
+ {
+     set_injector_data(data);
+ }
+ void send_eventcast_touch_data(int x, int y, int index, int status)
+ {
+     virtio_touchscreen_event(x, y, index, status);
+ }
+ void send_eventcast_hwkey_data(int keycode)
+ {
+     maru_hwkey_event(PRESSED, keycode);
+     maru_hwkey_event(RELEASED, keycode);
+ }
+ // handle eventcast_req message
+ bool msgproc_eventcast_req(ECS_Client* ccli, ECS__EventCastReq* msg)
+ {
+     gchar cmd[10] = {0};
+     gchar **server_addr = NULL;
+     LOG_TRACE("enter %s\n", __func__);
+     g_strlcpy(cmd, msg->category, sizeof(cmd));
+     type_length length = (type_length) msg->length;
+     type_group group = (type_group) (msg->group & 0xff);
+     type_action action = (type_action) (msg->action & 0xff);
+     LOG_TRACE("<< header = cmd = %s, length = %d, action=%d, group=%d\n",
+             cmd, length, action, group);
+     switch(action) {
+         case ECS_EVENTCAST_MSG_ACTION_CONNECT:
+             LOG_INFO("MSG_ACTION_CONNECT\n");
+             if (msg->data.data && msg->data.len > 0) {
+                 const gchar *data = (const gchar *)msg->data.data;
+                 gchar *ip_address = NULL;
+                 guint64 port = 0;
+                 server_addr = g_strsplit(data, ":", 0);
+                 if (server_addr && server_addr[0]) {
+                     int len = strlen(server_addr[0]);
+                     if (len) {
+                         ip_address = g_malloc(len + 1);
+                         g_strlcpy(ip_address, server_addr[0], len + 1);
+                     }
+                     LOG_INFO("IP address: %s, length: %d\n", ip_address, len);
+                 }
+                 if (server_addr && server_addr[1]) {
+                     port = g_ascii_strtoull(server_addr[1], NULL, 10);
+                     LOG_INFO("port number: %d\n", port);
+                 } else {
+                     LOG_SEVERE("failed to parse port number\n");
+                 }
+                 LOG_TRACE("len = %zd, data\" %s\"", strlen(data), data);
+                 connect_eventcast_app(ip_address, port);
+                 eventcast_port = port;
+                 LOG_TRACE(">> port_num: %d, %d\n", port, eventcast_port);
+                 g_free(ip_address);
+                 g_strfreev(server_addr);
+             } else {
+                 LOG_INFO("ip address and port value are null\n");
+             }
+             break;
+         case ECS_EVENTCAST_MSG_ACTION_DISCONNECT:
+             LOG_INFO(">> MSG_ACTION_DISCONNECT\n");
+             disconnect_eventcast_app();
+             eventcast_port = 0;
+             break;
+         case ECS_EVENTCAST_MSG_ACTION_CONNECTION_STATUS:
+         case ECS_EVENTCAST_MSG_ACTION_SENSOR_STATUS:
+         case ECS_EVENTCAST_MSG_ACTION_TOUCH_STATUS:
+             LOG_TRACE(">> get_status_action\n");
+             send_eventcast_status_ntf(group, action);
+             break;
+         default:
+             break;
+     }
+     LOG_TRACE("leave %s\n", __func__);
+     return true;
+ }
Simple merge
index 55aef098ce2ba0239e8eca8167b017db44e5d3bc,b2773806bc097cc8b3516d3ac7c17a19c7593ffa..3ad09b30dafcce75e371f0318bd8a51da0f26440
  #include "qapi/qmp/json-parser.h"
  #include "ui/qemu-spice.h"
  #include "qemu/queue.h"
 -#include "qemu/option.h"
  #include "sysemu/char.h"
  #include "qemu/main-loop.h"
- #ifdef CONFIG_LINUX
- #include <sys/epoll.h>
- #endif
  #include "qemu-common.h"
- #include "sdb.h"
+ #include "util/sdb.h"
  #include "ecs-json-streamer.h"
  #include "qmp-commands.h"
  
- #include "hw/maru_virtio_vmodem.h"
- #include "hw/maru_virtio_evdi.h"
 -#include "ecs.h"
 -#ifndef CONFIG_USE_SHM
 -#include "display/maru_finger.h"
 -#endif
 -
 -#include "hw/virtio/maru_virtio_evdi.h"
 -#include "hw/virtio/maru_virtio_sensor.h"
 -#include "hw/virtio/maru_virtio_jack.h"
 -#include "hw/virtio/maru_virtio_power.h"
 -#include "hw/virtio/maru_virtio_nfc.h"
+ #include "hw/virtio/maru_virtio_vmodem.h"
 -#include "skin/maruskin_operation.h"
 -#include "skin/maruskin_server.h"
 -#include "util/maru_device_hotplug.h"
 -#include "emul_state.h"
++#include "hw/virtio/maru_virtio_evdi.h"
 +
 +#include "ecs.h"
  
  #include "debug_ch.h"
 -MULTI_DEBUG_CHANNEL(qemu, ecs-msg);
  
 -// utility functions
 -static int guest_connection = 0;
 -extern QemuMutex mutex_guest_connection;
 -extern QemuMutex mutex_location_data;
 -static char location_data[MAX_INJECTOR_REQ_DATA];
 -/*static function define*/
 -static bool handle_sdcard(char* dataBuf, size_t dataLen);
 -static char* get_emulator_sdcard_path(void);
 -static char *get_old_tizen_sdk_data_path(void);
 +MULTI_DEBUG_CHANNEL(qemu, ecs);
  
  static void* build_master(ECS__Master* master, int* payloadsize)
  {
@@@ -253,4 -763,459 +251,3 @@@ bool ntf_to_injector(const char* data, 
  
      return true;
  }
 -
 -static bool injector_req_handle(const char* cat, type_action action)
 -{
 -    /*SD CARD msg process*/
 -    if (!strcmp(cat, MSG_TYPE_SDCARD)) {
 -        return false;
 -
 -    } else if (!strcmp(cat, "suspend")) {
 -        ecs_suspend_lock_state(ecs_get_suspend_state());
 -        return true;
 -    } else if (!strcmp(cat, MSG_TYPE_GUEST)) {
 -        INFO("emuld connection is %d\n", action);
 -        qemu_mutex_lock(&mutex_guest_connection);
 -        guest_connection = action;
 -        qemu_mutex_unlock(&mutex_guest_connection);
 -        return false;
 -    }
 -
 -    return false;
 -}
 -
 -bool send_injector_ntf(const char* data, const int len)
 -{
 -    type_length length = 0;
 -    type_group group = 0;
 -    type_action action = 0;
 -
 -    const int catsize = 10;
 -    char cat[catsize + 1];
 -    memset(cat, 0, catsize + 1);
 -
 -    read_val_str(data, cat, catsize);
 -    read_val_short(data + catsize, &length);
 -    read_val_char(data + catsize + 2, &group);
 -    read_val_char(data + catsize + 2 + 1, &action);
 -
 -    if (injector_req_handle(cat, action)) {
 -        return true;
 -    }
 -
 -    const char* ijdata = (data + catsize + 2 + 1 + 1);
 -
 -    TRACE("<< header cat = %s, length = %d, action=%d, group=%d", cat, length,action, group);
 -
 -    ECS__Master master = ECS__MASTER__INIT;
 -    ECS__InjectorNtf ntf = ECS__INJECTOR_NTF__INIT;
 -
 -    ntf.category = (char*) g_malloc(catsize + 1);
 -    strncpy(ntf.category, cat, 10);
 -
 -    ntf.length = length;
 -    ntf.group = group;
 -    ntf.action = action;
 -
 -    if (length > 0)
 -    {
 -        ntf.has_data = 1;
 -
 -        ntf.data.data = g_malloc(length);
 -        ntf.data.len = length;
 -        memcpy(ntf.data.data, ijdata, length);
 -    }
 -
 -    master.type = ECS__MASTER__TYPE__INJECTOR_NTF;
 -    master.injector_ntf = &ntf;
 -
 -    send_to_ecp(&master);
 -
 -    if (ntf.data.len > 0)
 -    {
 -        g_free(ntf.data.data);
 -    }
 -
 -    g_free(ntf.category);
 -
 -    return true;
 -}
 -
 -bool send_device_ntf(const char* data, const int len)
 -{
 -    type_length length = 0;
 -    type_group group = 0;
 -    type_action action = 0;
 -
 -    const int catsize = 10;
 -    char cat[catsize + 1];
 -    memset(cat, 0, catsize + 1);
 -
 -    read_val_str(data, cat, catsize);
 -    read_val_short(data + catsize, &length);
 -    read_val_char(data + catsize + 2, &group);
 -    read_val_char(data + catsize + 2 + 1, &action);
 -
 -    const char* ijdata = (data + catsize + 2 + 1 + 1);
 -
 -    TRACE("<< header cat = %s, length = %d, action=%d, group=%d", cat, length,action, group);
 -
 -    ECS__Master master = ECS__MASTER__INIT;
 -    ECS__DeviceNtf ntf = ECS__DEVICE_NTF__INIT;
 -
 -    ntf.category = (char*) g_malloc(catsize + 1);
 -    strncpy(ntf.category, cat, 10);
 -
 -
 -    ntf.length = length;
 -    ntf.group = group;
 -    ntf.action = action;
 -
 -    if (length > 0)
 -    {
 -        ntf.has_data = 1;
 -
 -        ntf.data.data = g_malloc(length);
 -        ntf.data.len = length;
 -        memcpy(ntf.data.data, ijdata, length);
 -
 -        TRACE("data = %s, length = %hu", ijdata, length);
 -    }
 -
 -    master.type = ECS__MASTER__TYPE__DEVICE_NTF;
 -    master.device_ntf = &ntf;
 -
 -    send_to_ecp(&master);
 -
 -    if (ntf.data.data && ntf.data.len > 0)
 -    {
 -        g_free(ntf.data.data);
 -    }
 -
 -    if (ntf.category)
 -        g_free(ntf.category);
 -
 -    return true;
 -}
 -
 -bool send_nfc_ntf(struct nfc_msg_info* msg)
 -{
 -    const int catsize = 10;
 -    char cat[catsize + 1];
 -    ECS_Client *clii;
 -    memset(cat, 0, catsize + 1);
 -
 -    print_binary((char*)msg->buf, msg->use);
 -    TRACE("id: %02x, type: %02x, use: %d", msg->client_id, msg->client_type, msg->use);
 -    clii =  find_client(msg->client_id, msg->client_type);
 -    if (clii) {
 -        if(clii->client_type == TYPE_SIMUL_NFC) {
 -            strncpy(cat, MSG_TYPE_NFC, 3);
 -        } else if (clii->client_type == TYPE_ECP) {
 -            strncpy(cat, MSG_TYPE_SIMUL_NFC, 9);
 -        }else {
 -            ERR("cannot find type! : %d", clii->client_type);
 -        }
 -        TRACE("header category = %s", cat);
 -    }
 -    else {
 -        ERR("cannot find client!\n");
 -    }
 -
 -    ECS__Master master = ECS__MASTER__INIT;
 -    ECS__NfcNtf ntf = ECS__NFC_NTF__INIT;
 -
 -    ntf.category = (char*) g_malloc(catsize + 1);
 -    strncpy(ntf.category, cat, 10);
 -
 -    ntf.has_data = 1;
 -
 -    ntf.data.data = g_malloc(NFC_MAX_BUF_SIZE);
 -    ntf.data.len = NFC_MAX_BUF_SIZE;
 -    memcpy(ntf.data.data, msg->buf, NFC_MAX_BUF_SIZE);
 -
 -    printf("send to nfc injector: ");
 -    master.type = ECS__MASTER__TYPE__NFC_NTF;
 -    master.nfc_ntf = &ntf;
 -
 -    send_single_msg(&master, clii);
 -
 -    if (ntf.data.data && ntf.data.len > 0)
 -    {
 -        g_free(ntf.data.data);
 -    }
 -
 -    if (ntf.category)
 -        g_free(ntf.category);
 -
 -    return true;
 -}
 -
 -static bool handle_sdcard(char* dataBuf, size_t dataLen)
 -{
 -    int err_no = 0;
 -    char ret = 0;
 -    INFO("handle_sdcard() data: %s\n", dataBuf);
 -    if (dataBuf != NULL) {
 -        ret = dataBuf[0];
 -
 -        if (ret == '0' ) {
 -            /* umount sdcard */
 -            //mloop_evcmd_usbdisk(NULL);
 -            char sdcard_img_path[256];
 -            char* sdcard_path = NULL;
 -
 -            sdcard_path = get_emulator_sdcard_path();
 -            if (sdcard_path) {
 -                g_strlcpy(sdcard_img_path, sdcard_path,
 -                        sizeof(sdcard_img_path));
 -
 -                /* emulator_sdcard_img_path + sdcard img name */
 -                char* sdcard_img_name = dataBuf+2;
 -                if (dataLen > 3 && sdcard_img_name != NULL) {
 -                    char* pLinechange = strchr(sdcard_img_name, '\n');
 -                    if(pLinechange != NULL){
 -                        sdcard_img_name = g_strndup(sdcard_img_name, pLinechange - sdcard_img_name);
 -                    }
 -
 -                    g_strlcat(sdcard_img_path, sdcard_img_name, sizeof(sdcard_img_path));
 -                    INFO("sdcard path: [%s]\n", sdcard_img_path);
 -
 -                    /*if using strndup than free string*/
 -                    if (pLinechange != NULL && sdcard_img_name!= NULL) {
 -                        free(sdcard_img_name);
 -                    }
 -                }
 -                g_free(sdcard_path);
 -
 -            }
 -            err_no = remove_sdcard_lock_os(sdcard_img_path);
 -            INFO("umount err_no: %d\n", err_no);
 -            if (errno == 0 && is_sdcard_attached()) {
 -                do_hotplug(DETACH_SDCARD, NULL, 0);
 -            } else {
 -                ERR("failed to umount: %s\n", sdcard_img_path);
 -                send_gen_injector_ntf(MSG_TYPE_SDCARD, 6, 11, err_no, NULL);
 -                return err_no;
 -            }
 -        }
 -        else if (ret == '1') {
 -            /* mount sdcard */
 -            char sdcard_img_path[256];
 -            char* sdcard_path = NULL;
 -
 -            sdcard_path = get_emulator_sdcard_path();
 -            if (sdcard_path) {
 -                g_strlcpy(sdcard_img_path, sdcard_path,
 -                        sizeof(sdcard_img_path));
 -
 -                /* emulator_sdcard_img_path + sdcard img name */
 -                char* sdcard_img_name = dataBuf+2;
 -                if (dataLen > 3 && sdcard_img_name != NULL) {
 -                    char* pLinechange = strchr(sdcard_img_name, '\n');
 -                    if(pLinechange != NULL){
 -                        sdcard_img_name = g_strndup(sdcard_img_name, pLinechange - sdcard_img_name);
 -                    }
 -
 -                    g_strlcat(sdcard_img_path, sdcard_img_name, sizeof(sdcard_img_path));
 -                    TRACE("sdcard path: [%s]\n", sdcard_img_path);
 -
 -                    //mloop_evcmd_usbdisk(sdcard_img_path);
 -                    if ( !is_sdcard_attached() && make_sdcard_lock_os(sdcard_img_path)) {
 -                        do_hotplug(ATTACH_SDCARD, sdcard_img_path, strlen(sdcard_img_path) + 1);
 -                        send_gen_injector_ntf(MSG_TYPE_SDCARD, 6, 11, 0, NULL);
 -                    } else {
 -                        send_gen_injector_ntf(MSG_TYPE_SDCARD, 6, 11, 5, NULL);
 -                        return ERR_LCK;
 -                    }
 -                    /*if using strndup than free string*/
 -                    if (pLinechange != NULL && sdcard_img_name!= NULL) {
 -                        free(sdcard_img_name);
 -                    }
 -
 -                }
 -
 -                g_free(sdcard_path);
 -            } else {
 -                ERR("failed to get sdcard path!!\n");
 -            }
 -        } else if (ret == '2') {
 -            TRACE("sdcard status 2 bypass\n" );
 -        } else {
 -            ERR("!!! unknown command : %c\n", ret);
 -        }
 -
 -    } else {
 -        ERR("!!! unknown data : %c\n", ret);
 -    }
 -    return ERR_SUCCESS;
 -}
 -
 -static char* get_emulator_sdcard_path(void)
 -{
 -    char *emulator_sdcard_path = NULL;
 -    char *tizen_sdk_data = NULL;
 -
 -#ifndef CONFIG_WIN32
 -    char emulator_sdcard[] = "/emulator/sdcard/";
 -#else
 -    char emulator_sdcard[] = "\\emulator\\sdcard\\";
 -#endif
 -
 -    TRACE("emulator_sdcard: %s, %zu\n", emulator_sdcard, sizeof(emulator_sdcard));
 -
 -    tizen_sdk_data = get_tizen_sdk_data_path();
 -    if (!tizen_sdk_data) {
 -        ERR("failed to get tizen-sdk-data path.\n");
 -        return NULL;
 -    }
 -
 -    emulator_sdcard_path =
 -        g_malloc(strlen(tizen_sdk_data) + sizeof(emulator_sdcard) + 1);
 -    if (!emulator_sdcard_path) {
 -        ERR("failed to allocate memory.\n");
 -        return NULL;
 -    }
 -
 -    g_snprintf(emulator_sdcard_path, strlen(tizen_sdk_data) + sizeof(emulator_sdcard),
 -             "%s%s", tizen_sdk_data, emulator_sdcard);
 -
 -    g_free(tizen_sdk_data);
 -
 -    TRACE("sdcard path: %s\n", emulator_sdcard_path);
 -    return emulator_sdcard_path;
 -}
 -
 -/*
 - *  get tizen-sdk-data path from sdk.info.
 - */
 -char *get_tizen_sdk_data_path(void)
 -{
 -    char const *emul_bin_path = NULL;
 -    char *sdk_info_file_path = NULL;
 -    char *tizen_sdk_data_path = NULL;
 -#ifndef CONFIG_WIN32
 -    const char *sdk_info = "../../../sdk.info";
 -#else
 -    const char *sdk_info = "..\\..\\..\\sdk.info";
 -#endif
 -    const char sdk_data_var[] = "TIZEN_SDK_DATA_PATH";
 -
 -    FILE *sdk_info_fp = NULL;
 -    int sdk_info_path_len = 0;
 -
 -    TRACE("%s\n", __func__);
 -
 -    emul_bin_path = get_bin_path();
 -    if (!emul_bin_path) {
 -        ERR("failed to get emulator path.\n");
 -        return NULL;
 -    }
 -
 -    sdk_info_path_len = strlen(emul_bin_path) + strlen(sdk_info) + 1;
 -    sdk_info_file_path = g_malloc(sdk_info_path_len);
 -    if (!sdk_info_file_path) {
 -        ERR("failed to allocate sdk-data buffer.\n");
 -        return NULL;
 -    }
 -
 -    g_snprintf(sdk_info_file_path, sdk_info_path_len, "%s%s",
 -                emul_bin_path, sdk_info);
 -    INFO("sdk.info path: %s\n", sdk_info_file_path);
 -
 -    sdk_info_fp = fopen(sdk_info_file_path, "r");
 -    g_free(sdk_info_file_path);
 -
 -    if (sdk_info_fp) {
 -        TRACE("Succeeded to open [sdk.info].\n");
 -
 -        char tmp[256] = { '\0', };
 -        char *tmpline = NULL;
 -        while (fgets(tmp, sizeof(tmp), sdk_info_fp) != NULL) {
 -            if ((tmpline = g_strstr_len(tmp, sizeof(tmp), sdk_data_var))) {
 -                tmpline += strlen(sdk_data_var) + 1; // 1 for '='
 -                break;
 -            }
 -        }
 -
 -        if (tmpline) {
 -            if (tmpline[strlen(tmpline) - 1] == '\n') {
 -                tmpline[strlen(tmpline) - 1] = '\0';
 -            }
 -            if (tmpline[strlen(tmpline) - 1] == '\r') {
 -                tmpline[strlen(tmpline) - 1] = '\0';
 -            }
 -
 -            tizen_sdk_data_path = g_malloc(strlen(tmpline) + 1);
 -            g_strlcpy(tizen_sdk_data_path, tmpline, strlen(tmpline) + 1);
 -
 -            INFO("tizen-sdk-data path: %s\n", tizen_sdk_data_path);
 -
 -            fclose(sdk_info_fp);
 -            return tizen_sdk_data_path;
 -        }
 -
 -        fclose(sdk_info_fp);
 -    }
 -
 -    // legacy mode
 -    ERR("Failed to open [sdk.info].\n");
 -
 -    return get_old_tizen_sdk_data_path();
 -}
 -
 -static char *get_old_tizen_sdk_data_path(void)
 -{
 -    char *tizen_sdk_data_path = NULL;
 -
 -    INFO("try to search tizen-sdk-data path in another way.\n");
 -
 -#ifndef CONFIG_WIN32
 -    char tizen_sdk_data[] = "/tizen-sdk-data";
 -    int tizen_sdk_data_len = 0;
 -    char *home_dir;
 -
 -    home_dir = (char *)g_getenv("HOME");
 -    if (!home_dir) {
 -        home_dir = (char *)g_get_home_dir();
 -    }
 -
 -    tizen_sdk_data_len = strlen(home_dir) + sizeof(tizen_sdk_data) + 1;
 -    tizen_sdk_data_path = g_malloc(tizen_sdk_data_len);
 -    if (!tizen_sdk_data_path) {
 -        ERR("failed to allocate memory.\n");
 -        return NULL;
 -    }
 -    g_strlcpy(tizen_sdk_data_path, home_dir, tizen_sdk_data_len);
 -    g_strlcat(tizen_sdk_data_path, tizen_sdk_data, tizen_sdk_data_len);
 -
 -#else
 -    char tizen_sdk_data[] = "\\tizen-sdk-data\\";
 -    gint tizen_sdk_data_len = 0;
 -    HKEY hKey;
 -    char strLocalAppDataPath[1024] = { 0 };
 -    DWORD dwBufLen = 1024;
 -
 -    RegOpenKeyEx(HKEY_CURRENT_USER,
 -        "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
 -        0, KEY_QUERY_VALUE, &hKey);
 -
 -    RegQueryValueEx(hKey, "Local AppData", NULL,
 -                    NULL, (LPBYTE)strLocalAppDataPath, &dwBufLen);
 -    RegCloseKey(hKey);
 -
 -    tizen_sdk_data_len = strlen(strLocalAppDataPath) + sizeof(tizen_sdk_data) + 1;
 -    tizen_sdk_data_path = g_malloc(tizen_sdk_data_len);
 -    if (!tizen_sdk_data_path) {
 -        ERR("failed to allocate memory.\n");
 -        return NULL;
 -    }
 -
 -    g_strlcpy(tizen_sdk_data_path, strLocalAppDataPath, tizen_sdk_data_len);
 -    g_strlcat(tizen_sdk_data_path, tizen_sdk_data, tizen_sdk_data_len);
 -#endif
 -
 -    INFO("tizen-sdk-data path: %s\n", tizen_sdk_data_path);
 -    return tizen_sdk_data_path;
 -}
--
index 947cda6d0f34586875e33318eccfaa33c14d2237,0000000000000000000000000000000000000000..55d6f6ac3001693233186f6c59173e8654b41276
mode 100644,000000..100644
--- /dev/null
@@@ -1,537 -1,0 +1,466 @@@
- #include "mloop_event.h"
- #include "hw/maru_virtio_sensor.h"
- #include "hw/maru_virtio_nfc.h"
 +/* Emulator Control Server
 + *
 + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
 + *
 + * Contact:
 + *  Jinhyung choi   <jinhyung2.choi@samsung.com>
 + *  MunKyu Im       <munkyu.im@samsung.com>
 + *  Daiyoung Kim    <daiyoung777.kim@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 "qemu-common.h"
 +#include "qemu/option.h"
 +#include "qemu/config-file.h"
 +
 +#include "qmp-commands.h"
 +#include "net/slirp.h"
 +#include "fsdev/qemu-fsdev.h"
 +#include "monitor/qdev.h"
- #ifndef CONFIG_USE_SHM
- #include "maru_finger.h"
- #endif
++#include "hw/virtio/maru_virtio_sensor.h"
++#include "hw/virtio/maru_virtio_nfc.h"
 +#include "skin/maruskin_operation.h"
 +#include "skin/maruskin_server.h"
- #include "emulator.h"
 +
- static bool is_hds_attached = false;
- #define FS_FILE_SYSTEM          "virtfs"
- #define FS_DRIVER               "virtio-9p-pci"
- #define FS_MOUNT_TAG            "fileshare"
- static bool do_virtfs_attach(const char * const file)
- {
-     QemuOpts *fsdev;
-     int ret;
-     QDict *qdict = qdict_new();
-     fsdev = qemu_opts_create(qemu_find_opts("fsdev"),
-                              FS_MOUNT_TAG, 0, NULL);
-     if (!fsdev) {
-         fprintf(stderr, "duplicate fsdev id: %s\n", FS_MOUNT_TAG);
-         return false;
-     }
-     qemu_opt_set(fsdev, "fsdriver", "local");
-     qemu_opt_set(fsdev, "path", file);
-     qemu_opt_set(fsdev, "security_model", "none");
-     ret = qemu_fsdev_add(fsdev);
-     if (ret != 0) {
-         ERR("qemu_fsdev_add failed. with ret: %d\n", ret);
-         return false;
-     }
-     qdict = qdict_new();
-     qdict_put(qdict, "driver", qstring_from_str(FS_DRIVER));
-     qdict_put(qdict, "fsdev", qstring_from_str(FS_MOUNT_TAG));
-     qdict_put(qdict, "mount_tag", qstring_from_str(FS_MOUNT_TAG));
-     qdict_put(qdict, "id", qstring_from_str(FS_MOUNT_TAG));
-     if (do_device_add(default_mon, qdict, NULL)) {
-         QDECREF(qdict);
-         return false;
-     }
-     QDECREF(qdict);
-     is_hds_attached = true;
-     return true;
- }
- bool do_virtfs_detach(void)
- {
-     INFO("try to detach hds.\n");
-     QDict *qdict = qdict_new();
-     qemu_fsdev_remove(FS_MOUNT_TAG);
-     qdict_put(qdict, "id", qstring_from_str(FS_MOUNT_TAG));
-     if (qmp_marshal_input_device_del(cur_mon, qdict, NULL)) {
-         QDECREF(qdict);
-         return false;
-     }
-     QDECREF(qdict);
-     is_hds_attached = false;
-     return true;
- }
++#include "util/maru_device_hotplug.h"
 +#include "emul_state.h"
 +#include "ecs.h"
 +#include "debug_ch.h"
 +
 +MULTI_DEBUG_CHANNEL(qemu, ecs);
 +
 +static void msgproc_device_ans(ECS_Client* ccli, const char* category, bool succeed, char* data)
 +{
 +    if (ccli == NULL) {
 +        return;
 +    }
 +    int catlen = 0;
 +    ECS__Master master = ECS__MASTER__INIT;
 +    ECS__DeviceAns ans = ECS__DEVICE_ANS__INIT;
 +
 +    TRACE("device ans - category : %s, succed : %d\n", category, succeed);
 +
 +    catlen = strlen(category);
 +    ans.category = (char*) g_malloc0(catlen + 1);
 +    memcpy(ans.category, category, catlen);
 +
 +    ans.errcode = !succeed;
 +
 +    if (data != NULL) {
 +        ans.length = strlen(data);
 +
 +        if (ans.length > 0) {
 +            ans.has_data = 1;
 +            ans.data.data = g_malloc(ans.length);
 +            ans.data.len = ans.length;
 +            memcpy(ans.data.data, data, ans.length);
 +            TRACE("data = %s, length = %hu\n", data, ans.length);
 +        }
 +    }
 +
 +    master.type = ECS__MASTER__TYPE__DEVICE_ANS;
 +    master.device_ans = &ans;
 +
 +    pb_to_all_clients(&master);
 +
 +    if (ans.category)
 +        g_free(ans.category);
 +}
 +
 +extern char tizen_target_img_path[];
 +void send_target_image_information(ECS_Client* ccli) {
 +    ECS__Master master = ECS__MASTER__INIT;
 +    ECS__DeviceAns ans = ECS__DEVICE_ANS__INIT;
 +    int length = strlen(tizen_target_img_path); // ??
 +
 +    ans.category = (char*) g_malloc(10 + 1);
 +    strncpy(ans.category, "info", 10);
 +
 +    ans.errcode = 0;
 +    ans.length = length;
 +    ans.group = 1;
 +    ans.action = 1;
 +
 +    if (length > 0)
 +    {
 +        ans.has_data = 1;
 +
 +        ans.data.data = g_malloc(length);
 +        ans.data.len = length;
 +        memcpy(ans.data.data, tizen_target_img_path, length);
 +
 +        TRACE("data = %s, length = %hu\n", tizen_target_img_path, length);
 +    }
 +
 +    master.type = ECS__MASTER__TYPE__DEVICE_ANS;
 +    master.device_ans = &ans;
 +
 +    pb_to_single_client(&master, ccli);
 +
 +    if (ans.data.len > 0)
 +    {
 +        g_free(ans.data.data);
 +    }
 +
 +    g_free(ans.category);
 +}
 +
 +static void msgproc_device_req_sensor(ECS_Client* ccli, ECS__DeviceReq* msg, char* cmd)
 +{
 +    char* data = NULL;
 +    type_group group = (type_group) (msg->group & 0xff);
 +    type_action action = (type_action) (msg->action & 0xff);
 +
 +    if (msg->has_data && msg->data.len > 0)
 +    {
 +        data = (char*) g_malloc0(msg->data.len + 1);
 +        memcpy(data, msg->data.data, msg->data.len);
 +    }
 +
 +    if (group == MSG_GROUP_STATUS) {
 +        if (action == MSG_ACT_ACCEL) {
 +            get_sensor_accel();
 +        } else if (action == MSG_ACT_GYRO) {
 +            get_sensor_gyro();
 +        } else if (action == MSG_ACT_MAG) {
 +            get_sensor_mag();
 +        } else if (action == MSG_ACT_LIGHT) {
 +            get_sensor_light();
 +        } else if (action == MSG_ACT_PROXI) {
 +            get_sensor_proxi();
 +        }
 +    } else {
 +        if (data != NULL) {
 +            set_injector_data(data);
 +        } else {
 +            ERR("sensor set data is null\n");
 +        }
 +    }
 +    msgproc_device_ans(ccli, cmd, true, NULL);
 +
 +    if (data) {
 +        g_free(data);
 +    }
 +}
 +
 +static void msgproc_device_req_network(ECS_Client* ccli, ECS__DeviceReq* msg)
 +{
 +    char* data = NULL;
 +
 +    if (msg->has_data && msg->data.len > 0)
 +    {
 +        data = (char*) g_malloc0(msg->data.len + 1);
 +        memcpy(data, msg->data.data, msg->data.len);
 +    }
 +
 +    if (data != NULL) {
 +        TRACE(">>> Network msg: '%s'\n", data);
 +        if(net_slirp_redir(data) < 0) {
 +            ERR( "redirect [%s] fail\n", data);
 +        } else {
 +            TRACE("redirect [%s] success\n", data);
 +        }
 +    } else {
 +        ERR("Network redirection data is null.\n");
 +    }
 +
 +    if (data) {
 +        g_free(data);
 +    }
 +}
 +
 +static void msgproc_device_req_tgesture(ECS_Client* ccli, ECS__DeviceReq* msg)
 +{
 +    char* data = NULL;
 +    type_group group = (type_group) (msg->group & 0xff);
 +
 +    if (msg->has_data && msg->data.len > 0)
 +    {
 +        data = (char*) g_malloc0(msg->data.len + 1);
 +        memcpy(data, msg->data.data, msg->data.len);
 +    }
 +
 +    /* release multi-touch */
 +#ifndef CONFIG_USE_SHM
 +    if (get_multi_touch_enable() != 0) {
 +        clear_finger_slot(false);
 +    }
 +#else
 +    // TODO:
 +#endif
 +
 +    if (data == NULL) {
 +        ERR("touch gesture data is NULL\n");
 +        return;
 +    }
 +
 +    TRACE("%s\n", data);
 +
 +    char token[] = "#";
 +
 +    if (group == 1) { /* HW key event */
 +        char *section = strtok(data, token);
 +        int event_type = atoi(section);
 +
 +        section = strtok(NULL, token);
 +        int keycode = atoi(section);
 +
 +        do_hw_key_event(event_type, keycode);
 +    } else { /* touch event */
 +        char *section = strtok(data, token);
 +        int event_type = atoi(section);
 +
 +        section = strtok(NULL, token);
 +        int xx = atoi(section);
 +
 +        section = strtok(NULL, token);
 +        int yy = atoi(section);
 +
 +        section = strtok(NULL, token);
 +        int zz = atoi(section);
 +
 +        do_mouse_event(1/* LEFT */, event_type, 0, 0, xx, yy, zz);
 +    }
 +
 +    if (data) {
 +        g_free(data);
 +    }
 +}
 +
 +static void msgproc_device_req_input(ECS_Client* ccli, ECS__DeviceReq* msg, char* cmd)
 +{
 +    char* data = NULL;
 +    type_group group = (type_group) (msg->group & 0xff);
 +    type_action action = (type_action) (msg->action & 0xff);
 +
 +    if (msg->has_data && msg->data.len > 0)
 +    {
 +        data = (char*) g_malloc0(msg->data.len + 1);
 +        memcpy(data, msg->data.data, msg->data.len);
 +    }
 +
 +    // cli input
 +    TRACE("receive input message [%s]\n", data);
 +
 +    if (group == 0) {
 +        TRACE("input keycode data : [%s]\n", data);
 +
 +        char token[] = " ";
 +        char *section = strtok(data, token);
 +        int keycode = atoi(section);
 +        if (action == 1) {
 +            //action 1 press
 +            do_hw_key_event(KEY_PRESSED, keycode);
 +
 +        } else if (action == 2) {
 +            //action 2 released
 +            do_hw_key_event(KEY_RELEASED, keycode);
 +
 +        } else {
 +            ERR("unknown action : [%d]\n", (int)action);
 +        }
 +    } else if (group == 1) {
 +        //spec out
 +        TRACE("input category's group 1 is spec out\n");
 +    } else {
 +        ERR("unknown group [%d]\n", (int)group);
 +    }
 +    msgproc_device_ans(ccli, cmd, true, NULL);
 +
 +    if (data) {
 +        g_free(data);
 +    }
 +}
 +
 +static void msgproc_device_req_nfc(ECS_Client* ccli, ECS__DeviceReq* msg)
 +{
 +    char* data = NULL;
 +    type_group group = (type_group) (msg->group & 0xff);
 +
 +    if (msg->has_data && msg->data.len > 0)
 +    {
 +        data = (char*) g_malloc0(msg->data.len + 1);
 +        memcpy(data, msg->data.data, msg->data.len);
 +    }
 +
 +    if (group == MSG_GROUP_STATUS) {
 +        get_nfc_data();
 +    } else {
 +        if (data != NULL) {
 +            send_to_nfc(ccli->client_id, ccli->client_type, data, msg->data.len);
 +        } else {
 +            ERR("nfc data is null\n");
 +        }
 +    }
 +
 +    if (data) {
 +        g_free(data);
 +    }
 +}
 +
-         if (is_hds_attached) {
 +static char hds_path[PATH_MAX];
 +
 +static void msgproc_device_req_hds(ECS_Client* ccli, ECS__DeviceReq* msg, char * cmd)
 +{
 +    char* data = NULL;
 +    type_group group = (type_group) (msg->group & 0xff);
 +    type_action action = (type_action) (msg->action & 0xff);
 +
 +    if (msg->has_data && msg->data.len > 0)
 +    {
 +        data = (char*) g_malloc0(msg->data.len + 1);
 +        memcpy(data, msg->data.data, msg->data.len);
 +    }
 +
 +    INFO("hds group: %d, action : %d\n", group, action);
 +    if (group == MSG_GROUP_STATUS) {
 +        char hds_data_send[PATH_MAX + 3];
-         INFO("try attach with is_hds_attached : %d\n", is_hds_attached);
-         if (data != NULL && !is_hds_attached) {
-             if (!do_virtfs_attach(data)) {
++        if (is_hds_attached()) {
 +            sprintf(hds_data_send, "1, %s", hds_path);
 +        } else {
 +            sprintf(hds_data_send, "0, ");
 +        }
 +        make_send_device_ntf(cmd, group, 99, hds_data_send);
 +    } else if (group == 100 && action == 1) {
-               }
++        INFO("try attach with is_hds_attached : %d\n", is_hds_attached());
++        if (data != NULL && !is_hds_attached()) {
++            do_hotplug(ATTACH_HDS, data, strlen(data) + 1);
++            if (!is_hds_attached()) {
 +                ERR("failed to attach");
 +                make_send_device_ntf(cmd, 100, 2, NULL);
 +            } else {
 +                memset(hds_path, 0, sizeof(hds_path));
 +                memcpy(hds_path, data, sizeof(hds_path) - 1);
 +                INFO("send emuld to mount.\n");
 +                send_msg_to_guest(ccli, cmd, group, action, data, strlen(data));
 +            }
 +        } else {
 +            make_send_device_ntf(cmd, 100, 2, NULL);
-         INFO("try detach with is_hds_attached : %d\n", is_hds_attached);
-         if (is_hds_attached) {
++        }
 +    } else if (group == 100 && action == 2) {
-     TRACE(">> device_req: header = cmd = %s, length = %d, action=%d, group=%d\n", 
++        INFO("try detach with is_hds_attached : %d\n", is_hds_attached());
++        if (is_hds_attached()) {
 +            INFO("send emuld to umount.\n");
 +            send_msg_to_guest(ccli, cmd, group, action, NULL, 0);
 +        } else {
 +            INFO("hds is not attached. do not try detach it.\n");
 +        }
 +    } else {
 +        ERR("hds unknown command: group %d action %d\n", group, action);
 +    }
 +
 +    if (data) {
 +        g_free(data);
 +    }
 +}
 +
 +bool msgproc_device_req(ECS_Client* ccli, ECS__DeviceReq* msg)
 +{
 +    char cmd[10];
 +    memset(cmd, 0, 10);
 +    strcpy(cmd, msg->category);
 +
++    TRACE(">> device_req: header = cmd = %s, length = %d, action=%d, group=%d\n",
 +            cmd, msg->length, msg->action, msg->group);
 +
 +    if (!strcmp(cmd, MSG_TYPE_SENSOR)) {
 +        msgproc_device_req_sensor(ccli, msg, cmd);
 +    } else if (!strcmp(cmd, "Network")) {
 +        msgproc_device_req_network(ccli, msg);
 +    } else if (!strcmp(cmd, "TGesture")) {
 +        msgproc_device_req_tgesture(ccli, msg);
 +    } else if (!strcmp(cmd, "info")) {
 +        // check to emulator target image path
 +        TRACE("receive info message %s\n", tizen_target_img_path);
 +        send_target_image_information(ccli);
 +    } else if (!strcmp(cmd, "hds")) {
 +        msgproc_device_req_hds(ccli, msg, cmd);
 +    } else if (!strcmp(cmd, "input")) {
 +        msgproc_device_req_input(ccli, msg, cmd);
 +    } else if (!strcmp(cmd, "vmname")) {
 +        char* vmname = get_emul_vm_name();
 +        msgproc_device_ans(ccli, cmd, true, vmname);
 +    } else if (!strcmp(cmd, "nfc")) {
 +        msgproc_device_req_nfc(ccli, msg);
 +    } else {
 +        ERR("unknown cmd [%s]\n", cmd);
 +    }
 +
 +    return true;
 +}
 +
 +bool send_device_ntf(const char* data, const int len)
 +{
 +    type_length length = 0;
 +    type_group group = 0;
 +    type_action action = 0;
 +
 +    const int catsize = 10;
 +    char cat[catsize + 1];
 +    memset(cat, 0, catsize + 1);
 +
 +    read_val_str(data, cat, catsize);
 +    read_val_short(data + catsize, &length);
 +    read_val_char(data + catsize + 2, &group);
 +    read_val_char(data + catsize + 2 + 1, &action);
 +
 +    const char* ijdata = (data + catsize + 2 + 1 + 1);
 +
 +    TRACE("<< header cat = %s, length = %d, action=%d, group=%d\n", cat, length,action, group);
 +
 +    ECS__Master master = ECS__MASTER__INIT;
 +    ECS__DeviceNtf ntf = ECS__DEVICE_NTF__INIT;
 +
 +    ntf.category = (char*) g_malloc(catsize + 1);
 +    strncpy(ntf.category, cat, 10);
 +
 +
 +    ntf.length = length;
 +    ntf.group = group;
 +    ntf.action = action;
 +
 +    if (length > 0)
 +    {
 +        ntf.has_data = 1;
 +
 +        ntf.data.data = g_malloc(length);
 +        ntf.data.len = length;
 +        memcpy(ntf.data.data, ijdata, length);
 +
 +        TRACE("data = %s, length = %hu\n", ijdata, length);
 +    }
 +
 +    master.type = ECS__MASTER__TYPE__DEVICE_NTF;
 +    master.device_ntf = &ntf;
 +
 +    pb_to_all_clients(&master);
 +
 +    if (ntf.data.data && ntf.data.len > 0)
 +    {
 +        g_free(ntf.data.data);
 +    }
 +
 +    if (ntf.category)
 +        g_free(ntf.category);
 +
 +    return true;
 +}
 +
index 4373a8f520f12caa0e956dab805413c92db86982,0000000000000000000000000000000000000000..6f7f6e78b81e423a85e914966abd369e75010f23
mode 100644,000000..100644
--- /dev/null
@@@ -1,699 -1,0 +1,611 @@@
- #include "mloop_event.h"
 +/* Emulator Control Server
 + *
 + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
 + *
 + * Contact:
 + *  Jinhyung choi   <jinhyung2.choi@samsung.com>
 + *  MunKyu Im       <munkyu.im@samsung.com>
 + *  Daiyoung Kim    <daiyoung777.kim@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 "qemu-common.h"
 +
- #include "hw/maru_virtio_vmodem.h"
- #include "hw/maru_virtio_evdi.h"
- #include "hw/maru_virtio_jack.h"
- #include "hw/maru_virtio_power.h"
- #include "emulator.h"
++#include "hw/virtio/maru_virtio_vmodem.h"
++#include "hw/virtio/maru_virtio_evdi.h"
++#include "hw/virtio/maru_virtio_jack.h"
++#include "hw/virtio/maru_virtio_power.h"
 +
- static bool is_sdcard_attached = false;
++#include "util/maru_device_hotplug.h"
 +#include "emul_state.h"
 +#include "ecs.h"
 +#include "debug_ch.h"
 +
 +MULTI_DEBUG_CHANNEL(qemu, ecs);
 +
 +extern QemuMutex mutex_guest_connection;
 +static int guest_connection = 0;
 +
 +extern QemuMutex mutex_location_data;
 +static char location_data[MAX_INJECTOR_REQ_DATA];
 +
-     char *emul_bin_path = NULL;
 +static void msgproc_injector_ans(ECS_Client* ccli, const char* category, bool succeed)
 +{
 +    if (ccli == NULL) {
 +        return;
 +    }
 +    int catlen = 0;
 +    ECS__Master master = ECS__MASTER__INIT;
 +    ECS__InjectorAns ans = ECS__INJECTOR_ANS__INIT;
 +
 +    TRACE("injector ans - category : %s, succed : %d\n", category, succeed);
 +
 +    catlen = strlen(category);
 +    ans.category = (char*) g_malloc0(catlen + 1);
 +    memcpy(ans.category, category, catlen);
 +
 +    ans.errcode = !succeed;
 +    master.type = ECS__MASTER__TYPE__INJECTOR_ANS;
 +    master.injector_ans = &ans;
 +
 +    pb_to_all_clients(&master);
 +
 +    if (ans.category)
 +        g_free(ans.category);
 +}
 +
 +static bool injector_send(ECS_Client* ccli, ECS__InjectorReq* msg, char* cmd)
 +{
 +    int sndlen = 15; // HEADER(CMD + LENGTH + GROUP + ACTION) + 1
 +    const char* msg_data;
 +    char* sndbuf;
 +    bool ret = false;
 +    type_group group;
 +
 +    group = (type_group) (msg->group & 0xff);
 +
 +    if (msg->has_data && msg->data.data && msg->data.len > 0)
 +        sndlen += msg->data.len;
 +
 +    sndbuf = (char*) g_malloc0(sndlen);
 +    if (!sndbuf) {
 +        msgproc_injector_ans(ccli, cmd, false);
 +        return false;
 +    }
 +
 +    memcpy(sndbuf, cmd, 10);
 +    memcpy(sndbuf + 10, &msg->length, 2);
 +    memcpy(sndbuf + 12, &msg->group, 1);
 +    memcpy(sndbuf + 13, &msg->action, 1);
 +
 +    if (msg->has_data && msg->data.data && msg->data.len > 0) {
 +        msg_data = (const char*)msg->data.data;
 +        memcpy(sndbuf + 14, msg_data, msg->data.len);
 +        TRACE(">> print len = %zd, data\" %s\"\n", msg->data.len, msg_data);
 +    }
 +
 +    if(strcmp(cmd, "telephony") == 0) {
 +        TRACE("telephony msg >>");
 +        ret = send_to_vmodem(route_ij, sndbuf, sndlen);
 +    } else {
 +        TRACE("evdi msg >> %s", cmd);
 +        ret = send_to_evdi(route_ij, sndbuf, sndlen);
 +    }
 +
 +    g_free(sndbuf);
 +
 +    if (group != MSG_GROUP_STATUS) {
 +        msgproc_injector_ans(ccli, cmd, ret);
 +    }
 +
 +    if (!ret) {
 +        return false;
 +    }
 +
 +    return true;
 +}
 +
 +static char* get_emulator_sdcard_path(void)
 +{
 +    char *emulator_sdcard_path = NULL;
 +    char *tizen_sdk_data = NULL;
 +
 +#ifndef CONFIG_WIN32
 +    char emulator_sdcard[] = "/emulator/sdcard/";
 +#else
 +    char emulator_sdcard[] = "\\emulator\\sdcard\\";
 +#endif
 +
 +    TRACE("emulator_sdcard: %s, %zu\n", emulator_sdcard, sizeof(emulator_sdcard));
 +
 +    tizen_sdk_data = get_tizen_sdk_data_path();
 +    if (!tizen_sdk_data) {
 +        ERR("failed to get tizen-sdk-data path.\n");
 +        return NULL;
 +    }
 +
 +    emulator_sdcard_path =
 +        g_malloc(strlen(tizen_sdk_data) + sizeof(emulator_sdcard) + 1);
 +    if (!emulator_sdcard_path) {
 +        ERR("failed to allocate memory.\n");
 +        return NULL;
 +    }
 +
 +    g_snprintf(emulator_sdcard_path, strlen(tizen_sdk_data) + sizeof(emulator_sdcard),
 +             "%s%s", tizen_sdk_data, emulator_sdcard);
 +
 +    g_free(tizen_sdk_data);
 +
 +    TRACE("sdcard path: %s\n", emulator_sdcard_path);
 +    return emulator_sdcard_path;
 +}
 +
 +static char *get_old_tizen_sdk_data_path(void)
 +{
 +    char *tizen_sdk_data_path = NULL;
 +
 +    INFO("try to search tizen-sdk-data path in another way.\n");
 +
 +#ifndef CONFIG_WIN32
 +    char tizen_sdk_data[] = "/tizen-sdk-data";
 +    int tizen_sdk_data_len = 0;
 +    char *home_dir;
 +
 +    home_dir = (char *)g_getenv("HOME");
 +    if (!home_dir) {
 +        home_dir = (char *)g_get_home_dir();
 +    }
 +
 +    tizen_sdk_data_len = strlen(home_dir) + sizeof(tizen_sdk_data) + 1;
 +    tizen_sdk_data_path = g_malloc(tizen_sdk_data_len);
 +    if (!tizen_sdk_data_path) {
 +        ERR("failed to allocate memory.\n");
 +        return NULL;
 +    }
 +    g_strlcpy(tizen_sdk_data_path, home_dir, tizen_sdk_data_len);
 +    g_strlcat(tizen_sdk_data_path, tizen_sdk_data, tizen_sdk_data_len);
 +
 +#else
 +    char tizen_sdk_data[] = "\\tizen-sdk-data\\";
 +    gint tizen_sdk_data_len = 0;
 +    HKEY hKey;
 +    char strLocalAppDataPath[1024] = { 0 };
 +    DWORD dwBufLen = 1024;
 +
 +    RegOpenKeyEx(HKEY_CURRENT_USER,
 +        "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
 +        0, KEY_QUERY_VALUE, &hKey);
 +
 +    RegQueryValueEx(hKey, "Local AppData", NULL,
 +                    NULL, (LPBYTE)strLocalAppDataPath, &dwBufLen);
 +    RegCloseKey(hKey);
 +
 +    tizen_sdk_data_len = strlen(strLocalAppDataPath) + sizeof(tizen_sdk_data) + 1;
 +    tizen_sdk_data_path = g_malloc(tizen_sdk_data_len);
 +    if (!tizen_sdk_data_path) {
 +        ERR("failed to allocate memory.\n");
 +        return NULL;
 +    }
 +
 +    g_strlcpy(tizen_sdk_data_path, strLocalAppDataPath, tizen_sdk_data_len);
 +    g_strlcat(tizen_sdk_data_path, tizen_sdk_data, tizen_sdk_data_len);
 +#endif
 +
 +    INFO("tizen-sdk-data path: %s\n", tizen_sdk_data_path);
 +    return tizen_sdk_data_path;
 +}
 +
 +/*
 + *  get tizen-sdk-data path from sdk.info.
 + */
 +char *get_tizen_sdk_data_path(void)
 +{
- static void send_gen_injector_ntf(const char* cmd, int cmdlen, int grp, int act, char* on)
++    char const *emul_bin_path = NULL;
 +    char *sdk_info_file_path = NULL;
 +    char *tizen_sdk_data_path = NULL;
 +#ifndef CONFIG_WIN32
 +    const char *sdk_info = "../../../sdk.info";
 +#else
 +    const char *sdk_info = "..\\..\\..\\sdk.info";
 +#endif
 +    const char sdk_data_var[] = "TIZEN_SDK_DATA_PATH";
 +
 +    FILE *sdk_info_fp = NULL;
 +    int sdk_info_path_len = 0;
 +
 +    TRACE("%s\n", __func__);
 +
 +    emul_bin_path = get_bin_path();
 +    if (!emul_bin_path) {
 +        ERR("failed to get emulator path.\n");
 +        return NULL;
 +    }
 +
 +    sdk_info_path_len = strlen(emul_bin_path) + strlen(sdk_info) + 1;
 +    sdk_info_file_path = g_malloc(sdk_info_path_len);
 +    if (!sdk_info_file_path) {
 +        ERR("failed to allocate sdk-data buffer.\n");
 +        return NULL;
 +    }
 +
 +    g_snprintf(sdk_info_file_path, sdk_info_path_len, "%s%s",
 +                emul_bin_path, sdk_info);
 +    INFO("sdk.info path: %s\n", sdk_info_file_path);
 +
 +    sdk_info_fp = fopen(sdk_info_file_path, "r");
 +    g_free(sdk_info_file_path);
 +
 +    if (sdk_info_fp) {
 +        TRACE("Succeeded to open [sdk.info].\n");
 +
 +        char tmp[256] = { '\0', };
 +        char *tmpline = NULL;
 +        while (fgets(tmp, sizeof(tmp), sdk_info_fp) != NULL) {
 +            if ((tmpline = g_strstr_len(tmp, sizeof(tmp), sdk_data_var))) {
 +                tmpline += strlen(sdk_data_var) + 1; // 1 for '='
 +                break;
 +            }
 +        }
 +
 +        if (tmpline) {
 +            if (tmpline[strlen(tmpline) - 1] == '\n') {
 +                tmpline[strlen(tmpline) - 1] = '\0';
 +            }
 +            if (tmpline[strlen(tmpline) - 1] == '\r') {
 +                tmpline[strlen(tmpline) - 1] = '\0';
 +            }
 +
 +            tizen_sdk_data_path = g_malloc(strlen(tmpline) + 1);
 +            g_strlcpy(tizen_sdk_data_path, tmpline, strlen(tmpline) + 1);
 +
 +            INFO("tizen-sdk-data path: %s\n", tizen_sdk_data_path);
 +
 +            fclose(sdk_info_fp);
 +            return tizen_sdk_data_path;
 +        }
 +
 +        fclose(sdk_info_fp);
 +    }
 +
 +    // legacy mode
 +    ERR("Failed to open [sdk.info].\n");
 +
 +    return get_old_tizen_sdk_data_path();
 +}
 +
-     int msglen = 0, datalen = 0;
-     type_length length  = 0;
-     type_group group = grp;
-     type_action action = act;
++static void handle_sdcard(char* dataBuf, size_t dataLen)
 +{
-     if (cmd == NULL || cmdlen > 10)
-         return;
-     if (on == NULL) {
-         msglen = 14;
-     } else {
-         datalen = strlen(on);
-         length  = (unsigned short)datalen;
-         msglen = datalen + 15;
-     }
-     char* status_msg = (char*) malloc(msglen);
-     if(!status_msg)
-         return;
-     memset(status_msg, 0, msglen);
-     memcpy(status_msg, cmd, cmdlen);
-     memcpy(status_msg + 10, &length, sizeof(unsigned short));
-     memcpy(status_msg + 12, &group, sizeof(unsigned char));
-     memcpy(status_msg + 13, &action, sizeof(unsigned char));
-     if (on != NULL) {
-         memcpy(status_msg + 14, on, datalen);
-     }
-     send_injector_ntf(status_msg, msglen);
-     if (status_msg)
-         free(status_msg);
- }
- static bool handle_sdcard(char* dataBuf, size_t dataLen)
- {
-     int err_no = 0;
 +
-     INFO("handle_sdcard() data: %s\n", dataBuf);
-     if (dataBuf != NULL) {
 +    char ret = 0;
-             //mloop_evcmd_usbdisk(NULL);
-             char sdcard_img_path[256];
-             char* sdcard_path = NULL;
-             sdcard_path = get_emulator_sdcard_path();
-             if (sdcard_path) {
-                 g_strlcpy(sdcard_img_path, sdcard_path,
-                         sizeof(sdcard_img_path));
-                 /* emulator_sdcard_img_path + sdcard img name */
-                 char* sdcard_img_name = dataBuf+2;
-                 if (dataLen > 3 && sdcard_img_name != NULL) {
-                     char* pLinechange = strchr(sdcard_img_name, '\n');
-                     if(pLinechange != NULL){
-                         sdcard_img_name = g_strndup(sdcard_img_name, pLinechange - sdcard_img_name);
-                     }
-                     g_strlcat(sdcard_img_path, sdcard_img_name, sizeof(sdcard_img_path));
-                     INFO("sdcard path: [%s]\n", sdcard_img_path);
-                     /*if using strndup than free string*/
-                     if (pLinechange != NULL && sdcard_img_name!= NULL) {
-                         free(sdcard_img_name);
-                     }
-                 }
-                 g_free(sdcard_path);
-             }
-             err_no = remove_sdcard_lock_os(sdcard_img_path);
-             INFO("umount err_no: %d\n", err_no);
-             if (errno == 0 && is_sdcard_attached) {
-                 mloop_evcmd_sdcard(NULL);
-                 is_sdcard_attached = false;
-             } else {
-                 ERR("failed to umount: %s\n", sdcard_img_path);
-                 send_gen_injector_ntf(MSG_TYPE_SDCARD, 6, 11, err_no, NULL);
-                 return err_no;
-             }
-         }
-         else if (ret == '1') {
++
++    if (dataBuf != NULL){
 +        ret = dataBuf[0];
 +
 +        if (ret == '0' ) {
 +            /* umount sdcard */
-                 if (dataLen > 3 && sdcard_img_name != NULL) {
++            do_hotplug(DETACH_SDCARD, NULL, 0);
++        } else if (ret == '1') {
 +            /* mount sdcard */
 +            char sdcard_img_path[256];
 +            char* sdcard_path = NULL;
 +
 +            sdcard_path = get_emulator_sdcard_path();
 +            if (sdcard_path) {
 +                g_strlcpy(sdcard_img_path, sdcard_path,
 +                        sizeof(sdcard_img_path));
 +
 +                /* emulator_sdcard_img_path + sdcard img name */
 +                char* sdcard_img_name = dataBuf+2;
-                     //mloop_evcmd_usbdisk(sdcard_img_path);
-                     if (!is_sdcard_attached && make_sdcard_lock_os(sdcard_img_path)) {
-                         mloop_evcmd_sdcard(sdcard_img_path);
-                         is_sdcard_attached = true;
-                     } else {
-                         send_gen_injector_ntf(MSG_TYPE_SDCARD, 6, 11, 5, NULL);
-                         return ERR_LCK;
-                     }
++                if(dataLen > 3 && sdcard_img_name != NULL){
 +                    char* pLinechange = strchr(sdcard_img_name, '\n');
 +                    if(pLinechange != NULL){
 +                        sdcard_img_name = g_strndup(sdcard_img_name, pLinechange - sdcard_img_name);
 +                    }
 +
 +                    g_strlcat(sdcard_img_path, sdcard_img_name, sizeof(sdcard_img_path));
 +                    TRACE("sdcard path: [%s]\n", sdcard_img_path);
 +
-                     if (pLinechange != NULL && sdcard_img_name!= NULL) {
++                    do_hotplug(ATTACH_SDCARD, sdcard_img_path, strlen(sdcard_img_path) + 1);
++
 +                    /*if using strndup than free string*/
-         } else if (ret == '2') {
-             TRACE("sdcard status 2 bypass\n" );
-         } else {
++                    if(pLinechange != NULL && sdcard_img_name!= NULL){
 +                        free(sdcard_img_name);
 +                    }
 +
 +                }
 +
 +                g_free(sdcard_path);
 +            } else {
 +                ERR("failed to get sdcard path!!\n");
 +            }
-     } else {
++        } else if(ret == '2'){
++            TRACE("sdcard status 2 bypass" );
++        }else {
 +            ERR("!!! unknown command : %c\n", ret);
 +        }
 +
-     return ERR_SUCCESS;
++    }else{
 +        ERR("!!! unknown data : %c\n", ret);
 +    }
-         if (handle_sdcard((char*) msg->data.data, msg->data.len) > 0) {
-             return false;
-         }
 +}
 +
 +static bool injector_req_sdcard(ECS_Client* ccli, ECS__InjectorReq* msg, char *cmd)
 +{
 +    if (msg->has_data) {
 +        TRACE("msg(%zu) : %s\n", msg->data.len, msg->data.data);
-     return injector_send(ccli, msg, cmd);
++        handle_sdcard((char*) msg->data.data, msg->data.len);
 +    } else {
 +        ERR("has no msg\n");
 +    }
 +
-                 if (!do_virtfs_detach()) {
++    injector_send(ccli, msg, cmd);
++
++    return true;
 +}
 +
 +static void send_status_injector_ntf(const char* cmd, int cmdlen, int act, char* on)
 +{
 +    int msglen = 0, datalen = 0;
 +    type_length length  = 0;
 +    type_group group = MSG_GROUP_STATUS;
 +    type_action action = act;
 +
 +    if (cmd == NULL || cmdlen > 10)
 +        return;
 +
 +    if (on == NULL) {
 +        msglen = 14;
 +    } else {
 +        datalen = strlen(on);
 +        length  = (unsigned short)datalen;
 +
 +        msglen = datalen + 15;
 +    }
 +
 +    char* status_msg = (char*) malloc(msglen);
 +    if(!status_msg)
 +        return;
 +
 +    memset(status_msg, 0, msglen);
 +
 +    memcpy(status_msg, cmd, cmdlen);
 +    memcpy(status_msg + 10, &length, sizeof(unsigned short));
 +    memcpy(status_msg + 12, &group, sizeof(unsigned char));
 +    memcpy(status_msg + 13, &action, sizeof(unsigned char));
 +
 +    if (on != NULL) {
 +        memcpy(status_msg + 14, on, datalen);
 +    }
 +
 +    send_injector_ntf(status_msg, msglen);
 +
 +    if (status_msg)
 +        free(status_msg);
 +}
 +
 +static bool injector_req_sensor(ECS_Client* ccli, ECS__InjectorReq* msg, char *cmd)
 +{
 +    char data[MAX_INJECTOR_REQ_DATA];
 +    type_group group;
 +    type_action action;
 +
 +    memset(data, 0, MAX_INJECTOR_REQ_DATA);
 +    group = (type_group) (msg->group & 0xff);
 +    action = (type_action) (msg->action & 0xff);
 +
 +    if (group == MSG_GROUP_STATUS) {
 +        switch (action) {
 +        case MSG_ACT_BATTERY_LEVEL:
 +            sprintf(data, "%d", get_power_capacity());
 +            break;
 +        case MSG_ACT_BATTERY_CHARGER:
 +            sprintf(data, "%d", get_jack_charger());
 +            break;
 +        case MSG_ACT_USB:
 +            sprintf(data, "%d", get_jack_usb());
 +            break;
 +        case MSG_ACT_EARJACK:
 +            sprintf(data, "%d", get_jack_earjack());
 +            break;
 +        case MSG_ACT_LOCATION:
 +            qemu_mutex_lock(&mutex_location_data);
 +            sprintf(data, "%s", location_data);
 +            qemu_mutex_unlock(&mutex_location_data);
 +            break;
 +        default:
 +            return injector_send(ccli, msg, cmd);
 +        }
 +        TRACE("status : %s\n", data);
 +        send_status_injector_ntf(MSG_TYPE_SENSOR, 6, action, data);
 +        return true;
 +    } else if (msg->data.data && msg->data.len > 0) {
 +        set_injector_data((char*) msg->data.data);
 +        return injector_send(ccli, msg, cmd);
 +    }
 +
 +    return false;
 +}
 +
 +static bool injector_req_guest(void)
 +{
 +    int value = 0;
 +    qemu_mutex_lock(&mutex_guest_connection);
 +    value = guest_connection;
 +    qemu_mutex_unlock(&mutex_guest_connection);
 +    send_status_injector_ntf(MSG_TYPE_GUEST, 5, value, NULL);
 +    return true;
 +}
 +
 +static bool injector_req_location(ECS_Client* ccli, ECS__InjectorReq* msg, char *cmd)
 +{
 +    if (msg->data.data != NULL && msg->data.len > 0) {
 +        qemu_mutex_lock(&mutex_location_data);
 +        snprintf(location_data, msg->data.len + 1, "%s", (char*)msg->data.data);
 +        qemu_mutex_unlock(&mutex_location_data);
 +        return injector_send(ccli, msg, cmd);
 +    }
 +
 +    return false;
 +}
 +
 +bool msgproc_injector_req(ECS_Client* ccli, ECS__InjectorReq* msg)
 +{
 +    char cmd[11];
 +    bool ret = false;
 +
 +    strncpy(cmd, msg->category, sizeof(cmd) - 1);
 +
 +    if (!strcmp(cmd, MSG_TYPE_SDCARD)) {
 +        ret = injector_req_sdcard(ccli, msg, cmd);
 +    } else if (!strcmp(cmd, MSG_TYPE_SENSOR)) {
 +        ret = injector_req_sensor(ccli, msg, cmd);
 +    } else if (!strcmp(cmd, MSG_TYPE_GUEST)) {
 +        ret = injector_req_guest();
 +    } else if (!strcmp(cmd, MSG_TYPE_LOCATION)) {
 +        ret = injector_req_location(ccli, msg, cmd);
 +    } else {
 +        ret = injector_send(ccli, msg, cmd);
 +    }
 +
 +    return ret;
 +}
 +
 +void ecs_suspend_lock_state(int state)
 +{
 +    int catlen;
 +
 +    ECS__InjectorReq msg = ECS__INJECTOR_REQ__INIT;
 +    const char* category = "suspend";
 +
 +    catlen = strlen(category);
 +    msg.category = (char*) g_malloc0(catlen + 1);
 +    memcpy(msg.category, category, catlen);
 +
 +    msg.group = 5;
 +    msg.action = state;
 +
 +    msgproc_injector_req(NULL, &msg);
 +}
 +
 +#define MSG_GROUP_HDS   100
 +static bool injector_req_handle(char* cat, type_action action)
 +{
 +    /*SD CARD msg process*/
 +    if (!strcmp(cat, MSG_TYPE_SDCARD)) {
 +        return false;
 +    } else if (!strcmp(cat, "suspend")) {
 +        ecs_suspend_lock_state(ecs_get_suspend_state());
 +        return true;
 +    } else if (!strcmp(cat, MSG_TYPE_GUEST)) {
 +        INFO("emuld connection is %d\n", action);
 +        qemu_mutex_lock(&mutex_guest_connection);
 +        guest_connection = action;
 +        qemu_mutex_unlock(&mutex_guest_connection);
 +        return false;
 +    } else if (!strcmp(cat, "hds")) {
 +        INFO("hds status is %d\n", action);
 +        switch (action) {
 +            case 1:
 +                make_send_device_ntf(cat, MSG_GROUP_HDS, action, NULL);
 +                break;
 +            case 2:
 +                make_send_device_ntf(cat, MSG_GROUP_HDS, action, NULL);
 +                break;
 +            case 3:
++                do_hotplug(DETACH_HDS, NULL, 0);
++                if (!is_hds_attached()) {
 +                    make_send_device_ntf(cat, MSG_GROUP_HDS, 5, NULL);
 +                } else {
 +                    make_send_device_ntf(cat, MSG_GROUP_HDS, action, NULL);
 +                }
 +                break;
 +            case 4:
 +                make_send_device_ntf(cat, MSG_GROUP_HDS, action, NULL);
 +                break;
 +            default:
 +                ERR("unknown action: %s.\n", action);
 +                break;
 +        }
 +        return true;
 +    } else {
 +        ERR("unknown command: %s.\n", cat);
 +    }
 +
 +    return false;
 +}
 +
 +bool send_injector_ntf(const char* data, const int len)
 +{
 +    type_length length = 0;
 +    type_group group = 0;
 +    type_action action = 0;
 +
 +    const int catsize = 10;
 +    char cat[catsize + 1];
 +    memset(cat, 0, catsize + 1);
 +
 +    read_val_str(data, cat, catsize);
 +    read_val_short(data + catsize, &length);
 +    read_val_char(data + catsize + 2, &group);
 +    read_val_char(data + catsize + 2 + 1, &action);
 +
 +    if (injector_req_handle(cat, action)) {
 +        return true;
 +    }
 +
 +    const char* ijdata = (data + catsize + 2 + 1 + 1);
 +
 +    TRACE("<< header cat = %s, length = %d, action=%d, group=%d\n", cat, length,action, group);
 +
 +    ECS__Master master = ECS__MASTER__INIT;
 +    ECS__InjectorNtf ntf = ECS__INJECTOR_NTF__INIT;
 +
 +    ntf.category = (char*) g_malloc(catsize + 1);
 +    strncpy(ntf.category, cat, 10);
 +
 +    ntf.length = length;
 +    ntf.group = group;
 +    ntf.action = action;
 +
 +    if (length > 0)
 +    {
 +        ntf.has_data = 1;
 +
 +        ntf.data.data = g_malloc(length);
 +        ntf.data.len = length;
 +        memcpy(ntf.data.data, ijdata, length);
 +    }
 +
 +    master.type = ECS__MASTER__TYPE__INJECTOR_NTF;
 +    master.injector_ntf = &ntf;
 +
 +    pb_to_all_clients(&master);
 +
 +    if (ntf.data.len > 0)
 +    {
 +        g_free(ntf.data.data);
 +    }
 +
 +    g_free(ntf.category);
 +
 +    return true;
 +}
 +
index 7e5ee5ff8ca21463f9740d3f9eb97ab69b293c23,0000000000000000000000000000000000000000..dcc1e4c5d5ef404acca11dbe2717599291391c15
mode 100644,000000..100644
--- /dev/null
@@@ -1,116 -1,0 +1,116 @@@
- #include "hw/maru_virtio_nfc.h"
 +/* Emulator Control Server
 + *
 + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
 + *
 + * Contact:
 + *  Jinhyung choi   <jinhyung2.choi@samsung.com>
 + *  MunKyu Im       <munkyu.im@samsung.com>
 + *  Daiyoung Kim    <daiyoung777.kim@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 "qemu-common.h"
 +
++#include "hw/virtio/maru_virtio_nfc.h"
 +
 +#include "ecs.h"
 +
 +#include "debug_ch.h"
 +
 +MULTI_DEBUG_CHANNEL(qemu, ecs);
 +
 +bool msgproc_nfc_req(ECS_Client* ccli, ECS__NfcReq* msg)
 +{
 +    int datalen = msg->data.len;
 +    void* data = (void*)g_malloc(datalen);
 +    if(!data) {
 +        ERR("g_malloc failed!\n");
 +        return false;
 +    }
 +
 +    memset(data, 0, datalen);
 +    memcpy(data, msg->data.data, msg->data.len);
 +
 +    if (msg->has_data && msg->data.len > 0)
 +    {
 +        TRACE("recv from nfc injector: %s, %z\n", msg->has_data, msg->data.len);
 +        print_binary(data, datalen);
 +    }
 +
 +    send_to_nfc(ccli->client_id, ccli->client_type, data, msg->data.len);
 +    g_free(data);
 +    return true;
 +}
 +
 +bool send_nfc_ntf(struct nfc_msg_info* msg)
 +{
 +    const int catsize = 10;
 +    char cat[catsize + 1];
 +    ECS_Client *clii;
 +    memset(cat, 0, catsize + 1);
 +
 +    print_binary((char*)msg->buf, msg->use);
 +    TRACE("id: %02x, type: %02x, use: %d\n", msg->client_id, msg->client_type, msg->use);
 +    clii =  find_client(msg->client_id, msg->client_type);
 +    if (clii) {
 +        if(clii->client_type == TYPE_SIMUL_NFC) {
 +            strncpy(cat, MSG_TYPE_NFC, 3);
 +        } else if (clii->client_type == TYPE_ECP) {
 +            strncpy(cat, MSG_TYPE_SIMUL_NFC, 9);
 +        }else {
 +            ERR("cannot find type! : %d\n", clii->client_type);
 +        }
 +        TRACE("header category = %s\n", cat);
 +    }
 +    else {
 +        ERR("cannot find client!\n");
 +    }
 +
 +    ECS__Master master = ECS__MASTER__INIT;
 +    ECS__NfcNtf ntf = ECS__NFC_NTF__INIT;
 +
 +    ntf.category = (char*) g_malloc(catsize + 1);
 +    strncpy(ntf.category, cat, 10);
 +
 +    ntf.has_data = 1;
 +
 +    ntf.data.data = g_malloc(NFC_MAX_BUF_SIZE);
 +    ntf.data.len = NFC_MAX_BUF_SIZE;
 +    memcpy(ntf.data.data, msg->buf, NFC_MAX_BUF_SIZE);
 +
 +    TRACE("send to nfc injector: \n");
 +    master.type = ECS__MASTER__TYPE__NFC_NTF;
 +    master.nfc_ntf = &ntf;
 +
 +    pb_to_all_clients(&master);
 +
 +    if (ntf.data.data && ntf.data.len > 0)
 +    {
 +        g_free(ntf.data.data);
 +    }
 +
 +    if (ntf.category)
 +        g_free(ntf.category);
 +
 +    return true;
 +}
 +
 +
Simple merge
index 740ff93bc805262d76025aa2db1eb0477cf27a7d,2663d776a662cc41933da5f0bb9ff852b4579f73..0266102048f4a27dada00ab7092c868a2b9015b8
  #ifndef __EMUL_STATE_H__
  #define __EMUL_STATE_H__
  
- #include "maru_common.h"
- #include "maru_finger.h"
+ #include "display/maru_finger.h"
+ #define SUPPORT_LEGACY_ARGS
+ #define MAX_ADDR_LEN    256
+ #define MAX_PORT_LEN    256
  
 +#define MAX_ADDR_LEN    256
 +#define MAX_PORT_LEN    256
 +
  enum {
      RESET = 0,
      BOOT_COMPLETED = 1,
index 0000000000000000000000000000000000000000,cb6585dceeccb0a47342f49af57234ab6fff98d3..b0217336828e445dcd790eb0696015066e58dbdb
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,1757 +1,1773 @@@
 -        // FIXME: improve error handling
 -        // return false;
+ /*
+  * Virtual Codec Device
+  *
+  * Copyright (c) 2013 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+  *
+  * Contact:
+  *  Kitae Kim <kt920.kim@samsung.com>
+  *  SeokYeon Hwang <syeon.hwang@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 "maru_brillcodec.h"
+ #include "libavresample/avresample.h"
+ #include "libavutil/mathematics.h"
+ #include "libavutil/opt.h"
+ #include "libavformat/avformat.h"
+ #include "debug_ch.h"
+ /* define debug channel */
+ MULTI_DEBUG_CHANNEL(qemu, brillcodec);
+ // device memory
+ #define CODEC_META_DATA_SIZE    (256)
+ // libav
+ #define GEN_MASK(x) ((1 << (x)) - 1)
+ #define ROUND_UP_X(v, x) (((v) + GEN_MASK(x)) & ~GEN_MASK(x))
+ #define ROUND_UP_2(x) ROUND_UP_X(x, 1)
+ #define ROUND_UP_4(x) ROUND_UP_X(x, 2)
+ #define ROUND_UP_8(x) ROUND_UP_X(x, 3)
+ #define DIV_ROUND_UP_X(v, x) (((v) + GEN_MASK(x)) >> (x))
+ #define DEFAULT_VIDEO_GOP_SIZE 15
+ enum codec_api_type {
+     CODEC_INIT = 0,
+     CODEC_DECODE_VIDEO,
+     CODEC_ENCODE_VIDEO,
+     CODEC_DECODE_AUDIO,
+     CODEC_ENCODE_AUDIO,
+     CODEC_PICTURE_COPY,
+     CODEC_DEINIT,
+     CODEC_FLUSH_BUFFERS,
+  };
+ enum codec_type {
+     CODEC_TYPE_UNKNOWN = -1,
+     CODEC_TYPE_DECODE,
+     CODEC_TYPE_ENCODE,
+ };
+ struct video_data {
+     int32_t width;
+     int32_t height;
+     int32_t fps_n;
+     int32_t fps_d;
+     int32_t par_n;
+     int32_t par_d;
+     int32_t pix_fmt;
+     int32_t bpp;
+     int32_t ticks_per_frame;
+ };
+ struct audio_data {
+     int32_t channels;
+     int32_t sample_rate;
+     int32_t block_align;
+     int32_t depth;
+     int32_t sample_fmt;
+     int32_t frame_size;
+     int32_t bits_per_smp_fmt;
+     int32_t reserved;
+     int64_t channel_layout;
+ };
+ DeviceMemEntry *entry[CODEC_CONTEXT_MAX];
+ // define a queue to manage ioparam, context data
+ typedef struct CodecDataStg {
+     CodecParam *param_buf;
+     DeviceMemEntry *data_buf;
+     QTAILQ_ENTRY(CodecDataStg) node;
+ } CodecDataStg;
+ // define two queue to store input and output buffers.
+ struct codec_wq codec_wq = QTAILQ_HEAD_INITIALIZER(codec_wq);
+ static QTAILQ_HEAD(codec_rq, CodecDataStg) codec_rq =
+    QTAILQ_HEAD_INITIALIZER(codec_rq);
+ // codec functions
+ static bool codec_init(MaruBrillCodecState *, int, void *);
+ static bool codec_deinit(MaruBrillCodecState *, int, void *);
+ static bool codec_decode_video(MaruBrillCodecState *, int, void *);
+ static bool codec_encode_video(MaruBrillCodecState *, int, void *);
+ static bool codec_decode_audio(MaruBrillCodecState *, int, void *);
+ static bool codec_encode_audio(MaruBrillCodecState *, int, void *);
+ static bool codec_picture_copy(MaruBrillCodecState *, int, void *);
+ static bool codec_flush_buffers(MaruBrillCodecState *, int, void *);
+ typedef bool (*CodecFuncEntry)(MaruBrillCodecState *, int, void *);
+ static CodecFuncEntry codec_func_handler[] = {
+     codec_init,
+     codec_decode_video,
+     codec_encode_video,
+     codec_decode_audio,
+     codec_encode_audio,
+     codec_picture_copy,
+     codec_deinit,
+     codec_flush_buffers,
+ };
+ static AVCodecParserContext *maru_brill_codec_parser_init(AVCodecContext *avctx);
+ static void maru_brill_codec_push_readqueue(MaruBrillCodecState *s, CodecParam *ioparam);
+ static void maru_brill_codec_push_writequeue(MaruBrillCodecState *s, void* opaque,
+                                             size_t data_size, int ctx_id,
+                                             DataHandler *handler);
+ static void *maru_brill_codec_store_inbuf(uint8_t *mem_base, CodecParam *ioparam);
+ // default handler
+ static void default_get_data(void *dst, void *src, size_t size, enum AVPixelFormat pix_fmt) {
+     memcpy(dst, src, size);
+ }
+ static void default_release(void *opaque) {
+     g_free(opaque);
+ }
+ static DataHandler default_data_handler = {
+     .get_data = default_get_data,
+     .release = default_release,
+ };
+ // default video decode data handler
+ static void extract(void *dst, void *src, size_t size, enum AVPixelFormat pix_fmt) {
+     AVFrame *frame = (AVFrame *)src;
+     avpicture_layout((AVPicture *)src, pix_fmt, frame->width, frame->height, dst, size);
+ }
+ static void release(void *buf) {}
+ static DataHandler default_video_decode_data_handler = {
+     .get_data = extract,
+     .release = release,
+ };
+ static void maru_brill_codec_thread_exit(MaruBrillCodecState *s)
+ {
+     int index;
+     TRACE("enter: %s\n", __func__);
+     /* stop to run dedicated threads. */
+     s->is_thread_running = false;
+     for (index = 0; index < s->worker_thread_cnt; index++) {
+         qemu_thread_join(&s->threadpool.threads[index]);
+     }
+     TRACE("destroy mutex and conditional.\n");
+     qemu_mutex_destroy(&s->threadpool.mutex);
+     qemu_cond_destroy(&s->threadpool.cond);
+     if (s->threadpool.threads) {
+         g_free(s->threadpool.threads);
+         s->threadpool.threads = NULL;
+     }
+     TRACE("leave: %s\n", __func__);
+ }
+ void maru_brill_codec_wakeup_threads(MaruBrillCodecState *s, int api_index)
+ {
+     CodecParam *ioparam = NULL;
+     ioparam = g_malloc0(sizeof(CodecParam));
+     if (!ioparam) {
+         ERR("failed to allocate ioparam\n");
+         return;
+     }
+     memcpy(ioparam, &s->ioparam, sizeof(CodecParam));
+     TRACE("wakeup thread. ctx_id: %u, api_id: %u, mem_offset: 0x%x\n",
+         ioparam->ctx_index, ioparam->api_index, ioparam->mem_offset);
+     qemu_mutex_lock(&s->context_mutex);
+     if (ioparam->api_index != CODEC_INIT) {
+         if (!CONTEXT(s, ioparam->ctx_index).opened_context) {
+             INFO("abandon api %d for context %d\n",
+                     ioparam->api_index, ioparam->ctx_index);
+             qemu_mutex_unlock(&s->context_mutex);
+             return;
+         }
+     }
+     qemu_mutex_unlock(&s->context_mutex);
+     maru_brill_codec_push_readqueue(s, ioparam);
+     qemu_mutex_lock(&s->context_mutex);
+     // W/A for threads starvation.
+     while (s->idle_thread_cnt == 0) {
+         qemu_mutex_unlock(&s->context_mutex);
+         TRACE("Worker threads are exhausted\n");
+         usleep(2000); // wait 2ms.
+         qemu_mutex_lock(&s->context_mutex);
+     }
+     qemu_cond_signal(&s->threadpool.cond);
+     qemu_mutex_unlock(&s->context_mutex);
+     TRACE("after sending conditional signal\n");
+ }
+ void *maru_brill_codec_threads(void *opaque)
+ {
+     MaruBrillCodecState *s = (MaruBrillCodecState *)opaque;
+     bool ret = false;
+     TRACE("enter: %s\n", __func__);
+     while (s->is_thread_running) {
+         int ctx_id = 0, api_id = 0;
+         CodecDataStg *elem = NULL;
+         DeviceMemEntry *indata_buf = NULL;
+         qemu_mutex_lock(&s->context_mutex);
+         ++(s->idle_thread_cnt); // protected under mutex.
+         qemu_cond_wait(&s->threadpool.cond, &s->context_mutex);
+         --(s->idle_thread_cnt); // protected under mutex.
+         qemu_mutex_unlock(&s->context_mutex);
+         qemu_mutex_lock(&s->ioparam_queue_mutex);
+         elem = QTAILQ_FIRST(&codec_rq);
+         if (elem) {
+             QTAILQ_REMOVE(&codec_rq, elem, node);
+             qemu_mutex_unlock(&s->ioparam_queue_mutex);
+         } else {
+             qemu_mutex_unlock(&s->ioparam_queue_mutex);
+             continue;
+         }
+         if (!elem->param_buf) {
+             continue;
+         }
+         api_id = elem->param_buf->api_index;
+         ctx_id = elem->param_buf->ctx_index;
+         indata_buf = elem->data_buf;
+         TRACE("api_id: %d ctx_id: %d\n", api_id, ctx_id);
+         qemu_mutex_lock(&s->context_mutex);
+         CONTEXT(s, ctx_id).occupied_thread = true;
+         qemu_mutex_unlock(&s->context_mutex);
+         ret = codec_func_handler[api_id](s, ctx_id, indata_buf);
+         if (!ret) {
+             ERR("fail api %d for context %d\n", api_id, ctx_id);
+             g_free(elem->param_buf);
+             continue;
+         }
+         TRACE("release a buffer of CodecParam\n");
+         g_free(elem->param_buf);
+         elem->param_buf = NULL;
+         if (elem->data_buf) {
+             if (elem->data_buf->opaque) {
+                 TRACE("release inbuf\n");
+                 g_free(elem->data_buf->opaque);
+                 elem->data_buf->opaque = NULL;
+             }
+             TRACE("release a buffer indata_buf\n");
+             g_free(elem->data_buf);
+             elem->data_buf = NULL;
+         }
+         TRACE("release an element of CodecDataStg\n");
+         g_free(elem);
+         qemu_mutex_lock(&s->context_mutex);
+         if (CONTEXT(s, ctx_id).requested_close) {
+             INFO("make worker thread to handle deinit\n");
+             // codec_deinit(s, ctx_id, NULL);
+             maru_brill_codec_release_context(s, ctx_id);
+             CONTEXT(s, ctx_id).requested_close = false;
+         }
+         qemu_mutex_unlock(&s->context_mutex);
+         TRACE("switch context to raise interrupt.\n");
+         qemu_bh_schedule(s->codec_bh);
+         qemu_mutex_lock(&s->context_mutex);
+         CONTEXT(s, ctx_id).occupied_thread = false;
+         qemu_mutex_unlock(&s->context_mutex);
+     }
+     maru_brill_codec_thread_exit(s);
+     TRACE("leave: %s\n", __func__);
+     return NULL;
+ }
+ // queue
+ static void maru_brill_codec_push_readqueue(MaruBrillCodecState *s,
+                                             CodecParam *ioparam)
+ {
+     CodecDataStg *elem = NULL;
+     DeviceMemEntry *data_buf = NULL;
+     elem = g_malloc0(sizeof(CodecDataStg));
+     if (!elem) {
+         ERR("failed to allocate ioparam_queue. %d\n", sizeof(CodecDataStg));
+         return;
+     }
+     elem->param_buf = ioparam;
+     switch(ioparam->api_index) {
+     case CODEC_INIT ... CODEC_ENCODE_AUDIO:
+         data_buf = maru_brill_codec_store_inbuf((uint8_t *)s->vaddr, ioparam);
+         break;
+     default:
+         TRACE("no buffer from guest\n");
+         break;
+     }
+     elem->data_buf = data_buf;
+     qemu_mutex_lock(&s->ioparam_queue_mutex);
+     QTAILQ_INSERT_TAIL(&codec_rq, elem, node);
+     qemu_mutex_unlock(&s->ioparam_queue_mutex);
+ }
+ static void *maru_brill_codec_store_inbuf(uint8_t *mem_base,
+                                         CodecParam *ioparam)
+ {
+     DeviceMemEntry *elem = NULL;
+     int readbuf_size, size = 0;
+     uint8_t *readbuf = NULL;
+     uint8_t *device_mem = mem_base + ioparam->mem_offset;
+     elem = g_malloc0(sizeof(DeviceMemEntry));
+     if (!elem) {
+         ERR("failed to allocate readqueue node. size: %d\n",
+             sizeof(DeviceMemEntry));
+         return NULL;
+     }
+     memcpy(&readbuf_size, device_mem, sizeof(readbuf_size));
+     size = sizeof(readbuf_size);
+     TRACE("readbuf size: %d\n", readbuf_size);
+     if (readbuf_size <= 0) {
+         TRACE("inbuf size is 0. api_id %d, ctx_id %d, mem_offset %x\n",
+             ioparam->api_index, ioparam->ctx_index, ioparam->mem_offset);
+     } else {
+         readbuf = g_malloc0(readbuf_size);
+         if (!readbuf) {
+             ERR("failed to allocate a read buffer. size: %d\n", readbuf_size);
+         } else {
+             TRACE("copy input buffer from guest. ctx_id: %d, mem_offset: %x\n",
+                 ioparam->ctx_index, ioparam->mem_offset);
+             memcpy(readbuf, device_mem + size, readbuf_size);
+         }
+     }
+     // memset(device_mem, 0x00, sizeof(readbuf_size));
+     elem->opaque = readbuf;
+     elem->data_size = readbuf_size;
+     elem->ctx_id = ioparam->ctx_index;
+     return elem;
+ }
+ static void maru_brill_codec_push_writequeue(MaruBrillCodecState *s, void* opaque,
+                                             size_t data_size, int ctx_id,
+                                             DataHandler *handler)
+ {
+     DeviceMemEntry *elem = NULL;
+     elem = g_malloc0(sizeof(DeviceMemEntry));
+     elem->opaque = opaque;
+     elem->data_size = data_size;
+     elem->ctx_id = ctx_id;
+     if (handler) {
+         elem->handler = handler;
+     } else {
+         elem->handler = &default_data_handler;
+     }
+     qemu_mutex_lock(&s->context_queue_mutex);
+     QTAILQ_INSERT_TAIL(&codec_wq, elem, node);
+     qemu_mutex_unlock(&s->context_queue_mutex);
+ }
+ void maru_brill_codec_pop_writequeue(MaruBrillCodecState *s, uint32_t ctx_idx)
+ {
+     DeviceMemEntry *elem = NULL;
+     uint32_t mem_offset = 0;
+     TRACE("enter: %s\n", __func__);
+     if (ctx_idx < 1 || ctx_idx > (CODEC_CONTEXT_MAX - 1)) {
+         ERR("invalid buffer index. %d\n", ctx_idx);
+         return;
+     }
+     TRACE("pop_writeqeue. context index: %d\n", ctx_idx);
+     elem = entry[ctx_idx];
+     if (elem) {
+         mem_offset = s->ioparam.mem_offset;
+         // check corrupted mem_offset
+         if (mem_offset < CODEC_MEM_SIZE) {
+             elem->handler->get_data(s->vaddr + mem_offset, elem->opaque, elem->data_size, s->context[ctx_idx].avctx->pix_fmt);
+             elem->handler->release(elem->opaque);
+         } else {
+             TRACE("mem_offset is corrupted!!\n");
+         }
+         TRACE("pop_writequeue. release elem: %p\n", elem);
+         g_free(elem);
+         entry[ctx_idx] = NULL;
+     } else {
+         TRACE("there is no buffer to copy data to guest\n");
+     }
+     TRACE("leave: %s\n", __func__);
+ }
+ static void serialize_video_data(const struct video_data *video,
+                                 AVCodecContext *avctx)
+ {
+     if (video->width) {
+         avctx->width = video->width;
+     }
+     if (video->height) {
+         avctx->height = video->height;
+     }
+     if (video->fps_n) {
+         avctx->time_base.num = video->fps_n;
+     }
+     if (video->fps_d) {
+         avctx->time_base.den = video->fps_d;
+     }
+     if (video->pix_fmt > PIX_FMT_NONE) {
+         avctx->pix_fmt = video->pix_fmt;
+     }
+     if (video->par_n) {
+         avctx->sample_aspect_ratio.num = video->par_n;
+     }
+     if (video->par_d) {
+         avctx->sample_aspect_ratio.den = video->par_d;
+     }
+     if (video->bpp) {
+         avctx->bits_per_coded_sample = video->bpp;
+     }
+     if (video->ticks_per_frame) {
+         avctx->ticks_per_frame = video->ticks_per_frame;
+     }
+     INFO("codec_init. video, resolution: %dx%d, framerate: %d/%d "
+         "pixel_fmt: %d sample_aspect_ratio: %d/%d bpp %d\n",
+         avctx->width, avctx->height, avctx->time_base.num,
+         avctx->time_base.den, avctx->pix_fmt, avctx->sample_aspect_ratio.num,
+         avctx->sample_aspect_ratio.den, avctx->bits_per_coded_sample);
+ }
+ static void deserialize_video_data (const AVCodecContext *avctx,
+                                     struct video_data *video)
+ {
+     memset(video, 0x00, sizeof(struct video_data));
+     video->width = avctx->width;
+     video->height = avctx->height;
+     video->fps_n = avctx->time_base.num;
+     video->fps_d = avctx->time_base.den;
+     video->pix_fmt = avctx->pix_fmt;
+     video->par_n = avctx->sample_aspect_ratio.num;
+     video->par_d = avctx->sample_aspect_ratio.den;
+     video->bpp = avctx->bits_per_coded_sample;
+     video->ticks_per_frame = avctx->ticks_per_frame;
+ }
+ static void serialize_audio_data (const struct audio_data *audio,
+                                   AVCodecContext *avctx)
+ {
+     if (audio->channels) {
+         avctx->channels = audio->channels;
+     }
+     if (audio->sample_rate) {
+         avctx->sample_rate = audio->sample_rate;
+     }
+     if (audio->block_align) {
+         avctx->block_align = audio->block_align;
+     }
+     if (audio->sample_fmt > AV_SAMPLE_FMT_NONE) {
+         avctx->sample_fmt = audio->sample_fmt;
+     }
+     INFO("codec_init. audio, channel %d sample_rate %d sample_fmt %d ch_layout %lld\n",
+         avctx->channels, avctx->sample_rate, avctx->sample_fmt, avctx->channel_layout);
+ }
+ void maru_brill_codec_release_context(MaruBrillCodecState *s, int32_t ctx_id)
+ {
+     DeviceMemEntry *wq_elem = NULL, *wnext = NULL;
+     CodecDataStg *rq_elem = NULL, *rnext = NULL;
+     TRACE("enter: %s\n", __func__);
+     TRACE("release %d of context\n", ctx_id);
+     qemu_mutex_lock(&s->threadpool.mutex);
+     if (CONTEXT(s, ctx_id).opened_context) {
+         // qemu_mutex_unlock(&s->threadpool.mutex);
+         codec_deinit(s, ctx_id, NULL);
+         // qemu_mutex_lock(&s->threadpool.mutex);
+     }
+     CONTEXT(s, ctx_id).occupied_context = false;
+     qemu_mutex_unlock(&s->threadpool.mutex);
+     // TODO: check if foreach statment needs lock or not.
+     QTAILQ_FOREACH_SAFE(rq_elem, &codec_rq, node, rnext) {
+         if (rq_elem && rq_elem->data_buf &&
+             (rq_elem->data_buf->ctx_id == ctx_id)) {
+             TRACE("remove unused node from codec_rq. ctx_id: %d\n", ctx_id);
+             qemu_mutex_lock(&s->context_queue_mutex);
+             QTAILQ_REMOVE(&codec_rq, rq_elem, node);
+             qemu_mutex_unlock(&s->context_queue_mutex);
+             if (rq_elem && rq_elem->data_buf) {
+                 TRACE("release rq_buffer: %p\n", rq_elem->data_buf);
+                 g_free(rq_elem->data_buf);
+             }
+             TRACE("release rq_elem: %p\n", rq_elem);
+             g_free(rq_elem);
+         } else {
+             TRACE("no elem of %d context in the codec_rq.\n", ctx_id);
+         }
+     }
+     QTAILQ_FOREACH_SAFE(wq_elem, &codec_wq, node, wnext) {
+         if (wq_elem && wq_elem->ctx_id == ctx_id) {
+             TRACE("remove unused node from codec_wq. ctx_id: %d\n", ctx_id);
+             qemu_mutex_lock(&s->context_queue_mutex);
+             QTAILQ_REMOVE(&codec_wq, wq_elem, node);
+             qemu_mutex_unlock(&s->context_queue_mutex);
+             if (wq_elem && wq_elem->opaque) {
+                 TRACE("release wq_buffer: %p\n", wq_elem->opaque);
+                 g_free(wq_elem->opaque);
+                 wq_elem->opaque = NULL;
+             }
+             TRACE("release wq_elem: %p\n", wq_elem);
+             g_free(wq_elem);
+         } else {
+             TRACE("no elem of %d context in the codec_wq.\n", ctx_id);
+         }
+     }
+     TRACE("leave: %s\n", __func__);
+ }
+ int maru_brill_codec_query_list (MaruBrillCodecState *s)
+ {
+     AVCodec *codec = NULL;
+     uint32_t size = 0, mem_size = 0;
+     uint32_t data_len = 0, length = 0;
+     int32_t codec_type, media_type;
+     int32_t codec_fmts[4], i;
+     /* register avcodec */
+     TRACE("register avcodec\n");
+     av_register_all();
+     codec = av_codec_next(NULL);
+     if (!codec) {
+         ERR("failed to get codec info.\n");
+         return -1;
+     }
+     // a region to store the number of codecs.
+     length = 32 + 64 + 6 * sizeof(int32_t);
+     mem_size = size = sizeof(uint32_t);
+     while (codec) {
+         codec_type =
+             codec->decode ? CODEC_TYPE_DECODE : CODEC_TYPE_ENCODE;
+         media_type = codec->type;
+         memset(codec_fmts, -1, sizeof(codec_fmts));
+         if (media_type == AVMEDIA_TYPE_VIDEO) {
+             if (codec->pix_fmts) {
+                 for (i = 0; codec->pix_fmts[i] != -1 && i < 4; i++) {
+                     codec_fmts[i] = codec->pix_fmts[i];
+                 }
+             }
+         } else if (media_type == AVMEDIA_TYPE_AUDIO) {
+             if (codec->sample_fmts) {
+                 for (i = 0; codec->sample_fmts[i] != -1; i++) {
+                     codec_fmts[i] = codec->sample_fmts[i];
+                 }
+             }
+         } else {
+             ERR("unknown media type: %d\n", media_type);
+         }
+         memset(s->vaddr + mem_size, 0x00, length);
+         mem_size += length;
+         data_len += length;
+         memcpy(s->vaddr, &data_len, sizeof(data_len));
+         memcpy(s->vaddr + size, &codec_type, sizeof(codec_type));
+         size += sizeof(codec_type);
+         memcpy(s->vaddr + size, &media_type, sizeof(media_type));
+         size += sizeof(media_type);
+         memcpy(s->vaddr + size, codec->name, strlen(codec->name));
+         size += 32;
+         memcpy(s->vaddr + size,
+            codec->long_name, strlen(codec->long_name));
+         size += 64;
+         memcpy(s->vaddr + size, codec_fmts, sizeof(codec_fmts));
+         size += sizeof(codec_fmts);
+         TRACE("register %s %s\n", codec->name, codec->decode ? "decoder" : "encoder");
+         codec = av_codec_next(codec);
+     }
+     return 0;
+ }
+ int maru_brill_codec_get_context_index(MaruBrillCodecState *s)
+ {
+     int ctx_id;
+     TRACE("enter: %s\n", __func__);
+     // requires mutex_lock? its function is protected by critical section.
+     qemu_mutex_lock(&s->threadpool.mutex);
+     for (ctx_id = 1; ctx_id < CODEC_CONTEXT_MAX; ctx_id++) {
+         if (CONTEXT(s, ctx_id).occupied_context == false) {
+             TRACE("get %d of codec context successfully.\n", ctx_id);
+             CONTEXT(s, ctx_id).occupied_context = true;
+             break;
+         }
+     }
+     qemu_mutex_unlock(&s->threadpool.mutex);
+     if (ctx_id == CODEC_CONTEXT_MAX) {
+         ERR("failed to get available codec context. ");
+         ERR("try to run codec again.\n");
+         ctx_id = -1;
+     }
+     TRACE("leave: %s\n", __func__);
+     return ctx_id;
+ }
+ // allocate avcontext and avframe struct.
+ static AVCodecContext *maru_brill_codec_alloc_context(MaruBrillCodecState *s, int ctx_id)
+ {
+     TRACE("enter: %s\n", __func__);
+     TRACE("allocate %d of context and frame.\n", ctx_id);
+     CONTEXT(s, ctx_id).avctx = avcodec_alloc_context3(NULL);
+     CONTEXT(s, ctx_id).frame = avcodec_alloc_frame();
+     CONTEXT(s, ctx_id).opened_context = false;
+     TRACE("leave: %s\n", __func__);
+     return CONTEXT(s, ctx_id).avctx;
+ }
+ static AVCodec *maru_brill_codec_find_avcodec(uint8_t *mem_buf)
+ {
+     AVCodec *codec = NULL;
+     int32_t encode, size = 0;
+     char codec_name[32] = {0, };
+     memcpy(&encode, mem_buf, sizeof(encode));
+     size = sizeof(encode);
+     memcpy(codec_name, mem_buf + size, sizeof(codec_name));
+     size += sizeof(codec_name);
+     TRACE("type: %d, name: %s\n", encode, codec_name);
+     if (encode) {
+         codec = avcodec_find_encoder_by_name (codec_name);
+     } else {
+         codec = avcodec_find_decoder_by_name (codec_name);
+     }
+     INFO("%s!! find %s %s\n", codec ? "success" : "failure",
+         codec_name, encode ? "encoder" : "decoder");
+     return codec;
+ }
+ static void read_codec_init_data(AVCodecContext *avctx, uint8_t *mem_buf)
+ {
+     struct video_data video = { 0, };
+     struct audio_data audio = { 0, };
+     int bitrate = 0, size = 0;
+     memcpy(&video, mem_buf + size, sizeof(video));
+     size = sizeof(video);
+     serialize_video_data(&video, avctx);
+     memcpy(&audio, mem_buf + size, sizeof(audio));
+     size += sizeof(audio);
+     serialize_audio_data(&audio, avctx);
+     memcpy(&bitrate, mem_buf + size, sizeof(bitrate));
+     size += sizeof(bitrate);
+     if (bitrate) {
+         avctx->bit_rate = bitrate;
+     }
+     memcpy(&avctx->codec_tag, mem_buf + size, sizeof(avctx->codec_tag));
+     size += sizeof(avctx->codec_tag);
+     memcpy(&avctx->extradata_size,
+             mem_buf + size, sizeof(avctx->extradata_size));
+     size += sizeof(avctx->extradata_size);
+     INFO("extradata size: %d.\n", avctx->extradata_size);
+     if (avctx->extradata_size > 0) {
+         avctx->extradata =
+             av_mallocz(ROUND_UP_X(avctx->extradata_size +
+                         FF_INPUT_BUFFER_PADDING_SIZE, 4));
+         if (avctx->extradata) {
+             memcpy(avctx->extradata, mem_buf + size, avctx->extradata_size);
+         }
+     } else {
+         TRACE("no extra data.\n");
+         avctx->extradata =
+             av_mallocz(ROUND_UP_X(FF_INPUT_BUFFER_PADDING_SIZE, 4));
+     }
+ }
+ // write the result of codec_init
+ static int write_codec_init_data(AVCodecContext *avctx, uint8_t *mem_buf)
+ {
+     int size = 0;
+     if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) {
+         int osize = av_get_bytes_per_sample(avctx->sample_fmt);
+         INFO("avcodec_open. sample_fmt %d, bytes_per_sample %d\n", avctx->sample_fmt, osize);
+         if ((avctx->codec_id == AV_CODEC_ID_AAC) && avctx->codec->encode2) {
+             osize = av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
+         }
+         memcpy(mem_buf, &avctx->sample_fmt, sizeof(avctx->sample_fmt));
+         size = sizeof(avctx->sample_fmt);
+         // frame_size: samples per packet, initialized when calling 'init'
+         memcpy(mem_buf + size, &avctx->frame_size, sizeof(avctx->frame_size));
+         size += sizeof(avctx->frame_size);
+         memcpy(mem_buf + size, &osize, sizeof(osize));
+         size += sizeof(osize);
+     }
+     return size;
+ }
+ static int convert_audio_sample_fmt(const AVCodec *codec, int codec_type, bool encode)
+ {
+     int audio_sample_fmt = AV_SAMPLE_FMT_NONE;
+     if (!codec) {
+         return audio_sample_fmt;
+     }
+     if (codec_type != AVMEDIA_TYPE_AUDIO) {
+         ERR("this codec_type is invalid %d\n", codec_type);
+         return audio_sample_fmt;
+     }
+     if (!strcmp(codec->name, "aac")) {
+         // FLOAT format
+         if (encode) {
+             audio_sample_fmt = AV_SAMPLE_FMT_FLTP;
+         } else {
+             audio_sample_fmt = AV_SAMPLE_FMT_FLT;
+         }
+     } else if (!strcmp(codec->name, "mp3") || !strcmp(codec->name, "mp3adu")) {
+         // S16 format
+         if (encode) {
+             audio_sample_fmt = AV_SAMPLE_FMT_S16P;
+         } else {
+             audio_sample_fmt = AV_SAMPLE_FMT_S16;
+         }
+     } else if (!strcmp(codec->name, "wmav1") || !strcmp(codec->name, "wmav2")) {
+         if (encode) {
+             audio_sample_fmt = AV_SAMPLE_FMT_FLTP;
+         } else {
+             audio_sample_fmt = AV_SAMPLE_FMT_FLT;
+         }
+     } else {
+         INFO("cannot handle %s codec\n", codec->name);
+     }
+     TRACE("convert audio sample_fmt %d\n", audio_sample_fmt);
+     return audio_sample_fmt;
+ }
+ static int fill_audio_into_frame(AVCodecContext *avctx, AVFrame *frame,
+                                 uint8_t *samples, int samples_size,
+                                 int nb_samples, int audio_sample_fmt)
+ {
+     int result = 0;
+     if (!avctx) {
+         ERR("fill_audio. AVCodecContext is NULL!!\n");
+         return -1;
+     }
+     if (!frame) {
+         ERR("fill_audio. AVFrame is NULL!!\n");
+         return -1;
+     }
+     frame->nb_samples = nb_samples;
+     frame->format = audio_sample_fmt;
+     frame->channel_layout = avctx->channel_layout;
+     result =
+         avcodec_fill_audio_frame(frame, avctx->channels, audio_sample_fmt, (const uint8_t *)samples, samples_size, 0);
+     TRACE("fill audio in_frame. ret: %d in_frame->ch_layout %lld\n", result, frame->channel_layout);
+     return result;
+ }
+ static AVFrame *resample_audio(AVCodecContext *avctx, AVFrame *sample_frame,
+                             int sample_buffer_size, int in_sample_fmt,
+                             AVFrame *resample_frame, int *resample_buffer_size,
+                             int resample_sample_fmt)
+ {
+     AVAudioResampleContext *avr = NULL;
+     uint8_t *resample_buffer = NULL;
+     int buffer_size = 0;
+     int resample_nb_samples = sample_frame->nb_samples;
+     avr = avresample_alloc_context();
+     if (!avr) {
+         ERR("failed to allocate avresample context\n");
+         return NULL;
+     }
+     TRACE("channel_layout %lld sample_rate %d in_sample_fmt %d resample_sample_fmt %d\n",
+         avctx->channel_layout, avctx->sample_rate, avctx->sample_fmt, resample_sample_fmt);
+     av_opt_set_int(avr, "in_channel_layout", avctx->channel_layout, 0);
+     av_opt_set_int(avr, "in_sample_fmt", in_sample_fmt, 0);
+     av_opt_set_int(avr, "in_sample_rate", avctx->sample_rate, 0);
+     av_opt_set_int(avr, "out_channel_layout", avctx->channel_layout, 0);
+     av_opt_set_int(avr, "out_sample_fmt", resample_sample_fmt, 0);
+     av_opt_set_int(avr, "out_sample_rate", avctx->sample_rate, 0);
+     TRACE("open avresample context\n");
+     if (avresample_open(avr) < 0) {
+         ERR("failed to open avresample context\n");
+         avresample_free(&avr);
+         return NULL;
+     }
+     resample_frame = avcodec_alloc_frame();
+     TRACE("resample audio. nb_samples %d sample_fmt %d\n", resample_nb_samples, resample_sample_fmt);
+     *resample_buffer_size = av_samples_get_buffer_size(NULL, avctx->channels, resample_nb_samples, resample_sample_fmt, 0);
+     if (*resample_buffer_size < 0) {
+         ERR("failed to get size of resample buffer %d\n", *resample_buffer_size);
+         avresample_close(avr);
+         avresample_free(&avr);
+         return NULL;
+     }
+     resample_buffer = av_mallocz(*resample_buffer_size);
+     if (!resample_buffer) {
+         ERR("failed to allocate resample buffer\n");
+         avresample_close(avr);
+         avresample_free(&avr);
+         return NULL;
+     }
+     fill_audio_into_frame(avctx, resample_frame, resample_buffer,
+                         *resample_buffer_size, resample_nb_samples, resample_sample_fmt);
+     buffer_size = avresample_convert(avr, resample_frame->data,
+                                     *resample_buffer_size, resample_nb_samples,
+                                     sample_frame->data, sample_buffer_size,
+                                     sample_frame->nb_samples);
+     TRACE("resample_audio buffer_size %d\n", buffer_size);
+     avresample_close(avr);
+     avresample_free(&avr);
+     return resample_frame;
+ }
+ static int parse_and_decode_video(AVCodecContext *avctx, AVFrame *picture,
+                                 AVCodecParserContext *pctx, int ctx_id,
+                                 AVPacket *packet, int *got_picture,
+                                 int idx, int64_t in_offset)
+ {
+     uint8_t *parser_outbuf = NULL;
+     int parser_outbuf_size = 0;
+     uint8_t *parser_buf = packet->data;
+     int parser_buf_size = packet->size;
+     int ret = 0, len = -1;
+     int64_t pts = 0, dts = 0, pos = 0;
+     pts = dts = idx;
+     pos = in_offset;
+     do {
+         if (pctx) {
+             ret = av_parser_parse2(pctx, avctx, &parser_outbuf,
+                     &parser_outbuf_size, parser_buf, parser_buf_size,
+                     pts, dts, pos);
+             if (ret) {
+                 parser_buf_size -= ret;
+                 parser_buf += ret;
+             }
+             TRACE("after parsing ret: %d parser_outbuf_size %d parser_buf_size %d pts %lld\n",
+                     ret, parser_outbuf_size, parser_buf_size, pctx->pts);
+             /* if there is no output, we must break and wait for more data.
+              * also the timestamp in the context is not updated.
+              */
+             if (parser_outbuf_size == 0) {
+                 if (parser_buf_size > 0) {
+                     TRACE("parsing data have been left\n");
+                     continue;
+                 } else {
+                     TRACE("finish parsing data\n");
+                     break;
+                 }
+             }
+             packet->data = parser_outbuf;
+             packet->size = parser_outbuf_size;
+         } else {
+             TRACE("not using parser %s\n", avctx->codec->name);
+         }
+         len = avcodec_decode_video2(avctx, picture, got_picture, packet);
+         TRACE("decode_video. len %d, got_picture %d\n", len, *got_picture);
+         if (!pctx) {
+             if (len == 0 && (*got_picture) == 0) {
+                 ERR("decoding video didn't return any data! ctx_id %d len %d\n", ctx_id, len);
+                 break;
+             } else if (len < 0) {
+                 ERR("decoding video error! ctx_id %d len %d\n", ctx_id, len);
+                 break;
+             }
+             parser_buf_size -= len;
+             parser_buf += len;
+         } else {
+             if (len == 0) {
+                 ERR("decoding video didn't return any data! ctx_id %d len %d\n", ctx_id, len);
+                 *got_picture = 0;
+                 break;
+             } else if (len < 0) {
+                 ERR("decoding video error! trying next ctx_id %d len %d\n", ctx_id, len);
+                 break;
+             }
+         }
+     } while (parser_buf_size > 0);
+     return len;
+ }
+ // codec functions
+ static bool codec_init(MaruBrillCodecState *s, int ctx_id, void *data_buf)
+ {
+     AVCodecContext *avctx = NULL;
+     AVCodec *codec = NULL;
+     int size = 0, ret = -1;
+     DeviceMemEntry *elem = NULL;
+     uint8_t *tempbuf = NULL;
+     int tempbuf_size = 0;
+     TRACE("enter: %s\n", __func__);
+     elem = (DeviceMemEntry *)data_buf;
+     // allocate AVCodecContext
+     avctx = maru_brill_codec_alloc_context(s, ctx_id);
+     if (!avctx) {
+         ERR("[%d] failed to allocate context.\n", __LINE__);
+         ret = -1;
+     } else {
+         codec = maru_brill_codec_find_avcodec(elem->opaque);
+         if (codec) {
+             size = sizeof(int32_t) + 32; // buffer size of codec_name
+             read_codec_init_data(avctx, elem->opaque + size);
+             // in case of aac encoder, sample format is float
+             if (!strcmp(codec->name, "aac") && codec->encode2) {
+                 TRACE("convert sample format into SAMPLE_FMT_FLTP\n");
+                 avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
+                 avctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
+                 INFO("aac encoder!! channels %d channel_layout %lld\n",
+                     avctx->channels, avctx->channel_layout);
+                 avctx->channel_layout = av_get_default_channel_layout(avctx->channels);
+             }
+             TRACE("audio sample format %d\n", avctx->sample_fmt);
+             TRACE("strict_std_compliance %d\n", avctx->strict_std_compliance);
++            // in case of aac encoder, sample format is float
++            if (!strcmp(codec->name, "aac") && codec->encode2) {
++                TRACE("convert sample format into SAMPLE_FMT_FLTP\n");
++                avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
++
++                avctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
++
++                INFO("aac encoder!! channels %d channel_layout %lld\n", avctx->channels, avctx->channel_layout);
++                avctx->channel_layout = av_get_default_channel_layout(avctx->channels);
++            }
++
++            TRACE("audio sample format %d\n", avctx->sample_fmt);
++            TRACE("strict_std_compliance %d\n", avctx->strict_std_compliance);
++
+             ret = avcodec_open2(avctx, codec, NULL);
+             INFO("avcodec_open. ret 0x%x ctx_id %d\n", ret, ctx_id);
+             INFO("channels %d sample_rate %d sample_fmt %d "
+                 "channel_layout %lld frame_size %d\n",
+                 avctx->channels, avctx->sample_rate, avctx->sample_fmt,
+                 avctx->channel_layout, avctx->frame_size);
+             tempbuf_size = (sizeof(avctx->sample_fmt) + sizeof(avctx->frame_size)
+                            + sizeof(avctx->extradata_size) + avctx->extradata_size)
+                            + sizeof(int);
+             CONTEXT(s, ctx_id).opened_context = true;
+             CONTEXT(s, ctx_id).parser_ctx =
+                 maru_brill_codec_parser_init(avctx);
+         } else {
+             ERR("failed to find codec. ctx_id: %d\n", ctx_id);
+             ret = -1;
+         }
+     }
+     tempbuf_size += sizeof(ret);
+     tempbuf = g_malloc(tempbuf_size);
+     if (!tempbuf) {
+         ERR("failed to allocate a buffer\n");
+         tempbuf_size = 0;
+     } else {
+         memcpy(tempbuf, &ret, sizeof(ret));
+         size = sizeof(ret);
+         if (ret < 0) {
+             ERR("failed to open codec contex.\n");
+         } else {
+             size += write_codec_init_data(avctx, tempbuf + size);
+             TRACE("codec_init. copyback!! size %d\n", size);
+             {
+                 memcpy(tempbuf + size, &avctx->extradata_size, sizeof(avctx->extradata_size));
+                 size += sizeof(avctx->extradata_size);
+                 INFO("codec_init. extradata_size: %d\n", avctx->extradata_size);
+                 if (avctx->extradata) {
+                     memcpy(tempbuf + size, avctx->extradata, avctx->extradata_size);
+                     size += avctx->extradata_size;
+                 }
+             }
+         }
+     }
+     maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id, NULL);
+     TRACE("leave: %s\n", __func__);
+     return true;
+ }
+ static bool codec_deinit(MaruBrillCodecState *s, int ctx_id, void *data_buf)
+ {
+     AVCodecContext *avctx = NULL;
+     AVFrame *frame = NULL;
+     AVCodecParserContext *parserctx = NULL;
+     TRACE("enter: %s\n", __func__);
+     avctx = CONTEXT(s, ctx_id).avctx;
+     frame = CONTEXT(s, ctx_id).frame;
+     parserctx = CONTEXT(s, ctx_id).parser_ctx;
+     if (!avctx || !frame) {
+         TRACE("%d of AVCodecContext or AVFrame is NULL. "
+             " Those resources have been released before.\n", ctx_id);
+         return false;
+     }
+     INFO("close avcontext of %d\n", ctx_id);
+     // qemu_mutex_lock(&s->threadpool.mutex);
+     avcodec_close(avctx);
+     CONTEXT(s, ctx_id).opened_context = false;
+     // qemu_mutex_unlock(&s->threadpool.mutex);
+     if (avctx->extradata) {
+         TRACE("free context extradata\n");
+         av_free(avctx->extradata);
+         CONTEXT(s, ctx_id).avctx->extradata = NULL;
+     }
+     if (frame) {
+         TRACE("free frame\n");
+         avcodec_free_frame(&frame);
+         CONTEXT(s, ctx_id).frame = NULL;
+     }
+     if (avctx) {
+         TRACE("free codec context\n");
+         av_free(avctx);
+         CONTEXT(s, ctx_id).avctx = NULL;
+     }
+     if (parserctx) {
+         INFO("close parser context\n");
+         av_parser_close(parserctx);
+         CONTEXT(s, ctx_id).parser_ctx = NULL;
+     }
+     maru_brill_codec_push_writequeue(s, NULL, 0, ctx_id, NULL);
+     TRACE("leave: %s\n", __func__);
+     return true;
+ }
+ static bool codec_flush_buffers(MaruBrillCodecState *s, int ctx_id, void *data_buf)
+ {
+     AVCodecContext *avctx = NULL;
+     bool ret = true;
+     TRACE("enter: %s\n", __func__);
+     avctx = CONTEXT(s, ctx_id).avctx;
+     if (!avctx) {
+         ERR("%d of AVCodecContext is NULL.\n", ctx_id);
+         ret = false;
+     } else if (!avctx->codec) {
+         ERR("%d of AVCodec is NULL.\n", ctx_id);
+         ret = false;
+     } else {
+         TRACE("flush %d context of buffers.\n", ctx_id);
+         AVCodecParserContext *pctx = NULL;
+         uint8_t *poutbuf = NULL;
+         int poutbuf_size = 0;
+         int res = 0;
+         uint8_t p_inbuf[FF_INPUT_BUFFER_PADDING_SIZE];
+         int p_inbuf_size = FF_INPUT_BUFFER_PADDING_SIZE;
+         memset(&p_inbuf, 0x00, p_inbuf_size);
+         pctx = CONTEXT(s, ctx_id).parser_ctx;
+         if (pctx) {
+             res = av_parser_parse2(pctx, avctx, &poutbuf, &poutbuf_size,
+                     p_inbuf, p_inbuf_size, -1, -1, -1);
+             INFO("before flush buffers, using parser. res: %d\n", res);
+         }
+         avcodec_flush_buffers(avctx);
+     }
+     maru_brill_codec_push_writequeue(s, NULL, 0, ctx_id, NULL);
+     TRACE("leave: %s\n", __func__);
+     return ret;
+ }
+ static bool codec_decode_video(MaruBrillCodecState *s, int ctx_id, void *data_buf)
+ {
+     AVCodecContext *avctx = NULL;
+     AVFrame *picture = NULL;
+     AVCodecParserContext *pctx = NULL;
+     AVPacket avpkt;
+     int got_picture = 0, len = -1;
+     int idx = 0, size = 0;
+     int64_t in_offset = 0;
+     uint8_t *inbuf = NULL;
+     int inbuf_size = 0;
+     DeviceMemEntry *elem = NULL;
+     uint8_t *tempbuf = NULL;
+     int tempbuf_size = 0;
+     TRACE("enter: %s\n", __func__);
+     elem = (DeviceMemEntry *)data_buf;
+     if (elem && elem->opaque) {
+         memcpy(&inbuf_size, elem->opaque, sizeof(inbuf_size));
+         size += sizeof(inbuf_size);
+         memcpy(&idx, elem->opaque + size, sizeof(idx));
+         size += sizeof(idx);
+         memcpy(&in_offset, elem->opaque + size, sizeof(in_offset));
+         size += sizeof(in_offset);
+         TRACE("decode_video. inbuf_size %d\n", inbuf_size);
+         if (inbuf_size > 0) {
+             inbuf = elem->opaque + size;
+         }
+     } else {
+         TRACE("decode_video. no input buffer\n");
+         // FIXME: improve error handling
+         // return false;
+     }
+     av_init_packet(&avpkt);
+     avpkt.data = inbuf;
+     avpkt.size = inbuf_size;
+     avctx = CONTEXT(s, ctx_id).avctx;
+     picture = CONTEXT(s, ctx_id).frame;
+     if (!avctx) {
+         ERR("decode_video. %d of AVCodecContext is NULL.\n", ctx_id);
+     } else if (!avctx->codec) {
+         ERR("decode_video. %d of AVCodec is NULL.\n", ctx_id);
+     } else if (!picture) {
+         ERR("decode_video. %d of AVFrame is NULL.\n", ctx_id);
+     } else {
+         pctx = CONTEXT(s, ctx_id).parser_ctx;
+         len = parse_and_decode_video(avctx, picture, pctx, ctx_id,
+                                     &avpkt, &got_picture, idx, in_offset);
+     }
+     tempbuf_size = sizeof(len) + sizeof(got_picture) + sizeof(struct video_data);
+     tempbuf = g_malloc(tempbuf_size);
+     if (!tempbuf) {
+         ERR("failed to allocate decoded audio buffer\n");
+         tempbuf_size = 0;
+     } else {
+         struct video_data video;
+         memcpy(tempbuf, &len, sizeof(len));
+         size = sizeof(len);
+         memcpy(tempbuf + size, &got_picture, sizeof(got_picture));
+         size += sizeof(got_picture);
+         if (avctx) {
+             deserialize_video_data(avctx, &video);
+             memcpy(tempbuf + size, &video, sizeof(struct video_data));
+         }
+     }
+     maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id, NULL);
+     TRACE("leave: %s\n", __func__);
+     return true;
+ }
+ static bool codec_picture_copy (MaruBrillCodecState *s, int ctx_id, void *elem)
+ {
+     AVCodecContext *avctx = NULL;
+     AVPicture *src = NULL;
+     int pict_size = 0;
+     bool ret = true;
+     TRACE("enter: %s\n", __func__);
+     TRACE("copy decoded image of %d context.\n", ctx_id);
+     avctx = CONTEXT(s, ctx_id).avctx;
+     src = (AVPicture *)CONTEXT(s, ctx_id).frame;
+     if (!avctx) {
+         ERR("picture_copy. %d of AVCodecContext is NULL.\n", ctx_id);
+         ret = false;
+     } else if (!avctx->codec) {
+         ERR("picture_copy. %d of AVCodec is NULL.\n", ctx_id);
+         ret = false;
+     } else if (!src) {
+         ERR("picture_copy. %d of AVFrame is NULL.\n", ctx_id);
+         ret = false;
+     } else {
+         TRACE("decoded image. pix_fmt: %d width: %d, height: %d\n",
+                 avctx->pix_fmt, avctx->width, avctx->height);
+         pict_size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
+         if ((pict_size) < 0) {
+             ERR("picture size: %d\n", pict_size);
+             ret = false;
+         } else {
+             TRACE("picture size: %d\n", pict_size);
+             maru_brill_codec_push_writequeue(s, src, pict_size, ctx_id, &default_video_decode_data_handler);
+         }
+     }
+     TRACE("leave: %s\n", __func__);
+     return ret;
+ }
+ /*
+  * decode_audio >> raw audio_buffer >> resample
+  *
+  * audios sink cannot handle planar format, so it is required
+  * to resample audio buffer into linear format.
+  */
+ static bool codec_decode_audio(MaruBrillCodecState *s, int ctx_id, void *data_buf)
+ {
+     AVCodecContext *avctx;
+     AVPacket avpkt;
+     AVFrame *audio_out = NULL;
+     uint8_t *inbuf = NULL;
+     int inbuf_size = 0, size = 0;
+     int len = -1, got_frame = 0;
+     DeviceMemEntry *elem = NULL;
+     uint8_t *tempbuf = NULL;
+     int tempbuf_size = 0;
+     AVFrame *resample_frame = NULL;
+     uint8_t *resample_buf = NULL;
+     int resample_buf_size = 0;
+     int out_sample_fmt = -1;
+     TRACE("enter: %s\n", __func__);
+     elem = (DeviceMemEntry *)data_buf;
+     if (elem && elem->opaque) {
+         memcpy(&inbuf_size, elem->opaque, sizeof(inbuf_size));
+         size = sizeof(inbuf_size);
+         TRACE("decode_audio. inbuf_size %d\n", inbuf_size);
+         if (inbuf_size > 0) {
+             inbuf = elem->opaque + size;
+         }
+     } else {
+         ERR("decode_audio. no input buffer\n");
+         // FIXME: improve error handling
+         // return false;
+     }
+     av_init_packet(&avpkt);
+     avpkt.data = inbuf;
+     avpkt.size = inbuf_size;
+     avctx = CONTEXT(s, ctx_id).avctx;
+     audio_out = CONTEXT(s, ctx_id).frame;
+     if (!avctx) {
+         ERR("decode_audio. %d of AVCodecContext is NULL\n", ctx_id);
+     } else if (!avctx->codec) {
+         ERR("decode_audio. %d of AVCodec is NULL\n", ctx_id);
+     } else if (!audio_out) {
+         ERR("decode_audio. %d of AVFrame is NULL\n", ctx_id);
+     } else {
+         len = avcodec_decode_audio4(avctx, audio_out, &got_frame, &avpkt);
+         TRACE("decode_audio. len %d, channel_layout %lld got_frame %d\n",
+             len, avctx->channel_layout, got_frame);
+         if (got_frame) {
+             if (av_sample_fmt_is_planar(avctx->sample_fmt)) {
+                 out_sample_fmt = convert_audio_sample_fmt(avctx->codec, avctx->codec_type, 0);
+                 if (avctx->channel_layout == 0) {
+                     avctx->channel_layout = av_get_default_channel_layout(avctx->channels);
+                     TRACE("decode_audio. channel_layout %lld channels %d\n",
+                         avctx->channel_layout, avctx->channels);
+                 }
+                 resample_frame = resample_audio(avctx, audio_out, audio_out->linesize[0],
+                                             avctx->sample_fmt, NULL, &resample_buf_size,
+                                             out_sample_fmt);
+                 if (resample_frame) {
+                     resample_buf = resample_frame->data[0];
+                 } else {
+                     ERR("failed to resample decoded audio buffer\n");
+                     len = -1;
+                     got_frame = 0;
+                 }
+             } else {
+                 INFO("decode_audio. linear audio format\n");
+                 resample_buf = audio_out->data[0];
+                 resample_buf_size = audio_out->linesize[0];
+             }
+         }
+     }
+     tempbuf_size = (sizeof(len) + sizeof(got_frame));
+     if (len < 0) {
+         ERR("failed to decode audio. ctx_id: %d len: %d got_frame: %d\n",
+             ctx_id, len, got_frame);
+         got_frame = 0;
+     } else {
+         tempbuf_size += (sizeof(out_sample_fmt) + sizeof(avctx->sample_rate)
+                         + sizeof(avctx->channels) + sizeof(avctx->channel_layout)
+                         + sizeof(resample_buf_size) + resample_buf_size);
+     }
+     tempbuf = g_malloc(tempbuf_size);
+     if (!tempbuf) {
+         ERR("failed to allocate decoded audio buffer\n");
+     } else {
+         memcpy(tempbuf, &len, sizeof(len));
+         size = sizeof(len);
+         memcpy(tempbuf + size, &got_frame, sizeof(got_frame));
+         size += sizeof(got_frame);
+         if (got_frame) {
+             memcpy(tempbuf + size, &out_sample_fmt, sizeof(out_sample_fmt));
+             size += sizeof(out_sample_fmt);
+             memcpy(tempbuf + size, &avctx->sample_rate, sizeof(avctx->sample_rate));
+             size += sizeof(avctx->sample_rate);
+             memcpy(tempbuf + size, &avctx->channels, sizeof(avctx->channels));
+             size += sizeof(avctx->channels);
+             memcpy(tempbuf + size, &avctx->channel_layout, sizeof(avctx->channel_layout));
+             size += sizeof(avctx->channel_layout);
+             memcpy(tempbuf + size, &resample_buf_size, sizeof(resample_buf_size));
+             size += sizeof(resample_buf_size);
+             if (resample_buf) {
+                 TRACE("copy resampled audio buffer\n");
+                 memcpy(tempbuf + size, resample_buf, resample_buf_size);
+             }
+         }
+     }
+     maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id, NULL);
+     if (resample_frame) {
+         TRACE("release decoded frame\n");
+         av_free(resample_buf);
+         av_free(resample_frame);
+     }
++    if (audio_out) {
++        avcodec_free_frame(&audio_out);
++    }
++
+     TRACE("leave: %s\n", __func__);
+     return true;
+ }
+ static bool codec_encode_video(MaruBrillCodecState *s, int ctx_id, void *data_buf)
+ {
+     AVCodecContext *avctx = NULL;
+     AVFrame *pict = NULL;
+     AVPacket avpkt;
+     uint8_t *inbuf = NULL, *outbuf = NULL;
+     int inbuf_size = 0, outbuf_size = 0;
+     int got_frame = 0, ret = 0, size = 0;
+     int64_t in_timestamp = 0;
+     int coded_frame = 0, key_frame = 0;
+     DeviceMemEntry *elem = NULL;
+     uint8_t *tempbuf = NULL;
+     int tempbuf_size = 0;
+     TRACE("enter: %s\n", __func__);
+     elem = (DeviceMemEntry *)data_buf;
+     if (elem && elem->opaque) {
+         memcpy(&inbuf_size, elem->opaque, sizeof(inbuf_size));
+         size += sizeof(inbuf_size);
+         memcpy(&in_timestamp, elem->opaque + size, sizeof(in_timestamp));
+         size += sizeof(in_timestamp);
+         TRACE("encode video. inbuf_size %d\n", inbuf_size);
+         if (inbuf_size > 0) {
+             inbuf = elem->opaque + size;
+         }
+     } else {
+         TRACE("encode video. no input buffer.\n");
+         // FIXME: improve error handling
+         // return false;
+     }
+     // initialize AVPacket
+     av_init_packet(&avpkt);
+     avpkt.data = NULL;
+     avpkt.size = 0;
+     avctx = CONTEXT(s, ctx_id).avctx;
+     pict = CONTEXT(s, ctx_id).frame;
+     if (!avctx || !pict) {
+         ERR("%d of context or frame is NULL\n", ctx_id);
+     } else if (!avctx->codec) {
+         ERR("%d of AVCodec is NULL.\n", ctx_id);
+     } else {
+         TRACE("pixel format: %d inbuf: %p, picture data: %p\n",
+             avctx->pix_fmt, inbuf, pict->data[0]);
+         ret = avpicture_fill((AVPicture *)pict, inbuf, avctx->pix_fmt,
+                             avctx->width, avctx->height);
+         if (ret < 0) {
+             ERR("after avpicture_fill, ret:%d\n", ret);
+         } else {
+             if (avctx->time_base.num == 0) {
+                 pict->pts = AV_NOPTS_VALUE;
+             } else {
+                 AVRational bq =
+                             {1, (G_USEC_PER_SEC * G_GINT64_CONSTANT(1000))};
+                 pict->pts = av_rescale_q(in_timestamp, bq, avctx->time_base);
+             }
+             TRACE("encode video. ticks_per_frame:%d, pts:%lld\n",
+                 avctx->ticks_per_frame, pict->pts);
+             outbuf_size =
+                 (avctx->width * avctx->height * 6) + FF_MIN_BUFFER_SIZE;
+             outbuf = g_malloc0(outbuf_size);
+             avpkt.data = outbuf;
+             avpkt.size = outbuf_size;
+             if (!outbuf) {
+                 ERR("failed to allocate a buffer of encoding video.\n");
+             } else {
+                 ret = avcodec_encode_video2(avctx, &avpkt, pict, &got_frame);
+                 TRACE("encode video. ret %d got_picture %d outbuf_size %d\n", ret, got_frame, avpkt.size);
+                 if (avctx->coded_frame) {
+                     TRACE("encode video. keyframe %d\n", avctx->coded_frame->key_frame);
+                 }
+             }
+         }
+     }
+     tempbuf_size = sizeof(ret);
+     if (ret < 0) {
+         ERR("failed to encode video. ctx_id %d ret %d\n", ctx_id, ret);
+     } else {
+         tempbuf_size += avpkt.size + sizeof(coded_frame) + sizeof(key_frame);
+     }
+     // write encoded video data
+     tempbuf = g_malloc0(tempbuf_size);
+     if (!tempbuf) {
+         ERR("encode video. failed to allocate encoded out buffer.\n");
+     } else {
+         memcpy(tempbuf, &avpkt.size, sizeof(avpkt.size));
+         size = sizeof(avpkt.size);
+         if ((got_frame) && outbuf) {
+             // inform gstreamer plugin about the status of encoded frames
+             // A flag for output buffer in gstreamer is depending on the status.
+             if (avctx->coded_frame) {
+                 coded_frame = 1;
+                 // if key_frame is 0, this frame cannot be decoded independently.
+                 key_frame = avctx->coded_frame->key_frame;
+             }
+             memcpy(tempbuf + size, &coded_frame, sizeof(coded_frame));
+             size += sizeof(coded_frame);
+             memcpy(tempbuf + size, &key_frame, sizeof(key_frame));
+             size += sizeof(key_frame);
+             memcpy(tempbuf + size, outbuf, avpkt.size);
+         }
+     }
+     if (outbuf) {
+         TRACE("release encoded output buffer. %p\n", outbuf);
+         g_free(outbuf);
+     }
+     maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id, NULL);
+     TRACE("leave: %s\n", __func__);
+     return true;
+ }
+ static bool codec_encode_audio(MaruBrillCodecState *s, int ctx_id, void *data_buf)
+ {
+     AVCodecContext *avctx = NULL;
+     AVPacket avpkt;
+     uint8_t *audio_in = NULL;
+     int32_t audio_in_size = 0;
+     int ret = -1, got_pkt = 0, size = 0;
+     DeviceMemEntry *elem = NULL;
+     uint8_t *tempbuf = NULL;
+     int tempbuf_size = 0;
+     AVFrame *in_frame = NULL;
+     AVFrame *resample_frame = NULL;
+     int64_t in_timestamp = 0;
+     TRACE("enter: %s\n", __func__);
+     /*
+      *  copy raw audio data from gstreamer encoder plugin
+      *  audio_in_size: size of raw audio data
+      *  audio_in : raw audio data
+      */
+     elem = (DeviceMemEntry *)data_buf;
+     if (elem && elem->opaque) {
+         memcpy(&audio_in_size, elem->opaque, sizeof(audio_in_size));
+         size += sizeof(audio_in_size);
+         memcpy(&in_timestamp, elem->opaque + size, sizeof(in_timestamp));
+         size += sizeof(in_timestamp);
+         TRACE("encode_audio. audio_in_size %d\n", audio_in_size);
+         if (audio_in_size > 0) {
+             // audio_in = g_malloc0(audio_in_size);
+             // memcpy(audio_in, elem->buf + size, audio_in_size);
+             audio_in = elem->opaque + size;
+         }
+     } else {
+         TRACE("encode_audio. no input buffer\n");
+     }
+     avctx = CONTEXT(s, ctx_id).avctx;
+     if (!avctx) {
+         ERR("encode_audio. %d of Context is NULL\n", ctx_id);
+     } else if (!avctx->codec) {
+         ERR("encode_audio. %d of AVCodec is NULL\n", ctx_id);
+     } else {
+         int bytes_per_sample = 0;
+         int nb_samples = 0;
+         int audio_in_sample_fmt = AV_SAMPLE_FMT_S16;
+         // audio input src can generate a buffer as an int format.
+         int resample_buf_size = 0;
+         int resample_sample_fmt = 0;
+         bytes_per_sample = av_get_bytes_per_sample(audio_in_sample_fmt);
+         TRACE("bytes per sample %d, sample format %d\n", bytes_per_sample, audio_in_sample_fmt);
+         nb_samples = audio_in_size / (bytes_per_sample * avctx->channels);
+         TRACE("nb_samples %d\n", nb_samples);
+         in_frame = avcodec_alloc_frame();
+         if (!in_frame) {
+             ERR("encode_audio. failed to allocate in_frame\n");
+         } else {
+             // prepare audio_in frame
+             ret = fill_audio_into_frame(avctx, in_frame, audio_in, audio_in_size, nb_samples, audio_in_sample_fmt);
+             if (ret < 0) {
+                 ERR("failed to fill audio into frame\n");
+             } else {
+                 resample_sample_fmt =
+                     convert_audio_sample_fmt(avctx->codec, avctx->codec_type, 1);
+                 resample_frame = resample_audio(avctx, in_frame, audio_in_size,
+                         audio_in_sample_fmt, NULL, &resample_buf_size,
+                         resample_sample_fmt);
+                 if (resample_frame) {
+                     av_init_packet(&avpkt);
+                     avpkt.data = NULL;
+                     avpkt.size = 0;
+                     ret = avcodec_encode_audio2(avctx, &avpkt, (const AVFrame *)resample_frame, &got_pkt);
+                     TRACE("encode audio. ret %d got_pkt %d avpkt.size %d frame_number %d\n",
+                         ret, got_pkt, avpkt.size, avctx->frame_number);
+                 }
+             }
+         }
+     }
+     tempbuf_size = sizeof(ret);
+     if (ret < 0) {
+         ERR("failed to encode audio. ctx_id %d ret %d\n", ctx_id, ret);
+     } else {
+         tempbuf_size += (sizeof(avpkt.size) + avpkt.size);
+     }
+     TRACE("encode_audio. writequeue elem buffer size %d\n", tempbuf_size);
+     // write encoded audio data
+     tempbuf = g_malloc0(tempbuf_size);
+     if (!tempbuf) {
+         ERR("encode audio. failed to allocate encoded out buffer.\n");
+     } else {
+         memcpy(tempbuf, &ret, sizeof(ret));
+         size = sizeof(ret);
+         if (ret == 0) {
+             memcpy(tempbuf + size, &avpkt.size, sizeof(avpkt.size));
+             size += sizeof(avpkt.size);
+             if (got_pkt) {
+                 memcpy(tempbuf + size, avpkt.data, avpkt.size);
+                 av_free_packet(&avpkt);
+             }
+         }
+     }
+     maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id, NULL);
+     if (in_frame) {
+         av_free(in_frame);
+     }
+     if (resample_frame) {
+         av_free(resample_frame->data[0]);
+         av_free(resample_frame);
+     }
+     TRACE("[%s] leave:\n", __func__);
+     return true;
+ }
+ static AVCodecParserContext *maru_brill_codec_parser_init(AVCodecContext *avctx)
+ {
+     AVCodecParserContext *parser = NULL;
+     if (!avctx) {
+         ERR("context is NULL\n");
+         return NULL;
+     }
+     switch (avctx->codec_id) {
+     case CODEC_ID_MPEG4:
+     case CODEC_ID_VC1:
+         TRACE("not using parser\n");
+         break;
+     case CODEC_ID_H264:
+         if (avctx->extradata_size == 0) {
+             TRACE("H.264 with no extradata, creating parser.\n");
+             parser = av_parser_init (avctx->codec_id);
+         }
+         break;
+     default:
+         parser = av_parser_init(avctx->codec_id);
+         if (parser) {
+             INFO("using parser: %s\n", avctx->codec->name);
+         }
+         break;
+     }
+     return parser;
+ }
Simple merge
index 0000000000000000000000000000000000000000,70d74981b168dac508379d47eaee570c14334a25..f55fd590e2dd6e4cd70f05c80cb566e7faf3be82
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,213 +1,286 @@@
+ /*
+  * Maru device hotplug
+  *
+  * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+  *
+  * Contact:
+  * SeokYeon Hwang <syeon.hwang@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 "qemu/main-loop.h"
+ #include "qemu/config-file.h"
+ #include "hw/qdev.h"
+ #include "monitor/qdev.h"
++#include "fsdev/qemu-fsdev.h"
+ #include "qmp-commands.h"
+ #include "sysemu/blockdev.h"
+ #include "qemu/event_notifier.h"
+ #include "emulator.h"
+ #include "maru_device_hotplug.h"
+ #define HOST_KEYBOARD_DRIVER        "virtio-keyboard-pci"
+ #define HOST_KEYBOARD_DEFAULT_ID    "HOSTKBD0"
+ #define SDCARD_DRIVE_DEFAULT_ID     "SDCARD_DRIVE0"
+ #define SDCARD_DRIVER               "virtio-blk-pci"
+ #define SDCARD_DEFAULT_ID           "SDCARD0"
++#define FS_MOUNT_TAG                "fileshare"
++
+ struct maru_device_hotplug {
+     EventNotifier notifier;
+     char *opaque;
+     int command;
+     // FIXME: Should we query device every time ??
+     bool host_keyboard_attached;
+     bool sdcard_attached;
++    bool hds_attached;
+ };
+ static struct maru_device_hotplug *state;
+ static bool do_host_keyboard_attach(void)
+ {
+     QDict *qdict = qdict_new();
+     qdict_put(qdict, "driver", qstring_from_str(HOST_KEYBOARD_DRIVER));
+     qdict_put(qdict, "id", qstring_from_str(HOST_KEYBOARD_DEFAULT_ID));
+     if (do_device_add(default_mon, qdict, NULL)) {
+         QDECREF(qdict);
+         // TODO error reporting
+         return false;
+     }
+     QDECREF(qdict);
+     state->host_keyboard_attached = true;
+     return true;
+ }
+ static bool do_host_keyboard_detach(void)
+ {
+     QDict *qdict = qdict_new();
+     qdict_put(qdict, "id", qstring_from_str(HOST_KEYBOARD_DEFAULT_ID));
+     if (qmp_marshal_input_device_del(default_mon, qdict, NULL)) {
+         QDECREF(qdict);
+         // TODO error reporting
+         return false;
+     }
+     QDECREF(qdict);
+     state->host_keyboard_attached = false;
+     return true;
+ }
+ static bool do_sdcard_attach(const char * const file)
+ {
+     QDict *qdict = qdict_new();
+     QDict *qdict_file = qdict_new();
+     QDict *qdict_options = qdict_new();
+     qdict_put(qdict_file, "driver", qstring_from_str("file"));
+     qdict_put(qdict_file, "filename", qstring_from_str(file));
+     qdict_put(qdict_options, "file", qdict_file);
+     qdict_put(qdict_options, "driver", qstring_from_str("qcow2"));
+     qdict_put(qdict_options, "id", qstring_from_str(SDCARD_DRIVE_DEFAULT_ID));
+     qdict_put(qdict, "options", qdict_options);
+     if (qmp_marshal_input_blockdev_add(default_mon, qdict, NULL)) {
+         QDECREF(qdict);
+     }
+     QDECREF(qdict);
+     qdict = qdict_new();
+     qdict_put(qdict, "driver", qstring_from_str(SDCARD_DRIVER));
+     qdict_put(qdict, "drive", qstring_from_str(SDCARD_DRIVE_DEFAULT_ID));
+     qdict_put(qdict, "id", qstring_from_str(SDCARD_DEFAULT_ID));
+     if (do_device_add(default_mon, qdict, NULL)) {
+         QDECREF(qdict);
+         // TODO error reporting
+         return false;
+     }
+     QDECREF(qdict);
+     state->sdcard_attached = true;
+     return true;
+ }
+ static bool do_sdcard_detach(void) {
+     QDict *qdict = qdict_new();
+     qdict_put(qdict, "id", qstring_from_str(SDCARD_DEFAULT_ID));
+     if (qmp_marshal_input_device_del(cur_mon, qdict, NULL)) {
+         QDECREF(qdict);
+         // TODO error reporting
+         return false;
+     }
+     QDECREF(qdict);
+     state->sdcard_attached = false;
+     return true;
+ }
++static bool do_hds_attach(const char * const file)
++{
++    QemuOpts *fsdev;
++    int ret;
++    QDict *qdict = qdict_new();
++
++    fsdev = qemu_opts_create(qemu_find_opts("fsdev"),
++                             FS_MOUNT_TAG, 0, NULL);
++    if (!fsdev) {
++        return false;
++    }
++
++    qemu_opt_set(fsdev, "fsdriver", "local");
++    qemu_opt_set(fsdev, "path", file);
++    qemu_opt_set(fsdev, "security_model", "none");
++
++    ret = qemu_fsdev_add(fsdev);
++    if (ret != 0) {
++        return false;
++    }
++
++    qdict = qdict_new();
++    qdict_put(qdict, "driver", qstring_from_str("virtio-9p-pci"));
++    qdict_put(qdict, "fsdev", qstring_from_str(FS_MOUNT_TAG));
++    qdict_put(qdict, "mount_tag", qstring_from_str(FS_MOUNT_TAG));
++    qdict_put(qdict, "id", qstring_from_str(FS_MOUNT_TAG));
++
++    if (do_device_add(default_mon, qdict, NULL)) {
++        QDECREF(qdict);
++        return false;
++    }
++
++    QDECREF(qdict);
++
++    state->hds_attached = true;
++
++    return true;
++}
++
++static bool do_hds_detach(void)
++{
++    QDict *qdict = qdict_new();
++    qemu_fsdev_remove(FS_MOUNT_TAG);
++
++    qdict_put(qdict, "id", qstring_from_str(FS_MOUNT_TAG));
++
++    if (qmp_marshal_input_device_del(cur_mon, qdict, NULL)) {
++        QDECREF(qdict);
++        return false;
++    }
++
++    QDECREF(qdict);
++
++    state->hds_attached = false;
++
++    return true;
++}
++
+ void do_hotplug(int command, void *opaque, size_t size)
+ {
+     if (command == ATTACH_SDCARD) {
+         state->opaque = g_malloc(size);
+         memcpy(state->opaque, opaque, size);
+     }
+     state->command = command;
+     event_notifier_set(&state->notifier);
+ }
+ static void device_hotplug_handler(EventNotifier *e)
+ {
+     event_notifier_test_and_clear(e);
+     switch(state->command) {
+     case ATTACH_HOST_KEYBOARD:
+         do_host_keyboard_attach();
+         break;
+     case DETACH_HOST_KEYBOARD:
+         do_host_keyboard_detach();
+         break;
+     case ATTACH_SDCARD:
+         do_sdcard_attach(state->opaque);
+         g_free(state->opaque);
+         break;
+     case DETACH_SDCARD:
+         do_sdcard_detach();
+         break;
++    case ATTACH_HDS:
++        do_hds_attach(state->opaque);
++        break;
++    case DETACH_HDS:
++        do_hds_detach();
++        break;
+     default:
+         break;
+     }
+ }
+ static void maru_device_hotplug_deinit(Notifier *notifier, void *data)
+ {
+     event_notifier_cleanup(&state->notifier);
+     g_free(state);
+ }
+ static Notifier maru_device_hotplug_exit = { .notify = maru_device_hotplug_deinit };
+ void maru_device_hotplug_init(void)
+ {
+     state = g_malloc0(sizeof(struct maru_device_hotplug));
+     event_notifier_init(&state->notifier, 0);
+     event_notifier_set_handler(&state->notifier, device_hotplug_handler);
+     emulator_add_exit_notifier(&maru_device_hotplug_exit);
+ }
+ bool is_host_keyboard_attached(void)
+ {
+     return state->host_keyboard_attached;
+ }
+ bool is_sdcard_attached(void)
+ {
+     return state->sdcard_attached;
+ }
++bool is_hds_attached(void)
++{
++    return state->hds_attached;
++}
++
index 0000000000000000000000000000000000000000,462baf3e8055651dd273a37c6b6fa425538c970b..69c8a97b085590da041e6c590cce561a8795c1e4
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,46 +1,49 @@@
+ /*
+  * Maru device hotplug
+  *
+  * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+  *
+  * Contact:
+  * SeokYeon Hwang <syeon.hwang@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 _MARU_DEVICE_HOTPLUG_H_
+ #define _MARU_DEVICE_HOTPLUG_H_
+ enum command {
+     ATTACH_HOST_KEYBOARD,
+     DETACH_HOST_KEYBOARD,
+     ATTACH_SDCARD,
+     DETACH_SDCARD,
++    ATTACH_HDS,
++    DETACH_HDS,
+ };
+ void maru_device_hotplug_init(void);
+ void do_hotplug(int command, void *opaque, size_t size);
+ bool is_host_keyboard_attached(void);
+ bool is_sdcard_attached(void);
++bool is_hds_attached(void);
+ #endif // _MARU_DEVICE_HOTPLUG_H_
index 0000000000000000000000000000000000000000,b98f9b396c32652801b2c630066b221ae294d40e..9c86f1efb5d5d9885764da41f5fe104374b301df
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,393 +1,393 @@@
 -    return make_sdcard_lock(sdcard);
+ /*
+  * Emulator
+  *
+  * Copyright (C) 2012, 2013 Samsung Electronics Co., Ltd. All rights reserved.
+  *
+  * Contact:
+  * SeokYeon Hwang <syeon.hwang@samsung.com>
+  * MunKyu Im <munkyu.im@samsung.com>
+  * GiWoong Kim <giwoong.kim@samsung.com>
+  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+  * HyunJun Son
+  *
+  * 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
+  *
+  */
+ /**
+   @file     osutil-darwin.c
+   @brief    Collection of utilities for darwin
+  */
+ #include "emulator_common.h"
+ #include "osutil.h"
+ #include "emulator.h"
+ #include "emul_state.h"
+ #include "debug_ch.h"
+ #include "maru_err_table.h"
+ #include "sdb.h"
+ #ifndef CONFIG_DARWIN
+ #error
+ #endif
+ #include <string.h>
+ #include <unistd.h>
+ #include <sys/shm.h>
+ #include <sys/sysctl.h>
+ #include <SystemConfiguration/SystemConfiguration.h>
+ MULTI_DEBUG_CHANNEL(qemu, osutil);
+ static int g_shmid;
+ static CFDictionaryRef proxySettings;
+ extern char tizen_target_img_path[];
+ static char *cfstring_to_cstring(CFStringRef str) {
+     if (str == NULL) {
+         return NULL;
+     }
+     CFIndex length = CFStringGetLength(str);
+     CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8);
+     char *buffer = (char *)malloc(maxSize);
+     if (CFStringGetCString(str, buffer, maxSize, kCFStringEncodingUTF8))
+         return buffer;
+     return NULL;
+ }
+ static int cfnumber_to_int(CFNumberRef num) {
+     if (!num)
+         return 0;
+     int value;
+     CFNumberGetValue(num, kCFNumberIntType, &value);
+     return value;
+ }
+ void check_vm_lock_os(void)
+ {
+     /* TODO: */
+ }
+ void make_vm_lock_os(void)
+ {
+     char *shared_memory;
+     int base_port;
+     base_port = get_emul_vm_base_port();
+     g_shmid = shmget((key_t)base_port, getpagesize(), 0666|IPC_CREAT);
+     if (g_shmid == -1) {
+         ERR("shmget failed\n");
+         perror("osutil-darwin: ");
+         return;
+     }
+     shared_memory = shmat(g_shmid, (char *)0x00, 0);
+     if (shared_memory == (void *)-1) {
+         ERR("shmat failed\n");
+         perror("osutil-darwin: ");
+         return;
+     }
+     g_sprintf(shared_memory, "%s", tizen_target_img_path);
+     INFO("shared memory key: %d, value: %s\n", base_port, (char *)shared_memory);
+     if (shmdt(shared_memory) == -1) {
+         ERR("shmdt failed\n");
+         perror("osutil-darwin: ");
+     }
+ }
+ void remove_vm_lock_os(void)
+ {
+     if (shmctl(g_shmid, IPC_RMID, 0) == -1) {
+         ERR("shmctl failed\n");
+         perror("osutil-linux: ");
+     }
+ }
+ void set_bin_path_os(char const *const exec_argv)
+ {
+     gchar *file_name = NULL;
+     if (!exec_argv) {
+         return;
+     }
+     char *data = g_strdup(exec_argv);
+     if (!data) {
+         ERR("Fail to strdup for paring a binary directory.\n");
+         return;
+     }
+     file_name = g_strrstr(data, "/");
+     if (!file_name) {
+         free(data);
+         return;
+     }
+     g_strlcpy(bin_path, data, strlen(data) - strlen(file_name) + 1);
+     g_strlcat(bin_path, "/", PATH_MAX);
+     free(data);
+ }
+ int get_number_of_processors(void)
+ {
+     int mib[2], sys_num = 0;
+     size_t len;
+     mib[0] = CTL_HW;
+     mib[1] = HW_AVAILCPU;
+     sysctl(mib, 2, &sys_num, &len, NULL, 0);
+     if (sys_num < 1) {
+         mib[1] = HW_NCPU;
+         sysctl(mib, 2, &sys_num, &len, NULL, 0);
+         if (sys_num < 1) {
+             sys_num = 1;
+         }
+     }
+     INFO("* Number of processors : %d\n", sys_num);
+     return sys_num;
+ }
+ void print_system_info_os(void)
+ {
+     INFO("* Mac\n");
+     /* uname */
+     INFO("* Host machine uname :\n");
+     char const *const uname_cmd = "uname -a";
+     if(system(uname_cmd) < 0) {
+         INFO("system function command '%s' \
+             returns error !", uname_cmd);
+     }
+     /* hw information */
+     int mib[2];
+     size_t len;
+     char *sys_info;
+     int sys_num = 0;
+     mib[0] = CTL_HW;
+     mib[1] = HW_MODEL;
+     sysctl(mib, 2, NULL, &len, NULL, 0);
+     sys_info = malloc(len * sizeof(char));
+     if (sysctl(mib, 2, sys_info, &len, NULL, 0) >= 0) {
+         INFO("* Machine model : %s\n", sys_info);
+     }
+     free(sys_info);
+     mib[0] = CTL_HW;
+     mib[1] = HW_MACHINE;
+     sysctl(mib, 2, NULL, &len, NULL, 0);
+     sys_info = malloc(len * sizeof(char));
+     if (sysctl(mib, 2, sys_info, &len, NULL, 0) >= 0) {
+         INFO("* Machine class : %s\n", sys_info);
+     }
+     free(sys_info);
+ #if 0
+     mib[0] = CTL_HW;
+     mib[1] = HW_NCPU;
+     len = sizeof(sys_num);
+     if (sysctl(mib, 2, &sys_num, &len, NULL, 0) >= 0) {
+         INFO("* Number of processors : %d\n", sys_num);
+     }
+ #endif
+     get_number_of_processors();
+     mib[0] = CTL_HW;
+     mib[1] = HW_PHYSMEM;
+     len = sizeof(sys_num);
+     if (sysctl(mib, 2, &sys_num, &len, NULL, 0) >= 0) {
+         INFO("* Total memory : %llu bytes\n", sys_num);
+     }
+     /* java version */
+     INFO("* Java version :\n");
+     char const *const lspci_cmd = "java -version";
+     fflush(stdout);
+     if(system(lspci_cmd) < 0) {
+         INFO("system function command '%s' \
+             returns error !", lspci_cmd);
+     }
+ }
+ static int get_auto_proxy(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
+ {
+     char type[DEFAULTBUFLEN];
+     char proxy[DEFAULTBUFLEN];
+     char line[DEFAULTBUFLEN];
+     FILE *fp_pacfile;
+     char *p = NULL;
+     CFStringRef pacURL = (CFStringRef)CFDictionaryGetValue(proxySettings,
+                     kSCPropNetProxiesProxyAutoConfigURLString);
+     if (pacURL) {
+         char url[DEFAULTBUFLEN] = {};
+         CFStringGetCString(pacURL, url, sizeof url, kCFStringEncodingASCII);
+                 INFO("pac address: %s\n", (char*)url);
+         download_url(url);
+         }
+     fp_pacfile = fopen(pac_tempfile, "r");
+     if(fp_pacfile != NULL) {
+         while(fgets(line, DEFAULTBUFLEN, fp_pacfile) != NULL) {
+             if( (strstr(line, "return") != NULL) && (strstr(line, "if") == NULL)) {
+                 INFO("line found %s", line);
+                 sscanf(line, "%*[^\"]\"%s %s", type, proxy);
+             }
+         }
+         if(g_str_has_prefix(type, DIRECT)) {
+             INFO("auto proxy is set to direct mode\n");
+             fclose(fp_pacfile);
+         }
+         else if(g_str_has_prefix(type, PROXY)) {
+             INFO("auto proxy is set to proxy mode\n");
+             INFO("type: %s, proxy: %s\n", type, proxy);
+             p = strtok(proxy, "\";");
+             if(p != NULL) {
+                 INFO("auto proxy to set: %s\n",p);
+                 strcpy(http_proxy, p);
+                 strcpy(https_proxy, p);
+                 strcpy(ftp_proxy, p);
+                 strcpy(socks_proxy, p);
+             }
+             fclose(fp_pacfile);
+         }
+         else
+         {
+             ERR("pac file is not wrong! It could be the wrong pac address or pac file format\n");
+             fclose(fp_pacfile);
+         }
+     }
+     else {
+         ERR("fail to get pacfile fp\n");
+     return -1;
+     }
+     remove(pac_tempfile);
+     return 0;
+ }
+ static void get_proxy(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
+ {
+     char *hostname;
+     int port;
+     CFNumberRef isEnable;
+     CFStringRef proxyHostname;
+     CFNumberRef proxyPort;
+     CFDictionaryRef proxySettings;
+     proxySettings = SCDynamicStoreCopyProxies(NULL);
+     isEnable  = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPEnable);
+     if (cfnumber_to_int(isEnable)) {
+         // Get proxy hostname
+         proxyHostname = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPProxy);
+         hostname = cfstring_to_cstring(proxyHostname);
+         // Get proxy port
+         proxyPort = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPPort);
+         port = cfnumber_to_int(proxyPort);
+         // Save hostname & port
+         snprintf(http_proxy, DEFAULTBUFLEN, "%s:%d", hostname, port);
+         free(hostname);
+     } else {
+         INFO("http proxy is null\n");
+     }
+     isEnable  = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPSEnable);
+     if (cfnumber_to_int(isEnable)) {
+         // Get proxy hostname
+         proxyHostname = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPSProxy);
+         hostname = cfstring_to_cstring(proxyHostname);
+         // Get proxy port
+         proxyPort = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPSPort);
+         port = cfnumber_to_int(proxyPort);
+         // Save hostname & port
+         snprintf(https_proxy, DEFAULTBUFLEN, "%s:%d", hostname, port);
+         free(hostname);
+     } else {
+         INFO("https proxy is null\n");
+     }
+     isEnable  = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesFTPEnable);
+     if (cfnumber_to_int(isEnable)) {
+         // Get proxy hostname
+         proxyHostname = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesFTPProxy);
+         hostname = cfstring_to_cstring(proxyHostname);
+         // Get proxy port
+         proxyPort = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesFTPPort);
+         port = cfnumber_to_int(proxyPort);
+         // Save hostname & port
+         snprintf(ftp_proxy, DEFAULTBUFLEN, "%s:%d", hostname, port);
+         free(hostname);
+     } else {
+         INFO("ftp proxy is null\n");
+     }
+     isEnable  = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesSOCKSEnable);
+     if (cfnumber_to_int(isEnable)) {
+         // Get proxy hostname
+         proxyHostname = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesSOCKSProxy);
+         hostname = cfstring_to_cstring(proxyHostname);
+         // Get proxy port
+         proxyPort = CFDictionaryGetValue(proxySettings, kSCPropNetProxiesSOCKSPort);
+         port = cfnumber_to_int(proxyPort);
+         // Save hostname & port
+         snprintf(socks_proxy, DEFAULTBUFLEN, "%s:%d", hostname, port);
+         free(hostname);
+     } else {
+         INFO("socks proxy is null\n");
+     }
+     CFRelease(proxySettings);
+ }
+ void get_host_proxy_os(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
+ {
+     int ret;
+     proxySettings = SCDynamicStoreCopyProxies(NULL);
+     if(proxySettings) {
+         INFO("AUTO PROXY MODE\n");
+         ret = get_auto_proxy(http_proxy, https_proxy, ftp_proxy, socks_proxy);
+         if(strlen(http_proxy) == 0 && ret < 0) {
+             INFO("MANUAL PROXY MODE\n");
+             get_proxy(http_proxy, https_proxy, ftp_proxy, socks_proxy);
+         }
+     }
+ }
+ bool make_sdcard_lock_os(char *sdcard)
+ {
 -    return remove_sdcard_lock(sdcard);
++    return make_sdcard_lock_posix(sdcard);
+ }
+ int remove_sdcard_lock_os(char *sdcard)
+ {
++    return remove_sdcard_lock_posix(sdcard);
+ }
index 0000000000000000000000000000000000000000,2cd47b1f371292885d6ee308db99b71b567c10d8..a84379c791cd986301eb8b148d9f244fb72aff9d
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,669 +1,670 @@@
 -    return make_sdcard_lock(sdcard);
+ /*
+  * Emulator
+  *
+  * Copyright (C) 2012 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+  *
+  * Contact:
+  * SeokYeon Hwang <syeon.hwang@samsung.com>
+  * MunKyu Im <munkyu.im@samsung.com>
+  * GiWoong Kim <giwoong.kim@samsung.com>
+  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+  * HyunJun Son
+  *
+  * 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
+  *
+  */
+ /**
+   @file     osutil-linux.c
+   @brief    Collection of utilities for linux
+  */
+ #include <png.h>
+ #include "osutil.h"
+ #include "emulator.h"
+ #include "emul_state.h"
+ #include "debug_ch.h"
+ #include "maru_err_table.h"
+ #include "sdb.h"
+ #ifndef CONFIG_LINUX
+ #error
+ #endif
+ #include <string.h>
+ #include <unistd.h>
+ #include <sys/shm.h>
+ #include <sys/ipc.h>
+ #include <linux/version.h>
+ #include <sys/utsname.h>
+ #include <sys/sysinfo.h>
+ #ifdef CONFIG_SPICE
+ #include <dirent.h>
+ #endif
+ MULTI_DEBUG_CHANNEL(emulator, osutil);
+ static int g_shmid;
+ static char *g_shared_memory;
+ static int gproxytool = GSETTINGS;
+ extern char tizen_target_img_path[];
+ /* Getting proxy commands */
+ static const char* gproxycmds[][2] = {
+     { "gconftool-2 -g /system/proxy/mode" , "gsettings get org.gnome.system.proxy mode" },
+     { "gconftool-2 -g /system/proxy/autoconfig_url", "gsettings get org.gnome.system.proxy autoconfig-url" },
+     { "gconftool-2 -g /system/http_proxy/host", "gsettings get org.gnome.system.proxy.http host" },
+     { "gconftool-2 -g /system/http_proxy/port", "gsettings get org.gnome.system.proxy.http port"},
+     { "gconftool-2 -g /system/proxy/secure_host", "gsettings get org.gnome.system.proxy.https host" },
+     { "gconftool-2 -g /system/proxy/secure_port", "gsettings get org.gnome.system.proxy.https port" },
+     { "gconftool-2 -g /system/proxy/ftp_host", "gsettings get org.gnome.system.proxy.ftp host" },
+     { "gconftool-2 -g /system/proxy/ftp_port", "gsettings get org.gnome.system.proxy.ftp port" },
+     { "gconftool-2 -g /system/proxy/socks_host", "gsettings get org.gnome.system.proxy.socks host" },
+     { "gconftool-2 -g /system/proxy/socks_port", "gsettings get org.gnome.system.proxy.socks port" },
+ };
+ void check_vm_lock_os(void)
+ {
+     int shm_id;
+     void *shm_addr;
+     uint32_t port;
+     int val;
+     struct shmid_ds shm_info;
+     for (port = 26100; port < 26200; port += 10) {
+         shm_id = shmget((key_t)port, 0, 0);
+         if (shm_id != -1) {
+             shm_addr = shmat(shm_id, (void *)0, 0);
+             if ((void *)-1 == shm_addr) {
+                 ERR("error occured at shmat()\n");
+                 break;
+             }
+             val = shmctl(shm_id, IPC_STAT, &shm_info);
+             if (val != -1) {
+                 INFO("count of process that use shared memory : %d\n",
+                     shm_info.shm_nattch);
+                 if ((shm_info.shm_nattch > 0) &&
+                     g_strcmp0(tizen_target_img_path, (char *)shm_addr) == 0) {
+                     if (check_port_bind_listen(port + 1) > 0) {
+                         shmdt(shm_addr);
+                         continue;
+                     }
+                     shmdt(shm_addr);
+                     maru_register_exit_msg(MARU_EXIT_UNKNOWN,
+                                         "Can not execute this VM.\n"
+                                         "The same name is running now.");
+                     exit(0);
+                 } else {
+                     shmdt(shm_addr);
+                 }
+             }
+         }
+     }
+ }
+ void make_vm_lock_os(void)
+ {
+     int base_port;
+     base_port = get_emul_vm_base_port();
+     g_shmid = shmget((key_t)base_port, getpagesize(), 0666|IPC_CREAT);
+     if (g_shmid == -1) {
+         ERR("shmget failed\n");
+         perror("osutil-linux: ");
+         return;
+     }
+     g_shared_memory = shmat(g_shmid, (char *)0x00, 0);
+     if (g_shared_memory == (void *)-1) {
+         ERR("shmat failed\n");
+         perror("osutil-linux: ");
+         return;
+     }
+     g_sprintf(g_shared_memory, "%s", tizen_target_img_path);
+     INFO("shared memory key: %d value: %s\n",
+         base_port, (char *)g_shared_memory);
+     if (shmdt(g_shared_memory) == -1) {
+         ERR("shmdt failed\n");
+         perror("osutil-linux: ");
+     }
+ }
+ void remove_vm_lock_os(void)
+ {
+     if (shmctl(g_shmid, IPC_RMID, 0) == -1) {
+         ERR("shmctl failed\n");
+         perror("osutil-linux: ");
+     }
+ }
+ void set_bin_path_os(char const *const exec_argv)
+ {
+     gchar link_path[PATH_MAX] = { 0, };
+     char *file_name = NULL;
+     ssize_t len = readlink("/proc/self/exe", link_path, sizeof(link_path) - 1);
+     if (len < 0 || len > (sizeof(link_path) - 1)) {
+         perror("set_bin_path error : ");
+         return;
+     }
+     link_path[len] = '\0';
+     file_name = g_strrstr(link_path, "/");
+     g_strlcpy(bin_path, link_path, strlen(link_path) - strlen(file_name) + 1);
+     g_strlcat(bin_path, "/", PATH_MAX);
+ #ifdef CONFIG_SPICE
+     g_strlcpy(remote_bin_path, link_path, strlen(link_path) - strlen(file_name) - 2);
+     g_strlcat(remote_bin_path, "remote/bin/", PATH_MAX);
+ #endif
+ }
+ int get_number_of_processors(void)
+ {
+     int num_processors = 0;
+     num_processors = sysconf(_SC_NPROCESSORS_ONLN);
+     if (num_processors < 1) {
+         num_processors = 1;
+     }
+     TRACE("Number of processors : %d\n", num_processors);
+     return num_processors;
+ }
+ void print_system_info_os(void)
+ {
+     INFO("* Linux\n");
+     INFO("* LibPNG Version : %s\n", PNG_LIBPNG_VER_STRING);
+     /* depends on building */
+     INFO("* QEMU build machine linux kernel version : (%d, %d, %d)\n",
+         LINUX_VERSION_CODE >> 16,
+         (LINUX_VERSION_CODE >> 8) & 0xff,
+         LINUX_VERSION_CODE & 0xff);
+      /* depends on launching */
+     struct utsname host_uname_buf;
+     if (uname(&host_uname_buf) == 0) {
+         INFO("* Host machine uname : %s %s %s %s %s\n",
+             host_uname_buf.sysname, host_uname_buf.nodename,
+             host_uname_buf.release, host_uname_buf.version,
+             host_uname_buf.machine);
+     }
+     struct sysinfo sys_info;
+     if (sysinfo(&sys_info) == 0) {
+         INFO("* Total Ram : %llu kB, Free: %llu kB\n",
+             sys_info.totalram * (unsigned long long)sys_info.mem_unit / 1024,
+             sys_info.freeram * (unsigned long long)sys_info.mem_unit / 1024);
+     }
+     /* get linux distribution information */
+     INFO("* Linux distribution infomation :\n");
+     char const *const lsb_release_cmd = "lsb_release -d -r -c";
+     gchar *buffer = NULL;
+     gint buffer_size = strlen(lsb_release_cmd) + 1;
+     buffer = g_malloc(buffer_size);
+     g_snprintf(buffer, buffer_size, "%s", lsb_release_cmd);
+     if (system(buffer) < 0) {
+         INFO("system function command '%s' \
+                 returns error !", buffer);
+     }
+     g_free(buffer);
+     /* pci device description */
+     INFO("* Host PCI devices :\n");
+     char const *const lspci_cmd = "lspci";
+     buffer_size = strlen(lspci_cmd) + 1;
+     buffer = g_malloc(buffer_size);
+     g_snprintf(buffer, buffer_size, "%s", lspci_cmd);
+     fflush(stdout);
+     if (system(buffer) < 0) {
+         INFO("system function command '%s' \
+                 returns error !", buffer);
+     }
+     g_free(buffer);
+ }
+ static void process_string(char *buf)
+ {
+     char tmp_buf[DEFAULTBUFLEN];
+     /* remove single quotes of strings gotten by gsettings */
+     if (gproxytool == GSETTINGS) {
+         remove_string(buf, tmp_buf, "\'");
+         memset(buf, 0, DEFAULTBUFLEN);
+         strncpy(buf, tmp_buf, strlen(tmp_buf)-1);
+     }
+ }
+ static int get_auto_proxy(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
+ {
+     char type[DEFAULTBUFLEN];
+     char proxy[DEFAULTBUFLEN];
+     char line[DEFAULTBUFLEN];
+     FILE *fp_pacfile;
+     char *p = NULL;
+     FILE *output;
+     char buf[DEFAULTBUFLEN];
+     output = popen(gproxycmds[GNOME_PROXY_AUTOCONFIG_URL][gproxytool], "r");
+     if (fscanf(output, "%s", buf) > 0) {
+         process_string(buf);
+         INFO("pac address: %s\n", buf);
+         download_url(buf);
+     }
+     pclose(output);
+     fp_pacfile = fopen(pac_tempfile, "r");
+     if (fp_pacfile != NULL) {
+         while (fgets(line, DEFAULTBUFLEN, fp_pacfile) != NULL) {
+             if ((strstr(line, "return") != NULL) && (strstr(line, "if") == NULL)) {
+                 INFO("line found %s", line);
+                 sscanf(line, "%*[^\"]\"%s %s", type, proxy);
+             }
+         }
+         if (g_str_has_prefix(type, DIRECT)) {
+             INFO("auto proxy is set to direct mode\n");
+             fclose(fp_pacfile);
+         } else if (g_str_has_prefix(type, PROXY)) {
+             INFO("auto proxy is set to proxy mode\n");
+             INFO("type: %s, proxy: %s\n", type, proxy);
+             p = strtok(proxy, "\";");
+             if (p != NULL) {
+                 INFO("auto proxy to set: %s\n",p);
+                 strcpy(http_proxy, p);
+                 strcpy(https_proxy, p);
+                 strcpy(ftp_proxy, p);
+                 strcpy(socks_proxy, p);
+             }
+             fclose(fp_pacfile);
+         } else {
+             ERR("pac file is not wrong! It could be the wrong pac address or pac file format\n");
+             fclose(fp_pacfile);
+         }
+     } else {
+         ERR("fail to get pacfile fp\n");
+         return -1;
+     }
+     if (remove(pac_tempfile) < 0) {
+         WARN("fail to remove the temporary pacfile\n");
+     }
+     return 0;
+ }
+ static void get_proxy(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
+ {
+     char buf[DEFAULTBUFLEN] = {0,};
+     char buf_port[MAXPORTLEN] = {0,};
+     char buf_proxy[DEFAULTBUFLEN] = {0,};
+     char *buf_proxy_bak;
+     char *proxy;
+     FILE *output;
+     int MAXPROXYLEN = DEFAULTBUFLEN + MAXPORTLEN;
+     output = popen(gproxycmds[GNOME_PROXY_HTTP_HOST][gproxytool], "r");
+     if(fscanf(output, "%s", buf) > 0) {
+         process_string(buf);
+         snprintf(buf_proxy, DEFAULTBUFLEN, "%s", buf);
+     }
+     pclose(output);
+     output = popen(gproxycmds[GNOME_PROXY_HTTP_PORT][gproxytool], "r");
+     if(fscanf(output, "%s", buf_port) <= 0) {
+         //for abnormal case: if can't find the key of http port, get from environment value.
+         buf_proxy_bak = getenv("http_proxy");
+         INFO("http_proxy from env: %s\n", buf_proxy_bak);
+         if(buf_proxy_bak != NULL) {
+             proxy = malloc(DEFAULTBUFLEN);
+             remove_string(buf_proxy_bak, proxy, HTTP_PREFIX);
+             strncpy(http_proxy, proxy, strlen(proxy)-1);
+             INFO("final http_proxy value: %s\n", http_proxy);
+             free(proxy);
+         }
+         else {
+             INFO("http_proxy is not set on env.\n");
+             pclose(output);
+             return;
+         }
+     }
+     else {
+         snprintf(http_proxy, MAXPROXYLEN, "%s:%s", buf_proxy, buf_port);
+         memset(buf_proxy, 0, DEFAULTBUFLEN);
+         INFO("http_proxy: %s\n", http_proxy);
+     }
+     pclose(output);
+     memset(buf, 0, DEFAULTBUFLEN);
+     output = popen(gproxycmds[GNOME_PROXY_HTTPS_HOST][gproxytool], "r");
+     if(fscanf(output, "%s", buf) > 0) {
+         process_string(buf);
+         snprintf(buf_proxy, DEFAULTBUFLEN, "%s", buf);
+     }
+     pclose(output);
+     output = popen(gproxycmds[GNOME_PROXY_HTTPS_PORT][gproxytool], "r");
+     if(fscanf(output, "%s", buf) > 0) {
+         snprintf(https_proxy, MAXPROXYLEN, "%s:%s", buf_proxy, buf);
+     }
+     pclose(output);
+     memset(buf, 0, DEFAULTBUFLEN);
+     memset(buf_proxy, 0, DEFAULTBUFLEN);
+     INFO("https_proxy : %s\n", https_proxy);
+     output = popen(gproxycmds[GNOME_PROXY_FTP_HOST][gproxytool], "r");
+     if(fscanf(output, "%s", buf) > 0) {
+         process_string(buf);
+         snprintf(buf_proxy, DEFAULTBUFLEN, "%s", buf);
+     }
+     pclose(output);
+     output = popen(gproxycmds[GNOME_PROXY_FTP_PORT][gproxytool], "r");
+     if(fscanf(output, "%s", buf) > 0) {
+         snprintf(ftp_proxy, MAXPROXYLEN, "%s:%s", buf_proxy, buf);
+     }
+     pclose(output);
+     memset(buf, 0, DEFAULTBUFLEN);
+     memset(buf_proxy, 0, DEFAULTBUFLEN);
+     INFO("ftp_proxy : %s\n", ftp_proxy);
+     output = popen(gproxycmds[GNOME_PROXY_SOCKS_HOST][gproxytool], "r");
+     if(fscanf(output, "%s", buf) > 0) {
+         process_string(buf);
+         snprintf(buf_proxy, DEFAULTBUFLEN, "%s", buf);
+     }
+     pclose(output);
+     output = popen(gproxycmds[GNOME_PROXY_SOCKS_PORT][gproxytool], "r");
+     if(fscanf(output, "%s", buf) > 0) {
+         snprintf(socks_proxy, MAXPROXYLEN, "%s:%s", buf_proxy, buf);
+     }
+     pclose(output);
+     INFO("socks_proxy : %s\n", socks_proxy);
+ }
+ void get_host_proxy_os(char *http_proxy, char *https_proxy, char *ftp_proxy, char *socks_proxy)
+ {
+     char buf[DEFAULTBUFLEN];
+     FILE *output;
+     int ret;
+     output = popen(gproxycmds[GNOME_PROXY_MODE][gproxytool], "r");
+     ret = fscanf(output, "%s", buf);
+     if (ret <= 0) {
+         pclose(output);
+         INFO("Try to use gsettings to get proxy\n");
+         gproxytool = GSETTINGS;
+         output = popen(gproxycmds[GNOME_PROXY_MODE][gproxytool], "r");
+         ret = fscanf(output, "%s", buf);
+     }
+     if (ret > 0) {
+         process_string(buf);
+         //priority : auto > manual > none
+         if (strcmp(buf, "auto") == 0) {
+             INFO("AUTO PROXY MODE\n");
+             get_auto_proxy(http_proxy, https_proxy, ftp_proxy, socks_proxy);
+         }
+         else if (strcmp(buf, "manual") == 0) {
+             INFO("MANUAL PROXY MODE\n");
+             get_proxy(http_proxy, https_proxy, ftp_proxy, socks_proxy);
+         }
+         else if (strcmp(buf, "none") == 0) {
+             INFO("DIRECT PROXY MODE\n");
+         }
+     }
+     pclose(output);
+ }
+ #ifdef CONFIG_SPICE
+ #define PID_MAX_COUNT 256
+ const char *execution_file_websocket = "websockify.py";
+ const char *execution_file_node = "node";
+ const char *node_proc_name = "emulator-x86-web";
+ void get_process_id(char const *process_name, char *first_param, int *pid, int *pscount)
+ {
+     char cmdline[2048], dir_name[255];
+     int total_len = 0, current_len = 0;
+     struct dirent *dir_entry_p;
+     DIR *dir_p;
+     FILE *fp;
+     char *mptr;
+     dir_p = opendir("/proc/");
+     while (NULL != (dir_entry_p = readdir(dir_p))) {
+         /* Checking for numbered directories */
+         if (strspn(dir_entry_p->d_name, "0123456789") == strlen(dir_entry_p->d_name)) {
+             strcpy(dir_name, "/proc/");
+             strcat(dir_name, dir_entry_p->d_name);
+             strcat(dir_name, "/cmdline");
+             fp = fopen(dir_name, "rb");
+             if (fp == NULL) {
+                 continue;
+             }
+             total_len = 0;
+             memset(cmdline, 0, sizeof(cmdline));
+             while (!feof(fp)) {
+                 cmdline[total_len++] = fgetc(fp);
+             }
+             fclose(fp);
+             current_len = strlen(cmdline);
+             mptr = cmdline;
+             do {
+                 if (strstr(mptr, process_name) != NULL) {
+                     if (!first_param || strstr(&cmdline[current_len + 1], first_param) != NULL) {
+                         if (sizeof(pid) < *pscount + 1) {
+                             WARN("PID array size is not enough.\n");
+                             return;
+                         }
+                         pid[*pscount] = atoi(dir_entry_p->d_name);
+                         INFO("get_process_id(%s %s) :Found. id = %d\n", process_name, first_param, pid[*pscount]);
+                         (*pscount)++;
+                     }
+                     break;
+                 }
+                 mptr = &cmdline[current_len + 1];
+                 current_len += strlen(mptr) + 1;
+             } while (current_len < total_len);
+         }
+     }
+     closedir(dir_p);
+     if (*pscount == 0) {
+         INFO("get_process_id(%s %s) : id = 0 (could not find process)\n", process_name, first_param);
+     }
+ }
+ void execute_websocket(int port)
+ {
+     char const *remote_bin_dir = get_remote_bin_path();
+     char const *relative_path = "../websocket/";
+     char websocket_path[strlen(remote_bin_dir) + strlen(execution_file_websocket) + strlen(relative_path) + 1];
+     int ret = -1;
+     char local_port[32];
+     char websocket_port[16];
+     memset(websocket_port, 0, sizeof(websocket_port));
+     sprintf(websocket_port, "%d", port);
+     memset(local_port, 0, sizeof(local_port));
+     sprintf(local_port, "localhost:%d", get_emul_spice_port());
+     memset(websocket_path, 0, sizeof(websocket_path));
+     sprintf(websocket_path, "%s%s%s", remote_bin_dir, relative_path, execution_file_websocket);
+     INFO("Exec [%s %s %s]\n", websocket_path, websocket_port, local_port);
+     ret = execl(websocket_path, execution_file_websocket, websocket_port, local_port, (char *)0);
+     if (ret == 127) {
+         WARN("Can't execute websocket.\n");
+     } else if (ret == -1) {
+         WARN("Fork error!\n");
+     }
+ }
+ void execute_nodejs(void)
+ {
+     char const *remote_bin_dir = get_remote_bin_path();
+     char const *relative_path = "../web-viewer/bin/emul";
+     char webviewer_script[strlen(remote_bin_dir) + strlen(relative_path) + 1];
+     char nodejs_path[strlen(remote_bin_dir) + strlen(execution_file_node) + 1];
+     int ret = -1;
+     memset(webviewer_script, 0, sizeof(webviewer_script));
+     sprintf(webviewer_script, "%s%s", remote_bin_dir, relative_path);
+     memset(nodejs_path, 0, sizeof(nodejs_path));
+     sprintf(nodejs_path, "%s%s", remote_bin_dir, execution_file_node);
+     INFO("Exec [%s %s]\n", nodejs_path, webviewer_script);
+     ret = execl(nodejs_path, execution_file_node, webviewer_script, (char *)0);
+     if (ret == 127) {
+         WARN("Can't execute node server.\n");
+     } else if (ret == -1) {
+         WARN("Fork error!\n");
+     }
+ }
+ void clean_websocket_port(int signal)
+ {
+     char websocket_port[16];
+     memset(websocket_port, 0, sizeof(websocket_port));
+     sprintf(websocket_port, "%d", get_emul_websocket_port());
+     int pscount = 0, i = 0;
+     int pid[PID_MAX_COUNT];
+     memset(pid, 0, PID_MAX_COUNT);
+     get_process_id(execution_file_websocket, websocket_port, pid, &pscount);
+     if (pscount > 0) {
+         for (i = 0; i < pscount; i++) {
+             INFO("Will be killed PID: %d\n", pid[i]);
+             kill(pid[i], signal);
+         }
+     }
+ }
+ static void websocket_notify_exit(Notifier *notifier, void *data)
+ {
+     clean_websocket_port(SIGTERM);
+ }
+ static void nodejs_notify_exit(Notifier *notifier, void *data)
+ {
+     int pscount = 0, i = 0;
+     int pid[PID_MAX_COUNT];
+     memset(pid, 0, sizeof(pid));
+     get_process_id("spicevmc", NULL, pid, &pscount);
+     if (pscount == 1) {
+         INFO("Detected the last spice emulator.\n");
+         pid[0] = 0;
+         pscount = 0;
+         get_process_id(node_proc_name, NULL, pid, &pscount);
+         for (i = 0; i < pscount; i++) {
+             INFO("Will be killed %s, PID: %d\n", node_proc_name, pid[i]);
+             kill(pid[i], SIGTERM);
+         }
+     }
+ }
+ static Notifier websocket_exit = { .notify = websocket_notify_exit };
+ static Notifier nodejs_exit = { .notify = nodejs_notify_exit };
+ void websocket_init(void)
+ {
+     int pscount = 0;
+     char websocket_port[16];
+     int pid[PID_MAX_COUNT];
+     memset(websocket_port, 0, sizeof(websocket_port));
+     sprintf(websocket_port, "%d", get_emul_websocket_port());
+     memset(pid, 0, sizeof(pid));
+     get_process_id(execution_file_websocket, websocket_port, pid, &pscount);
+     emulator_add_exit_notifier(&websocket_exit);
+     if (pscount == 0) {
+         int pid = fork();
+         if (pid == 0) {
+             setsid();
+             execute_websocket(get_emul_websocket_port());
+         }
+     } else {
+        INFO("Aleady running websokify %s localhost:%d\n", websocket_port, get_emul_spice_port());
+     }
+ }
+ void nodejs_init(void)
+ {
+     int pscount = 0;
+     int pid[PID_MAX_COUNT];
+     memset(pid, 0, sizeof(pid));
+     get_process_id(node_proc_name, NULL, pid, &pscount);
+     emulator_add_exit_notifier(&nodejs_exit);
+     if (pscount == 0) {
+         int pid = fork();
+         if (pid == 0) {
+             setsid();
+             execute_nodejs();
+         }
+     } else {
+        INFO("Aleady running node server.\n");
+     }
+ }
+ #endif
++
+ bool make_sdcard_lock_os(char *sdcard)
+ {
 -    return remove_sdcard_lock(sdcard);
++    return make_sdcard_lock_posix(sdcard);
+ }
+ int remove_sdcard_lock_os(char *sdcard)
+ {
++    return remove_sdcard_lock_posix(sdcard);
+ }
index 0000000000000000000000000000000000000000,a4d01df83d63f24f05c1a1b4c6bbbe5916988fb4..f2aa90e80a20914749e979210b3d87cf4f61edac
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,183 +1,183 @@@
 -inline bool make_sdcard_lock(char *sdcard)
+ /*
+  * Emulator
+  *
+  * Copyright (C) 2012, 2013 Samsung Electronics Co., Ltd. All rights reserved.
+  *
+  * Contact:
+  * SeokYeon Hwang <syeon.hwang@samsung.com>
+  * MunKyu Im <munkyu.im@samsung.com>
+  * GiWoong Kim <giwoong.kim@samsung.com>
+  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+  * HyunJun Son
+  *
+  * 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
+  *
+  */
+ /**
+   @file     osutil.c
+   @brief    Common functions for osutil
+  */
+ #include "osutil.h"
+ #include "debug_ch.h"
+ #include <curl/curl.h>
+ #include <string.h>
+ MULTI_DEBUG_CHANNEL(emulator, osutil);
+ const char *pac_tempfile = ".autoproxy";
+ #ifndef CONFIG_WIN32
+ static int g_fd;
+ #endif
+ inline size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
+ {
+     size_t written;
+     written = fwrite(ptr, size, nmemb, stream);
+     return written;
+ }
+ void download_url(char *url)
+ {
+     CURL *curl;
+     FILE *fp;
+     CURLcode res;
+     curl = curl_easy_init();
+     if (curl) {
+         fp = fopen(pac_tempfile, "wb");
+         if(fp == NULL) {
+             ERR("failed to fopen(): %s\n", pac_tempfile);
+             return;
+         }
+         curl_easy_setopt(curl, CURLOPT_URL, url);
+         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
+         /* just in case network does not work */
+         curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 3000);
+         curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
+         res = curl_easy_perform(curl);
+         if (res != 0) {
+             ERR("Fail to download pac file: %s\n", url);
+         }
+         curl_easy_cleanup(curl);
+         fclose(fp);
+     }
+     return;
+ }
+ inline void remove_string(char *src, char *dst, const char *toremove)
+ {
+     int len = strlen(toremove);
+     int i, j;
+     int max_len = strlen(src);
+     for(i = len, j = 0; i < max_len; i++)
+     {
+         dst[j++] = src[i];
+     }
+     dst[j] = '\0';
+ }
+ #ifndef CONFIG_WIN32
+ static int fd_lock(int fd)
+ {
+     struct flock lock;
+     lock.l_type = F_WRLCK;
+     lock.l_start = 0;
+     lock.l_whence = SEEK_SET;
+     lock.l_len = 0;
+     lock.l_pid = getpid();
+     return fcntl(fd, F_SETLK, &lock);
+ }
+ static int fd_unlock(int fd)
+ {
+     struct flock lock;
+     lock.l_type = F_UNLCK;
+     lock.l_start = 0;
+     lock.l_whence = SEEK_SET;
+     lock.l_len = 0;
+     return fcntl(fd, F_SETLK, &lock);
+ }
 -inline int remove_sdcard_lock(char *sdcard)
++inline bool make_sdcard_lock_posix(char *sdcard)
+ {
+     char *lock_file = g_strdup_printf("%s.lck", sdcard);
+     int fd = open(lock_file, O_CREAT|O_RDWR, 0666);
+     if (fd == -1)
+     {
+         perror("file open error : ");
+         return false;
+     }
+     if (fd_lock(fd) == -1)
+     {
+         perror("file is lock ");
+         close(fd);
+         return false;
+     }
+     INFO("Get file lock: %s\n", lock_file);
+     g_fd = fd;
+     close(fd);
+     return true;
+ }
++inline int remove_sdcard_lock_posix(char *sdcard)
+ {
+     errno = 0;
+     char *lock_file = g_strdup_printf("%s.lck", sdcard);
+     int fd = open(lock_file, O_RDWR, 0666);
+     if (fd == -1)
+     {
+         perror("file open error : ");
+         if(errno == ENOENT) {
+             return ERR_NOENT;
+         }
+         return ERR_UNLCK;
+     }
+     if (fd_unlock(fd) == -1)
+     {
+         perror("file unlock error ");
+         close(fd);
+         return ERR_UNLCK;
+     }
+     if (unlink(lock_file) < 0) {
+         perror("unlink error ");
+         close(fd);
+         return ERR_UNLCK;
+     }
+     INFO("unlock success: %s\n", lock_file);
+     close(fd);
+     close(g_fd);
+     return ERR_SUCCESS;
+ }
+ #endif
index 0000000000000000000000000000000000000000,ab4f7d5a1499f851dd0de58f4225919338d8b797..8e4de9413787a7cf7b30f63a253fafb6837129d2
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,116 +1,116 @@@
 -bool make_sdcard_lock(char *sdcard);
 -int remove_sdcard_lock(char *sdcard);
+ /*
+  * Emulator
+  *
+  * Copyright (C) 2011, 2012 Samsung Electronics Co., Ltd. All rights reserved.
+  *
+  * Contact:
+  * SeokYeon Hwang <syeon.hwang@samsung.com>
+  * MunKyu Im <munkyu.im@samsung.com>
+  * GiWoong Kim <giwoong.kim@samsung.com>
+  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+  * HyunJun Son
+  *
+  * 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 __OSUTIL_H__
+ #define __OSUTIL_H__
+ #include "qemu-common.h"
+ #define HTTP_PROTOCOL "http="
+ #define HTTP_PREFIX "http://"
+ #define HTTPS_PROTOCOL "https="
+ #define FTP_PROTOCOL "ftp="
+ #define SOCKS_PROTOCOL "socks="
+ #define DIRECT "DIRECT"
+ #define PROXY "PROXY"
+ #define MAXPORTLEN 6
+ #define DEFAULTBUFLEN 512
+ #define GNOME_PROXY_MODE 0
+ #define GNOME_PROXY_AUTOCONFIG_URL 1
+ #define GNOME_PROXY_HTTP_HOST 2
+ #define GNOME_PROXY_HTTP_PORT 3
+ #define GNOME_PROXY_HTTPS_HOST 4
+ #define GNOME_PROXY_HTTPS_PORT 5
+ #define GNOME_PROXY_FTP_HOST 6
+ #define GNOME_PROXY_FTP_PORT 7
+ #define GNOME_PROXY_SOCKS_HOST 8
+ #define GNOME_PROXY_SOCKS_PORT 9
+ #define GCONFTOOL 0
+ #define GSETTINGS 1
+ #define ERR_SUCCESS 0
+ #define ERR_UNLCK 4
+ #define ERR_LCK   5
+ #define ERR_NOENT 6
+ extern const char *pac_tempfile;
+ void check_vm_lock_os(void);
+ void make_vm_lock_os(void);
+ void remove_vm_lock_os(void);
+ bool make_sdcard_lock_os(char *sdcard);
+ int remove_sdcard_lock_os(char *sdcard);
+ void set_bin_path_os(char const *const);
+ #ifndef CONFIG_WIN32
++bool make_sdcard_lock_posix(char *sdcard);
++int remove_sdcard_lock_posix(char *sdcard);
+ #endif
+ void print_system_info_os(void);
+ void get_host_proxy_os(char *, char *, char *, char *);
+ void download_url(char *);
+ size_t write_data(void *, size_t, size_t, FILE *);
+ void remove_string(char *, char *, const char *);
+ #if defined(CONFIG_SPICE) && defined(CONFIG_LINUX)
+ void get_process_id(char const *process_name, char *first_param, int *pid, int *pscount);
+ void execute_websocket(int port);
+ void execute_nodejs(void);
+ void clean_websocket_port(int signal);
+ void nodejs_init(void);
+ void websocket_init(void);
+ #endif
+ static inline int get_timeofday(char *buf, size_t size)
+ {
+     qemu_timeval tv;
+     time_t ti;
+     struct tm *ptm = NULL;
+     int ret;
+     qemu_gettimeofday(&tv);
+     ti = tv.tv_sec;
+     /* In this case, localtime_r() function is not necessary. */
+     ptm = localtime(&ti);
+     ret = strftime(buf, size, "%H:%M:%S", ptm);
+     return ret + g_snprintf(buf + ret, size - ret, ".%06ld", (long)tv.tv_usec);
+ }
+ int get_number_of_processors(void);
+ #endif // __OS_UTIL_H__