pkgs: added extra packages installation 00/33300/3
authorJinhyung Choi <jinhyung2.choi@samsung.com>
Thu, 8 Jan 2015 06:38:16 +0000 (15:38 +0900)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Tue, 20 Jan 2015 08:10:24 +0000 (00:10 -0800)
Change-Id: I5aa6b139a77e75ece91d9fdca60e9105fb159542
Signed-off-by: Jinhyung Choi <jinhyung2.choi@samsung.com>
14 files changed:
tizen/src/ecs/ecs.c
tizen/src/ecs/ecs.h
tizen/src/ecs/ecs_msg.c
tizen/src/ecs/ecs_msg_device.c
tizen/src/ecs/ecs_msg_injector.c
tizen/src/emul_state.c
tizen/src/emul_state.h
tizen/src/hw/virtio/maru_virtio_evdi.c
tizen/src/hw/virtio/maru_virtio_evdi.h
tizen/src/hw/virtio/maru_virtio_pci.c
tizen/src/util/Makefile.objs
tizen/src/util/extra_pkgs_install.c [new file with mode: 0644]
tizen/src/util/extra_pkgs_install.h [new file with mode: 0644]
tizen/src/util/sdb.c

index 804e6c1..e757531 100644 (file)
@@ -72,7 +72,6 @@ static int payloadsize;
 static int g_client_id = 1;
 
 static QemuMutex mutex_clilist;
-QemuMutex mutex_guest_connection;
 QemuMutex mutex_location_data;
 
 static QemuThread ecs_thread_id;
@@ -236,7 +235,6 @@ static void ecs_close(ECS_State *cs) {
     current_ecs = NULL;
 
     qemu_mutex_destroy(&mutex_clilist);
-    qemu_mutex_destroy(&mutex_guest_connection);
     qemu_mutex_destroy(&mutex_location_data);
 }
 
