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
--- /dev/null
-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
#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"
ntf.data.len = length;
memcpy(ntf.data.data, ijdata, length);
- TRACE("data = %s, length = %hu\n", ijdata, length);
+ LOG_TRACE("data = %s, length = %hu\n", ijdata, length);
}
- master.type = ECS__MASTER__TYPE__TETHERING_NTF;
- master.tethering_ntf = &ntf;
+ master.type = ECS__MASTER__TYPE__EVENTCAST_NTF;
+ master.eventcast_ntf = &ntf;
- send_to_ecp(&master);
+ pb_to_all_clients(&master);
if (ntf.data.data && ntf.data.len > 0) {
g_free(ntf.data.data);
#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)
{
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;
-}
--
--- /dev/null
- #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;
+}
+
--- /dev/null
- #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;
+}
+
--- /dev/null
- #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;
+}
+
+
#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,
ERR("[%d] failed to allocate context.\n", __LINE__);
ret = -1;
} else {
- #if 0
- avcodec_get_context_defaults3(avctx, NULL);
+ 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->rc_strategy = 2;
- avctx->b_frame_strategy = 0;
- avctx->coder_type = 0;
- avctx->context_model = 0;
- avctx->scenechange_threshold = 0;
+ avctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
- avctx->gop_size = DEFAULT_VIDEO_GOP_SIZE;
- avctx->lmin = (2 * FF_QP2LAMBDA + 0.5);
- avctx->lmax = (31 * FF_QP2LAMBDA + 0.5);
- #endif
+ INFO("aac encoder!! channels %d channel_layout %lld\n",
+ avctx->channels, avctx->channel_layout);
+ avctx->channel_layout = av_get_default_channel_layout(avctx->channels);
+ }
- codec = maru_brill_codec_find_avcodec(elem->buf);
- if (codec) {
- size = sizeof(int32_t) + 32; // buffer size of codec_name
- read_codec_init_data(avctx, elem->buf + size);
+ 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);
}
}
- maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id);
+ maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id, NULL);
- if (audio_out) {
- avcodec_free_frame(&audio_out);
+ if (resample_frame) {
+ TRACE("release decoded frame\n");
+ av_free(resample_buf);
+ av_free(resample_frame);
}
- if (out_buf) {
- TRACE("and release decoded_audio buffer\n");
- av_free(out_buf);
++ if (audio_out) {
++ avcodec_free_frame(&audio_out);
+ }
+
-
TRACE("leave: %s\n", __func__);
return true;
}
}
} else {
TRACE("encode_audio. no input buffer\n");
- // FIXME: improve error handling
- // return false;
}
- av_init_packet(&avpkt);
- // packet data will be allocated by encoder
- avpkt.data = NULL;
- avpkt.size = 0;
-
- avctx = s->context[ctx_id].avctx;
+ avctx = CONTEXT(s, ctx_id).avctx;
if (!avctx) {
- ERR("encode_audio. %d of context is NULL\n", ctx_id);
- ret = -1;
+ ERR("encode_audio. %d of Context is NULL\n", ctx_id);
} else if (!avctx->codec) {
- ERR("encode_audio. %d of codec is NULL\n", ctx_id);
- ret = -1;
+ 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");
--- /dev/null
+ /*
+ * 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;
++}
++
*
*/
- /**
- * @file guest_debug.h
- * @brief - header of file these are config structures and defines in emulator
- */
+ #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,
+ };
- #ifndef __GUEST_DEBUG_H__
- #define __GUEST_DEBUG_H__
+ void maru_device_hotplug_init(void);
- #include "exec/memory.h"
+ void do_hotplug(int command, void *opaque, size_t size);
- char *get_logpath(void);
- MemoryRegion *get_ram_memory(void);
+ bool is_host_keyboard_attached(void);
+ bool is_sdcard_attached(void);
++bool is_hds_attached(void);
- #endif /* __GUEST_DEBUG_H__ */
+ #endif // _MARU_DEVICE_HOTPLUG_H_
bool make_sdcard_lock_os(char *sdcard)
{
-- return make_sdcard_lock(sdcard);
++ return make_sdcard_lock_posix(sdcard);
}
int remove_sdcard_lock_os(char *sdcard)
{
-- return remove_sdcard_lock(sdcard);
++ return remove_sdcard_lock_posix(sdcard);
}
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 make_sdcard_lock(sdcard);
++ return make_sdcard_lock_posix(sdcard);
}
int remove_sdcard_lock_os(char *sdcard)
{
-- return remove_sdcard_lock(sdcard);
++ return remove_sdcard_lock_posix(sdcard);
}
return fcntl(fd, F_SETLK, &lock);
}
--inline bool make_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);
}
--inline int remove_sdcard_lock(char *sdcard)
++inline int remove_sdcard_lock_posix(char *sdcard)
{
errno = 0;
char *lock_file = g_strdup_printf("%s.lck", sdcard);
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(char *sdcard);
--int remove_sdcard_lock(char *sdcard);
++bool make_sdcard_lock_posix(char *sdcard);
++int remove_sdcard_lock_posix(char *sdcard);
#endif
- void set_bin_path_os(gchar *);
void print_system_info_os(void);