@@ -717,7 +715,6 @@ static void* ecs_initialize(void* args) {
     cs->ecs_running = 1;
 
     qemu_mutex_init(&mutex_clilist);
-    qemu_mutex_init(&mutex_guest_connection);
     qemu_mutex_init(&mutex_location_data);
 
     TRACE("ecs_loop entered.\n");
index 4b75568..ae3e923 100644 (file)
@@ -66,6 +66,8 @@
 #define MSG_TYPE_SDCARD         "sdcard"
 #define MSG_TYPE_GUEST          "guest"
 #define MSG_TYPE_GUESTIP        "guest_ip"
+#define MSG_TYPE_HDS            "hds"
+#define MSG_TYPE_PACKAGE        "package"
 
 #define MSG_GROUP_STATUS        15
 #define MSG_GROUP_HDS           100
@@ -187,7 +189,7 @@ bool ntf_to_injector(const char* data, const int len);
 bool ntf_to_control(const char* data, const int len);
 bool ntf_to_monitor(const char* data, const int len);
 
-bool send_msg_to_guest(ECS_Client* ccli, char* cmd, int group, int action,
+bool send_msg_to_guest(const char* cmd, int group, int action,
                        char* data, int data_len);
 
 void make_send_device_ntf (char* cmd, int group, int action, char* data);
index 0f8ffc5..3fdbd49 100644 (file)
@@ -153,7 +153,7 @@ void make_send_device_ntf (char* cmd, int group, int action, char* data)
     free(send_msg);
 }
 
-bool send_msg_to_guest(ECS_Client* ccli, char* cmd, int group, int action, char* data, int data_len)
+bool send_msg_to_guest(const char* cmd, int group, int action, char* data, int data_len)
 {
     int sndlen = 15; // HEADER(CMD + LENGTH + GROUP + ACTION) + 1
     char* sndbuf;
index 328d5a6..b14464b 100644 (file)
@@ -367,7 +367,7 @@ static void msgproc_device_req_hds(ECS_Client* ccli, ECS__DeviceReq* msg, char *
             do_hotplug(ATTACH_HDS, host, strlen(host) + 1);
             LOG_INFO("send emuld to mount: %s, %d.\n", guest, strlen(guest));
             set_emul_hds_guest_path(guest);
-            send_msg_to_guest(ccli, cmd, group, action, guest, strlen(guest) + 1);
+            send_msg_to_guest(cmd, group, action, guest, strlen(guest) + 1);
         } else {
             make_send_device_ntf(cmd, group, 2, NULL);
         }
@@ -380,7 +380,7 @@ static void msgproc_device_req_hds(ECS_Client* ccli, ECS__DeviceReq* msg, char *
                 guest_path = get_emul_hds_guest_path();
             }
             LOG_INFO("send emuld to umount.%s\n", guest_path);
-            send_msg_to_guest(ccli, cmd, group, action, guest_path, strlen(guest_path) + 1);
+            send_msg_to_guest(cmd, group, action, guest_path, strlen(guest_path) + 1);
         } else {
             LOG_INFO("hds is not attached. do not try detach it.\n");
             make_send_device_ntf(cmd, group, 4, NULL);
index d3859f4..b20adde 100644 (file)
@@ -27,6 +27,9 @@
  *
  */
 
+#include <string.h>
+#include <stdlib.h>
+
 #include "qemu-common.h"
 
 #include "hw/virtio/maru_virtio_vmodem.h"
 #include "debug_ch.h"
 #include "util/osutil.h"
 
+#include "skin/maruskin_client.h"
+
 MULTI_DEBUG_CHANNEL(qemu, ecs);
 
-extern QemuMutex mutex_guest_connection;
-static int guest_connection = 0;
+#define MAX_PKGS_LIST       1024
+#define MAX_SDB_TRIAL       10
+#define SLEEP_WAIT_SDB      500 // ms
+#define SLEEP_CONNECT_SDB   1000 // ms
+
+static QemuThread sdb_thread_id;
 
 extern QemuMutex mutex_location_data;
 static char location_data[MAX_INJECTOR_REQ_DATA];
@@ -503,11 +512,7 @@ static bool injector_req_sensor(ECS_Client* ccli, ECS__InjectorReq* msg, char *c
 
 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);
+    send_status_injector_ntf(MSG_TYPE_GUEST, 5, get_emuld_connection(), NULL);
     return true;
 }
 
@@ -563,12 +568,191 @@ void ecs_suspend_lock_state(int state)
 }
 
 #define MSG_GROUP_HDS   100
-static bool injector_req_handle(char* cat, type_action action)
+static void do_hds(char* cat, type_action action)
 {
-    /*SD CARD msg process*/
-    if (!strcmp(cat, MSG_TYPE_SDCARD)) {
+    INFO("hds status is %d\n", action);
+    switch (action) {
+        case 1:
+            make_send_device_ntf(cat, MSG_GROUP_HDS, action, NULL);
+            break;
+        case 2:
+            do_hotplug(DETACH_HDS, NULL, 0);
+            make_send_device_ntf(cat, MSG_GROUP_HDS, action, NULL);
+            break;
+        case 3:
+            do_hotplug(DETACH_HDS, NULL, 0);
+            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;
+    }
+}
+
+static bool do_push_package(char* cmd)
+{
+    char buf[MAX_PKGS_LIST];
+    FILE* fp = popen(cmd, "r");
+    if (fp == NULL) {
+        LOG_SEVERE("Failed to popen push packages");
         return false;
-    } else if (!strcmp(cat, "suspend")) {
+    }
+
+    memset(buf, 0, sizeof(buf));
+    while(fgets(buf, sizeof(buf), fp) != NULL) {
+        LOG_INFO("[pkgs]%s", buf);
+        if (!strncmp(buf, "error", 5)){
+            pclose(fp);
+            return false;
+        }
+        memset(buf, 0, sizeof(buf));
+    }
+
+    pclose(fp);
+    return true;
+}
+
+static bool push_package(const char* data)
+{
+    int index = 0;
+    int ret = 0;
+    char cmd[MAX_PKGS_LIST];
+    char token[] = ", ";
+#ifndef CONFIG_WIN32
+    const char* sdb_path = "../../sdb";
+    const char* platform_path = "../../../platforms/";
+    const char* addon_path = "/emulator-images/add-ons/";
+#else
+    const char* sdb_path = "..\\..\\sdb.exe";
+    const char* platform_path = "..\\..\\..\\platforms\\";
+    const char* addon_path = "\\emulator-images\\add-ons\\";
+#endif
+    const char* bin_dir = get_bin_path();
+
+    memset(cmd, 0, sizeof(cmd));
+
+    char* addon = strtok((char*)data, token);
+
+    ret = sprintf(cmd, "%s%s -s emulator-%d push %s%s%s%s%s /opt/usr/apps/tmp/sdk_tools/%s 2>&1",
+            bin_dir, sdb_path, get_device_serial_number(),
+            bin_dir, platform_path, get_emul_profile(), addon_path, addon,
+            addon);
+    if (ret < 0) {
+        LOG_SEVERE("SDB push command is wrong: %s\n", cmd);
+        return false;
+    }
+
+    LOG_INFO("[pkgs] SDB push command: %s\n", cmd);
+
+    if (do_push_package(cmd)) {
+        LOG_INFO("[pkgs] SDB push SUCCESS\n");
+        return true;
+    }
+
+    /*
+     * FIXME: unnecessary sdb connection waiting sleep.
+     *        If SDB runs faster, it should be changed/removed.
+     */
+    while(!get_sdb_connection() && index != MAX_SDB_TRIAL) {
+        LOG_INFO("[pkgs] Waiting SDB connection...%d\n", index + 1);
+#ifdef CONFIG_WIN32
+        Sleep(SLEEP_WAIT_SDB);
+#else
+        usleep(SLEEP_WAIT_SDB * 1000);
+#endif
+        index++;
+    }
+
+    index = 0;
+#ifdef CONFIG_WIN32
+    Sleep(SLEEP_WAIT_SDB);
+#else
+    usleep(SLEEP_WAIT_SDB * 1000);
+#endif
+
+    while(index != MAX_SDB_TRIAL) {
+        if (do_push_package(cmd)) {
+            LOG_INFO("[pkgs] SDB push SUCCESS.\n");
+            return true;
+        }
+        LOG_INFO("[pkgs] Try to send package ...%d\n", index + 1);
+        index++;
+#ifdef CONFIG_WIN32
+        Sleep(SLEEP_CONNECT_SDB);
+#else
+        usleep(SLEEP_CONNECT_SDB * 1000);
+#endif
+    }
+
+    return false;
+}
+
+static void show_error_popup(char* data)
+{
+    char fail_msg[MAX_PKGS_LIST];
+    char token[] = ", ";
+    char* addon = strtok(data, token);
+
+    memset(fail_msg, 0, sizeof(fail_msg));
+    strcpy(fail_msg, "Extra package installation is failed.\n");
+    strcat(fail_msg, addon);
+    strcat(fail_msg, " must be installed MANUALLY!");
+
+    start_simple_client(fail_msg);
+}
+
+static void* push_pkgs_thread(void* args)
+{
+    char* pkg_data = strdup((char*)args);
+    char* data = strdup(pkg_data);
+    if (pkg_data == NULL || data == NULL) {
+        LOG_SEVERE("pkg data strdup is failed.\n");
+        return NULL;
+    }
+
+    if (!push_package(pkg_data)) {
+        LOG_SEVERE("file upload is failed. %s\n", data);
+        show_error_popup(data);
+        free(pkg_data);
+        free(data);
+        return NULL;
+    }
+
+    // request to install rpms
+    LOG_INFO("[pkgs] Request to install : %s\n", data);
+    send_msg_to_guest(MSG_TYPE_PACKAGE, 0, 2, data, strlen(data) + 1);
+
+    free(pkg_data);
+    free(data);
+
+    return NULL;
+}
+
+static void do_package(char* cat, type_action action, const char* data)
+{
+    if (action == 1) {
+        LOG_INFO("[pkgs] Already installed: %s\n", data);
+    } else if (action == 2) {
+        LOG_INFO("[pkgs] Needed to install: %s\n", data);
+        char pkgs[MAX_PKGS_LIST];
+        strcpy(pkgs, data);
+        qemu_thread_create(&sdb_thread_id, "sdb_push", push_pkgs_thread, (void*)pkgs, QEMU_THREAD_DETACHED);
+    } else if (action == 3) {
+        LOG_INFO("[pkgs] Package Installation Success: %s\n", data);
+    } else if (action == 4) {
+        LOG_INFO("[pkgs] Package Installation Failed: %s\n", data);
+        show_error_popup((char*)data);
+    } else {
+        LOG_SEVERE("unknown pkgs action: %d\n", action);
+    }
+}
+
+static bool injector_req_handle(char* cat, type_action action, const char* data)
+{
+    if (!strcmp(cat, "suspend")) {
         ecs_suspend_lock_state(ecs_get_suspend_state());
         return true;
     } else if (!strcmp(cat, "boot")) {
@@ -577,39 +761,12 @@ static bool injector_req_handle(char* cat, type_action action)
         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;
-        set_emuld_condition(guest_connection);
-        if (action == 1) {
-            LOG_INFO("emulator booting done.\n");
-            set_emulator_condition(BOOT_COMPLETED);
-        } else {
-            LOG_INFO("emulator closed.\n");
-            set_emulator_condition(RESET);
-        }
-        qemu_mutex_unlock(&mutex_guest_connection);
-        return false;
+        set_emuld_connection(action);
     } 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:
-                do_hotplug(DETACH_HDS, NULL, 0);
-                make_send_device_ntf(cat, MSG_GROUP_HDS, action, NULL);
-                break;
-            case 3:
-                do_hotplug(DETACH_HDS, NULL, 0);
-                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;
-        }
+        do_hds(cat, action);
+        return true;
+    } else if (!strcmp(cat, MSG_TYPE_PACKAGE)) {
+        do_package(cat, action, data);
         return true;
     }
 
@@ -631,12 +788,12 @@ bool send_injector_ntf(const char* data, const int len)
     read_val_char(data + catsize + 2, &group);
     read_val_char(data + catsize + 2 + 1, &action);
 
-    if (injector_req_handle(cat, action)) {
+    const char* ijdata = (data + catsize + 2 + 1 + 1);
+
+    if (injector_req_handle(cat, action, ijdata)) {
         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);
     if (!strcmp(cat, MSG_TYPE_GUESTIP)) {
         if (length > 0) {
index 0cdc109..1d9e4c6 100644 (file)
@@ -321,15 +321,6 @@ MultiTouchState *get_emul_multi_touch_state(void)
     return &(_emul_state.qemu_mts);
 }
 
-void set_emuld_condition(int condition)
-{
-   _emul_state.emuld_condition = condition;
-}
-
-int get_emuld_condition(void)
-{
-    return _emul_state.emuld_condition;
-}
 /* retrieves the status of the host lock key */
 int get_host_lock_key_state(int key)
 {
@@ -434,3 +425,35 @@ char* get_emul_hds_guest_path(void)
     return _emul_state.hds_guest_path;
 }
 
+void set_emul_profile(const char *profile)
+{
+    LOG_INFO("EMULATOR_PROFILE: %s\n", profile);
+    strncpy(_emul_state.emulator_profile, profile, sizeof(_emul_state.emulator_profile));
+    _emul_state.emulator_profile[sizeof(_emul_state.emulator_profile) -1] = 0;
+}
+
+char* get_emul_profile(void)
+{
+    return _emul_state.emulator_profile;
+}
+
+void set_emuld_connection(bool connected)
+{
+    _emul_state.emuld_connection = connected;
+}
+
+bool get_emuld_connection(void)
+{
+    return _emul_state.emuld_connection;
+}
+
+void set_sdb_connection(bool connected)
+{
+    _emul_state.sdb_connection = connected;
+}
+
+bool get_sdb_connection(void)
+{
+    return _emul_state.sdb_connection;
+}
+
index d9956eb..904f269 100644 (file)
@@ -39,6 +39,7 @@
 #define SUPPORT_LEGACY_ARGS
 
 #define MAX_HDS_PATH    256
+#define MAX_PROFILE     256
 
 enum {
     RESET = 0,
@@ -85,11 +86,6 @@ enum {
     HOST_NUMLOCK_KEY = 2,
 };
 
-enum {
-    EMULD_NOT_RUNNING = 0,
-    EMULD_RUNNING = 1,
-};
-
 typedef  struct EmulatorConfigInfo {
     bool skin_enable;
     int resolution_w;
@@ -123,6 +119,9 @@ typedef struct EmulatorConfigState {
     bool hds_attached;
     char hds_path[MAX_HDS_PATH];
     char hds_guest_path[MAX_HDS_PATH];
+    char emulator_profile[MAX_PROFILE];
+    bool emuld_connection;
+    bool sdb_connection;
 } EmulatorConfigState;
 
 /* misc */
@@ -156,6 +155,9 @@ void set_emul_tap_enable(bool enable);
 void set_emul_hds_attached(bool attached);
 void set_emul_hds_path(const char *path);
 void set_emul_hds_guest_path(const char *path);
+void set_emul_profile(const char *profile);
+void set_emuld_connection(bool connected);
+void set_sdb_connection(bool connected);
 
 /* getter */
 bool get_emul_skin_enable(void);
@@ -181,13 +183,14 @@ int get_host_lock_key_state(int key);
 int get_host_lock_key_state_darwin(int key);
 int get_emul_caps_lock_state(void);
 int get_emul_num_lock_state(void);
-int get_emuld_condition(void);
-void set_emuld_condition(int condition);
 char* get_emul_guest_ip(void);
 bool is_emul_tap_enable(void);
 
 bool get_emul_hds_attached(void);
 char* get_emul_hds_path(void);
 char* get_emul_hds_guest_path(void);
+char* get_emul_profile(void);
+bool get_emuld_connection(void);
+bool get_sdb_connection(void);
 
 #endif /* __EMUL_STATE_H__ */
index 7e7a417..10afe9e 100644 (file)
@@ -31,7 +31,9 @@
 #include "hw/maru_device_ids.h"
 #include "maru_virtio_evdi.h"
 #include "debug_ch.h"
+#include "emul_state.h"
 #include "ecs/ecs.h"
+#include "util/extra_pkgs_install.h"
 
 MULTI_DEBUG_CHANNEL(qemu, evdi);
 
@@ -89,7 +91,6 @@ bool send_to_evdi(const uint32_t route, char* data, const uint32_t len)
 
     if (unlikely(!virtio_queue_ready(vio_evdi->rvq))) {
         ERR("virtio queue is not ready\n");
-        return false;
     }
 
     while (left > 0)
@@ -126,6 +127,11 @@ static void flush_evdi_recv_queue(void)
 {
     int index;
 
+    if (!get_emuld_connection()) {
+        INFO("emuld is not ready.\n");
+        return;
+    }
+
     if (unlikely(!virtio_queue_ready(vio_evdi->rvq))) {
         INFO("virtio queue is not ready\n");
         return;
@@ -240,6 +246,10 @@ static void virtio_evdi_realize(DeviceState *dev, Error **errp)
 
     vio_evdi->bh = qemu_bh_new(maru_evdi_bh, vio_evdi);
 
+    if (vio_evdi->profile) {
+        set_emul_profile(vio_evdi->profile);
+        epi_init();
+    }
 }
 
 static void virtio_evdi_unrealize(DeviceState *dev, Error **errp)
@@ -260,10 +270,16 @@ static void virtio_evdi_reset(VirtIODevice *vdev)
     TRACE("virtio_evdi_reset.\n");
 }
 
+static Property virtio_evdi_properties[] = {
+    DEFINE_PROP_STRING(ATTRIBUTE_NAME_EVDI, VirtIOEVDI, profile),
+    DEFINE_PROP_END_OF_LIST(),
+};
 
 static void virtio_evdi_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+    dc->props = virtio_evdi_properties;
     vdc->realize = virtio_evdi_realize;
     vdc->unrealize = virtio_evdi_unrealize;
     vdc->get_features = virtio_evdi_get_features;
index a8c5fa0..9b8ccb6 100644 (file)
@@ -16,27 +16,29 @@ extern "C" {
 
 /* device protocol */
 
-#define __MAX_BUF_SIZE 1024
+#define __MAX_BUF_SIZE  1024
+
+#define ATTRIBUTE_NAME_EVDI "profile"
 
 enum
 {
-       route_qemu = 0,
-       route_control_server = 1,
-       route_monitor = 2,
-       route_ij = 3
+    route_qemu = 0,
+    route_control_server = 1,
+    route_monitor = 2,
+    route_ij = 3
 };
 
 typedef unsigned int CSCliSN;
 
 typedef struct msg_info {
-       char buf[__MAX_BUF_SIZE];
+    char buf[__MAX_BUF_SIZE];
 
-       uint32_t route;
-       uint32_t use;
-       uint16_t count;
-       uint16_t index;
+    uint32_t route;
+    uint32_t use;
+    uint16_t count;
+    uint16_t index;
 
-       CSCliSN cclisn;
+    CSCliSN cclisn;
 }msg_info;
 
 /* device protocol */
@@ -44,13 +46,13 @@ typedef struct msg_info {
 typedef struct VirtIOEVDI{
     VirtIODevice    vdev;
     VirtQueue       *rvq;
-    VirtQueue          *svq;
+    VirtQueue       *svq;
     DeviceState     *qdev;
 
     QEMUBH *bh;
-} VirtIOEVDI;
-
 
+    char            *profile;
+} VirtIOEVDI;
 
 #define TYPE_VIRTIO_EVDI "virtio-evdi-device"
 #define VIRTIO_EVDI(obj) \
index 118a976..614757f 100644 (file)
@@ -347,6 +347,12 @@ static TypeInfo virtio_hwkey_pci_info = {
 
 /* virtio-evdi-pci */
 
+static Property virtio_evdi_pci_properties[] = {
+    DEFINE_PROP_STRING(ATTRIBUTE_NAME_EVDI, VirtIOEVDIPCI, vdev.profile),
+    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static int virtio_evdi_pci_init(VirtIOPCIProxy *vpci_dev)
 {
     VirtIOEVDIPCI *dev = VIRTIO_EVDI_PCI(vpci_dev);
@@ -361,7 +367,7 @@ static int virtio_evdi_pci_init(VirtIOPCIProxy *vpci_dev)
 
 static void virtio_evdi_pci_class_init(ObjectClass *klass, void *data)
 {
-//    DeviceClass *dc = DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
     VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
     PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
 
@@ -370,6 +376,7 @@ static void virtio_evdi_pci_class_init(ObjectClass *klass, void *data)
     pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_EVDI;
     pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
     pcidev_k->class_id = PCI_CLASS_OTHERS;
+    dc->props = virtio_evdi_pci_properties;
 }
 
 static void virtio_evdi_pci_instance_init(Object *obj)
index b3503eb..e9b3de0 100644 (file)
@@ -23,4 +23,7 @@ obj-y += maru_err_table.o
 # debug channel
 obj-y += new_debug_ch.o
 
+# extra packages installation
+obj-y += extra_pkgs_install.o
+
 $(obj)/osutil.o: QEMU_CFLAGS += $(CURL_CFLAGS)
diff --git a/tizen/src/util/extra_pkgs_install.c b/tizen/src/util/extra_pkgs_install.c
new file mode 100644 (file)
index 0000000..8b6923c
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Emulator Extra Package Installation Utility
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Jinhyung choi   <jinhyung2.choi@samsung.com>
+ *  Sangho Park     <sangho1206.park@samsung.com>
+ *  YeongKyoon Lee  <yeongkyoon.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+#include "qemu-common.h"
+#include "qemu/queue.h"
+
+#include "hw/virtio/maru_virtio_evdi.h"
+
+#include "extra_pkgs_install.h"
+#include "emul_state.h"
+#include "debug_ch.h"
+
+MULTI_DEBUG_CHANNEL(qemu, pkgs);
+
+// FIXME: getting add-on path
+static char* get_addon_path(void)
+{
+#ifndef CONFIG_WIN32
+    const char *parent = "../../../";
+    const char *separator = "/";
+#else
+    const char *parent = "..\\..\\..\\";
+    const char *separator = "\\";
+#endif
+
+    int ret = 0;
+    char* extra_path = (char*)malloc(MAX_PKG_LIST);
+    if (!extra_path) {
+        LOG_SEVERE("cannot alloc extra_path.\n");
+        return NULL;
+    }
+
+    ret = sprintf(extra_path, "%s%s%s%s%s%s%s%s%s",
+            get_bin_path(), parent, PLATFORM_DIRECTORY,
+            separator, get_emul_profile(), separator,
+            IMAGE_DIRECTORY, separator, ADDON_DIRECTORY);
+    if (ret < 0) {
+        LOG_SEVERE("ADDON PATH composition is failed.\n");
+    }
+
+    LOG_INFO("ADDON PATH: %s\n", extra_path);
+
+    return extra_path;
+}
+
+static void add_addon_pkgs_name(char *pkgs, char* name)
+{
+    if (strlen(pkgs) == 0) {
+        strcpy(pkgs, name);
+    } else {
+        sprintf(pkgs, "%s, %s", pkgs, name);
+    }
+}
+
+static void send_to_emuld(char* addon, char* pkgs)
+{
+    int ret = 0;
+    int data_len = 0;
+    int action = 1;
+    char data[MAX_PKG_LIST + MAX_PATH_PKG_LIST];
+
+    memset(data, 0, sizeof(data));
+    sprintf(data, "%s, %s", addon, pkgs);
+
+    data_len = strlen(data) + 1;
+    int sndlen = 14 + data_len;
+    char *sndbuf = (char*) g_malloc0(sndlen);
+    if (!sndbuf) {
+        LOG_SEVERE("Failed to alloc emuld message\n");
+        return;
+    }
+
+    memcpy(sndbuf, CMD_PKG, 7);
+    memcpy(sndbuf + 10, &data_len, 2);
+    memcpy(sndbuf + 13, &action, 1);
+    memcpy(sndbuf + 14, data, data_len);
+
+    LOG_TRACE("sndbuf data: %s\n", sndbuf + 14);
+
+    ret = send_to_evdi(route_ij, sndbuf, sndlen);
+    if (ret < 0) {
+        LOG_SEVERE("Failed to send emuld message\n");
+    }
+}
+
+void epi_init(void)
+{
+    int pkg_count = 0;
+    char sub_addon_path[512];
+    DIR *main_dir = NULL;
+    DIR *sub_dir = NULL;
+    struct dirent *dir_entry = NULL;
+    struct dirent *sub_dir_entry = NULL;
+    char addon[MAX_PATH_PKG_LIST];
+    char pkgs[MAX_PKG_LIST];
+    char* addon_path = get_addon_path();
+
+    if (!addon_path) {
+        return;
+    }
+
+    main_dir = opendir(addon_path);
+    if (!main_dir) {
+        LOG_INFO("Add-on Directory is empty. No package install is required.\n");
+        return;
+    }
+
+    while ((dir_entry = readdir(main_dir))) {
+        if ((strncasecmp(dir_entry->d_name ,".", 1) != 0) &&
+            (strncasecmp(dir_entry->d_name ,"..", 2) != 0)) {
+            LOG_TRACE("reading addon directory: %s\n", dir_entry->d_name);
+
+            memset(sub_addon_path, 0, 512);
+            memset(addon, 0, sizeof(addon));
+            memset(pkgs, 0, sizeof(pkgs));
+
+            strcpy(addon, dir_entry->d_name);
+
+#ifndef CONFIG_WIN32
+            sprintf(sub_addon_path, "%s/%s", addon_path, dir_entry->d_name);
+#else
+            sprintf(sub_addon_path, "%s\\%s", addon_path, dir_entry->d_name);
+#endif
+            sub_dir = opendir(sub_addon_path);
+            if (!sub_dir) {
+                LOG_SEVERE("Add-on sub Directory open failed.");
+                continue;
+            }
+            while((sub_dir_entry = readdir(sub_dir))) {
+                if ((strncasecmp(sub_dir_entry->d_name ,".", 1) != 0) &&
+                    (strncasecmp(sub_dir_entry->d_name ,"..", 2) != 0)) {
+                    pkg_count++;
+                    add_addon_pkgs_name(pkgs, sub_dir_entry->d_name);
+                    LOG_TRACE("reading addon sub directory: %s\n", sub_dir_entry->d_name);
+                }
+            }
+
+            LOG_INFO("pkgs: %s, %s\n", addon, pkgs);
+
+            if (pkg_count == 0) {
+                LOG_INFO("pkgs addon %s is empty. skip!\n", addon);
+            } else {
+                // send to emuld
+                send_to_emuld(addon, pkgs);
+            }
+
+            closedir(sub_dir);
+            pkg_count = 0;
+        }
+    }
+
+    closedir(main_dir);
+}
diff --git a/tizen/src/util/extra_pkgs_install.h b/tizen/src/util/extra_pkgs_install.h
new file mode 100644 (file)
index 0000000..7000ae6
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Emulator Extra Package Installation Utility
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Jinhyung choi   <jinhyung2.choi@samsung.com>
+ *  Sangho Park     <sangho1206.park@samsung.com>
+ *  YeongKyoon Lee  <yeongkyoon.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+
+#ifndef _EXTRA_PKGS_INSTALL_
+#define _EXTRA_PKGS_INSTALL_
+
+#define PLATFORM_DIRECTORY  "platforms"
+#define IMAGE_DIRECTORY     "emulator-images"
+#define ADDON_DIRECTORY     "add-ons"
+
+#define CMD_PKG             "package"
+
+#define MAX_PKG_LIST        1024
+#define MAX_PATH_PKG_LIST   256
+
+void epi_init(void);
+
+#endif // _EXTRA_PKGS_INSTALL_
index b5c4d36..38ea12d 100644 (file)
@@ -470,6 +470,7 @@ static void command_handler(char* readbuf, struct sockaddr_in* client_addr)
         notify_sdb_daemon_start();
     } else if (strcmp(command, "5\n") == 0) {
         register_sdb_server(readbuf, client_addr);
+        set_sdb_connection(true);
     } else if (strcmp(command, "6\n") == 0) {
         wakeup_guest();
     } else if (strcmp(command, "7\n") == 0) {