-/*
- * Emulator
- *
- * Copyright (C) 2011, 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact:
- * SeokYeon Hwang <syeon.hwang@samsung.com>
- * HyunJun Son <hj79.son@samsung.com>
- * MunKyu Im <munkyu.im@samsung.com>
- * GiWoong Kim <giwoong.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 "maru_common.h"
-#include <stdlib.h>
-#ifdef CONFIG_SDL
-#include <SDL.h>
-#endif
-#include "emulator.h"
-#include "sdb.h"
-#include "string.h"
-#include "skin/maruskin_server.h"
-#include "skin/maruskin_client.h"
-#include "guest_server.h"
-#include "debug_ch.h"
-#include "option.h"
-#include "emul_state.h"
-#include "qemu_socket.h"
-#include "build_info.h"
-#include "maru_err_table.h"
-#include <glib.h>
-#include <glib/gstdio.h>
-
-#if defined(CONFIG_WIN32)
-#include <windows.h>
-#elif defined(CONFIG_LINUX)
-#include <linux/version.h>
-#include <sys/utsname.h>
-#include <sys/sysinfo.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#endif
-
-#include "mloop_event.h"
-
-MULTI_DEBUG_CHANNEL(qemu, main);
-
-
-#define IMAGE_PATH_PREFIX "file="
-#define IMAGE_PATH_SUFFIX ",if=virtio"
-#define SDB_PORT_PREFIX "sdb_port="
-#define LOGS_SUFFIX "/logs/"
-#define LOGFILE "emulator.log"
-#define MIDBUF 128
-int tizen_base_port = 0;
-
-char tizen_target_path[MAXLEN] = {0, };
-char logpath[MAXLEN] = { 0, };
-
-static int skin_argc = 0;
-static char** skin_argv = NULL;
-static int qemu_argc = 0;
-static char** qemu_argv = NULL;
-
-extern void maru_display_fini(void);
-void exit_emulator(void)
-{
- mloop_ev_stop();
- shutdown_skin_server();
- shutdown_guest_server();
-
- maru_display_fini();
-}
-
-static int check_port_bind_listen(u_int port)
-{
- struct sockaddr_in addr;
- int s, opt = 1;
- int ret = -1;
- socklen_t addrlen = sizeof(addr);
- memset(&addr, 0, addrlen);
-
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
- addr.sin_port = htons(port);
-
- if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) ||
- (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) ||
- (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
- (listen(s,1) < 0)) {
-
- /* fail */
- ret = -1;
- ERR( "check port(%d) bind listen fail \n", port);
- }else{
- /*fsucess*/
- ret = 1;
- INFO( "check port(%d) bind listen ok \n", port);
- }
-
-#ifdef CONFIG_WIN32
- closesocket(s);
-#else
- close(s);
-#endif
-
- return ret;
-}
-
-
-void check_shdmem(void)
-{
-#if defined(CONFIG_LINUX)
- int shm_id;
- void *shm_addr;
- u_int port;
- int val;
- struct shmid_ds shm_info;
-
- for(port=26100;port < 26200; port += 10)
- {
- if ( -1 != ( shm_id = shmget( (key_t)port, 0, 0)))
- {
- if((void *)-1 == (shm_addr = shmat(shm_id, (void *)0, 0)))
- {
- ERR( "error occured at shmat()\n");
- break;
- }
-
- val = shmctl(shm_id, IPC_STAT, &shm_info);
- if(val != -1)
- {
- INFO( "count of process that use shared memory : %d\n", shm_info.shm_nattch);
- if(shm_info.shm_nattch > 0 && strcmp(tizen_target_path, (char*)shm_addr) == 0)
- {
- if(check_port_bind_listen(port+1) > 0){
- shmdt(shm_addr);
- continue;
- }
- shmdt(shm_addr);
- maru_register_exit_msg(MARU_EXIT_UNKNOWN, (char*)"Can not execute this VM.\nThe same name is running now.");
- exit(0);
- }
- else{
- shmdt(shm_addr);
- }
- }
- }
- }
-
-#elif defined(CONFIG_WIN32)
- u_int port;
- char* base_port = NULL;
- char* pBuf;
- HANDLE hMapFile;
- for(port=26100;port < 26200; port += 10)
- {
- base_port = g_strdup_printf("%d", port);
- hMapFile = OpenFileMapping(
- FILE_MAP_READ,
- TRUE,
- base_port);
- if(hMapFile == NULL)
- {
- INFO("port %s is not used.\n", base_port);
- continue;
- }
- else
- {
- pBuf = (char*)MapViewOfFile(hMapFile,
- FILE_MAP_READ,
- 0,
- 0,
- 50);
- if (pBuf == NULL)
- {
- ERR("Could not map view of file (%d).\n", GetLastError());
- CloseHandle(hMapFile);
- return -1;
- }
-
- if(strcmp(pBuf, tizen_target_path) == 0)
- {
- if(check_port_bind_listen(port+1) > 0)
- {
- UnmapViewOfFile(pBuf);
- CloseHandle(hMapFile);
- continue;
- }
-
- maru_register_exit_msg(MARU_EXIT_UNKNOWN, "Can not execute this VM.\nThe same name is running now.");
- UnmapViewOfFile(pBuf);
- CloseHandle(hMapFile);
- free(base_port);
- exit(0);
- }
- else
- UnmapViewOfFile(pBuf);
- }
-
- CloseHandle(hMapFile);
- free(base_port);
- }
-#elif defined(CONFIG_DARWIN)
- //TODO:
-#endif
-}
-
-void make_shdmem(void)
-{
-#if defined(CONFIG_LINUX)
- int shmid;
- char *shared_memory;
- shmid = shmget((key_t)tizen_base_port, MAXLEN, 0666|IPC_CREAT);
- if (shmid == -1)
- {
- ERR("shmget failed\n");
- return;
- }
- shared_memory = shmat(shmid, (char*)0x00, 0);
- if (shared_memory == (void *)-1)
- {
- ERR("shmat failed\n");
- return;
- }
- sprintf(shared_memory, "%s", tizen_target_path);
- INFO( "shared memory key: %d value: %s\n", tizen_base_port, (char*)shared_memory);
-#elif defined(CONFIG_WIN32)
- HANDLE hMapFile;
- char* pBuf;
- char* port_in_use;
- char *shared_memory;
- shared_memory = g_strdup_printf("%s", tizen_target_path);
- port_in_use = g_strdup_printf("%d", tizen_base_port);
- hMapFile = CreateFileMapping(
- INVALID_HANDLE_VALUE, // use paging file
- NULL, // default security
- PAGE_READWRITE, // read/write access
- 0, // maximum object size (high-order DWORD)
- 50, // maximum object size (low-order DWORD)
- port_in_use); // name of mapping object
- if (hMapFile == NULL)
- {
- ERR("Could not create file mapping object (%d).\n", GetLastError());
- return;
- }
- pBuf = MapViewOfFile(hMapFile, // handle to map object
- FILE_MAP_ALL_ACCESS, // read/write permission
- 0,
- 0,
- 50);
-
- if (pBuf == NULL)
- {
- ERR("Could not map view of file (%d).\n", GetLastError());
- CloseHandle(hMapFile);
- return;
- }
-
- CopyMemory((PVOID)pBuf, shared_memory, strlen(shared_memory));
- free(port_in_use);
- free(shared_memory);
-#elif defined(CONFIG_DARWIN)
- //TODO:
-#endif
- return;
-}
-
-
-
-static void construct_main_window(int skin_argc, char* skin_argv[], int qemu_argc, char* qemu_argv[] )
-{
- INFO("construct main window\n");
-
- start_skin_server( skin_argc, skin_argv, qemu_argc, qemu_argv );
-
- if (get_emul_skin_enable() == 1) { //this line is check for debugging, etc..
- if ( 0 > start_skin_client(skin_argc, skin_argv) ) {
- maru_register_exit_msg(MARU_EXIT_SKIN_SERVER_FAILED, NULL);
- exit( -1 );
- }
- }
-
- set_emul_caps_lock_state(0);
- set_emul_num_lock_state(0);
-}
-
-static void parse_options(int argc, char* argv[], int* skin_argc, char*** skin_argv, int* qemu_argc, char*** qemu_argv)
-{
- int i;
- int j;
-
-// FIXME !!!
-// TODO:
-
- for(i = 1; i < argc; ++i)
- {
- if(strncmp(argv[i], "--skin-args", 11) == 0)
- {
- *skin_argv = &(argv[i + 1]);
- break;
- }
- }
- for(j = i; j < argc; ++j)
- {
- if(strncmp(argv[j], "--qemu-args", 11) == 0)
- {
- *skin_argc = j - i - 1;
-
- *qemu_argc = argc - j - i + 1;
- *qemu_argv = &(argv[j]);
-
- argv[j] = argv[0];
- }
- }
-}
-
-static void get_bin_dir( char* exec_argv ) {
-
- if ( !exec_argv ) {
- return;
- }
-
- char* data = strdup( exec_argv );
- if ( !data ) {
- fprintf( stderr, "Fail to strdup for paring a binary directory.\n" );
- return;
- }
-
- char* p = NULL;
-#ifdef _WIN32
- p = strrchr( data, '\\' );
- if ( !p ) {
- p = strrchr( data, '/' );
- }
-#else
- p = strrchr( data, '/' );
-#endif
- if ( !p ) {
- free( data );
- return;
- }
-
- strncpy( bin_dir, data, strlen( data ) - strlen( p ) );
-
- free( data );
-
-}
-
-void set_image_and_log_path(char* qemu_argv)
-{
- int i;
- int j = 0;
- int name_len = 0;
- int prefix_len = 0;
- int suffix_len = 0;
- int max = 0;
- char *path = malloc(MAXLEN);
- name_len = strlen(qemu_argv);
- prefix_len = strlen(IMAGE_PATH_PREFIX);
- suffix_len = strlen(IMAGE_PATH_SUFFIX);
- max = name_len - suffix_len;
- for(i = prefix_len , j = 0; i < max; i++)
- {
- path[j++] = qemu_argv[i];
- }
- path[j] = '\0';
- if(!g_path_is_absolute(path))
- strcpy(tizen_target_path, g_get_current_dir());
- else
- strcpy(tizen_target_path, g_path_get_dirname(path));
-
- strcpy(logpath, tizen_target_path);
- strcat(logpath, LOGS_SUFFIX);
-#ifdef CONFIG_WIN32
- if(access(g_win32_locale_filename_from_utf8(logpath), R_OK) != 0) {
- g_mkdir(g_win32_locale_filename_from_utf8(logpath), 0755);
- }
-#else
- if(access(logpath, R_OK) != 0) {
- g_mkdir(logpath, 0755);
- }
-#endif
- strcat(logpath, LOGFILE);
- set_log_path(logpath);
-}
-
-void redir_output(void)
-{
- FILE *fp;
-
- fp = freopen(logpath, "a+", stdout);
- if(fp ==NULL)
- fprintf(stderr, "log file open error\n");
- fp = freopen(logpath, "a+", stderr);
- if(fp ==NULL)
- fprintf(stderr, "log file open error\n");
-
- setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
- setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
-}
-
-void extract_info(int qemu_argc, char** qemu_argv)
-{
- int i;
-
- for(i = 0; i < qemu_argc; ++i)
- {
- if(strstr(qemu_argv[i], IMAGE_PATH_PREFIX) != NULL) {
- set_image_and_log_path(qemu_argv[i]);
- break;
- }
- }
-
- tizen_base_port = get_sdb_base_port();
-}
-
-static void system_info(void)
-{
-#define DIV 1024
-
- char timeinfo[64] = {0, };
- struct tm *tm_time;
- struct timeval tval;
-
- INFO("* SDK Version : %s\n", build_version);
- INFO("* Package %s\n", pkginfo_version);
- INFO("* User name : %s\n", g_get_real_name());
- INFO("* Host name : %s\n", g_get_host_name());
-
- /* timestamp */
- INFO("* Build date : %s\n", build_date);
- gettimeofday(&tval, NULL);
- tm_time = localtime(&(tval.tv_sec));
- strftime(timeinfo, sizeof(timeinfo), "%Y/%m/%d %H:%M:%S", tm_time);
- INFO("* Current time : %s\n", timeinfo);
-
-#ifdef CONFIG_SDL
- /* Gets the version of the dynamically linked SDL library */
- INFO("* Host sdl version : (%d, %d, %d)\n",
- SDL_Linked_Version()->major, SDL_Linked_Version()->minor, SDL_Linked_Version()->patch);
-#endif
-
-#if defined(CONFIG_WIN32)
- /* Retrieves information about the current os */
- OSVERSIONINFO osvi;
- ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-
- if (GetVersionEx(&osvi)) {
- INFO("* MajorVersion : %d, MinorVersion : %d, BuildNumber : %d, PlatformId : %d, CSDVersion : %s\n",
- osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber, osvi.dwPlatformId, osvi.szCSDVersion);
- }
-
- /* Retrieves information about the current system */
- SYSTEM_INFO sysi;
- ZeroMemory(&sysi, sizeof(SYSTEM_INFO));
-
- GetSystemInfo(&sysi);
- INFO("* Processor type : %d, Number of processors : %d\n", sysi.dwProcessorType, sysi.dwNumberOfProcessors);
-
- MEMORYSTATUSEX memInfo;
- memInfo.dwLength = sizeof(MEMORYSTATUSEX);
- GlobalMemoryStatusEx(&memInfo);
- INFO("* Total Ram : %llu kB, Free: %lld kB\n",
- memInfo.ullTotalPhys / DIV, memInfo.ullAvailPhys / DIV);
-
-#elif defined(CONFIG_LINUX)
- /* depends on building */
- INFO("* Qemu build machine linux kernel version : (%d, %d, %d)\n",
- LINUX_VERSION_CODE >> 16, (LINUX_VERSION_CODE >> 8) & 0xff, LINUX_VERSION_CODE & 0xff);
-
- /* depends on launching */
- struct utsname host_uname_buf;
- if (uname(&host_uname_buf) == 0) {
- INFO("* Host machine uname : %s %s %s %s %s\n", host_uname_buf.sysname, host_uname_buf.nodename,
- host_uname_buf.release, host_uname_buf.version, host_uname_buf.machine);
- }
-
- struct sysinfo sys_info;
- if (sysinfo(&sys_info) == 0) {
- INFO("* Total Ram : %llu kB, Free: %llu kB\n",
- sys_info.totalram * (unsigned long long)sys_info.mem_unit / DIV,
- sys_info.freeram * (unsigned long long)sys_info.mem_unit / DIV);
- }
-
- /* pci device description */
- INFO("* Pci devices :\n");
- char lscmd[MAXLEN] = "lspci >> ";
- strcat(lscmd, logpath);
- int i = system(lscmd);
- INFO("system function command : %s, system function returned value : %d\n", lscmd, i);
-
-#elif defined(CONFIG_DARWIN)
- //TODO:
-#endif
-
- INFO("\n");
-}
-
-void prepare_maru(void)
-{
- INFO("Prepare maru specified feature\n");
-
- sdb_setup();
-
- INFO("call construct_main_window\n");
-
- construct_main_window(skin_argc, skin_argv, qemu_argc, qemu_argv);
-
- int guest_server_port = tizen_base_port + SDB_UDP_SENSOR_INDEX;
- start_guest_server( guest_server_port );
-
- mloop_ev_init();
-}
-
-int qemu_main(int argc, char** argv, char** envp);
-
-int main(int argc, char* argv[])
-{
- parse_options(argc, argv, &skin_argc, &skin_argv, &qemu_argc, &qemu_argv);
- get_bin_dir( qemu_argv[0] );
- socket_init();
- extract_info(qemu_argc, qemu_argv);
-
- INFO("Emulator start !!!\n");
-
- atexit(maru_atexit);
-
- check_shdmem();
- make_shdmem();
-
- system_info();
-
- INFO("Prepare running...\n");
- redir_output(); // Redirect stdout, stderr after debug_ch is initialized...
-
- int i;
-
- fprintf(stdout, "qemu args : ==========================================\n");
- for(i = 0; i < qemu_argc; ++i)
- {
- fprintf(stdout, "%s ", qemu_argv[i]);
- }
- fprintf(stdout, "\n");
- fprintf(stdout, "======================================================\n");
-
- fprintf(stdout, "skin args : ==========================================\n");
- for(i = 0; i < skin_argc; ++i)
- {
- fprintf(stdout, "%s ", skin_argv[i]);
- }
- fprintf(stdout, "\n");
- fprintf(stdout, "======================================================\n");
-
- INFO("qemu main start!\n");
- qemu_main(qemu_argc, qemu_argv, NULL);
-
- exit_emulator();
-
- return 0;
-}
-
+/* \r
+ * Emulator\r
+ *\r
+ * Copyright (C) 2011, 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: \r
+ * SeokYeon Hwang <syeon.hwang@samsung.com>\r
+ * HyunJun Son <hj79.son@samsung.com>\r
+ * MunKyu Im <munkyu.im@samsung.com>\r
+ * GiWoong Kim <giwoong.kim@samsung.com>\r
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+\r
+\r
+#include <stdlib.h>\r
+#include <SDL.h>\r
+#include "maru_common.h"\r
+#include "emulator.h"\r
+#include "sdb.h"\r
+#include "string.h"\r
+#include "skin/maruskin_server.h"\r
+#include "skin/maruskin_client.h"\r
+#include "guest_server.h"\r
+#include "debug_ch.h"\r
+#include "option.h"\r
+#include "emul_state.h"\r
+#include "qemu_socket.h"\r
+#include "build_info.h"\r
+#include "maru_err_table.h"\r
+#include <glib.h>\r
+#include <glib/gstdio.h>\r
+\r
+#if defined( _WIN32)\r
+#include <windows.h>\r
+#elif defined(__linux__)\r
+#include <linux/version.h>\r
+#include <sys/utsname.h>\r
+#include <sys/sysinfo.h>\r
+#include <sys/ipc.h> \r
+#include <sys/shm.h>\r
+\r
+#endif\r
+\r
+#include "mloop_event.h"\r
+\r
+MULTI_DEBUG_CHANNEL(qemu, main);\r
+\r
+\r
+#define IMAGE_PATH_PREFIX "file="\r
+#define IMAGE_PATH_SUFFIX ",if=virtio"\r
+#define SDB_PORT_PREFIX "sdb_port="\r
+#define LOGS_SUFFIX "/logs/"\r
+#define LOGFILE "emulator.log"\r
+#define MIDBUF 128\r
+int tizen_base_port = 0;\r
+static pthread_mutex_t event_mutex = PTHREAD_MUTEX_INITIALIZER;\r
+char tizen_target_path[MAXLEN] = {0, };\r
+char logpath[MAXLEN] = { 0, };\r
+\r
+static int skin_argc = 0;\r
+static char** skin_argv = NULL;\r
+static int qemu_argc = 0;\r
+static char** qemu_argv = NULL;\r
+\r
+extern void maruskin_sdl_quit(void);\r
+void exit_emulator(void)\r
+{\r
+ cleanup_multi_touch_state();\r
+\r
+ mloop_ev_stop();\r
+ shutdown_skin_server();\r
+ shutdown_guest_server();\r
+\r
+ maruskin_sdl_quit();\r
+}\r
+\r
+void check_shdmem(void)\r
+{\r
+#ifndef CONFIG_WIN32\r
+ int shm_id;\r
+ void *shm_addr;\r
+ u_int port;\r
+ int val;\r
+ struct shmid_ds shm_info;\r
+\r
+ for(port=26100;port < 26200; port += 10)\r
+ {\r
+ if ( -1 != ( shm_id = shmget( (key_t)port, 0, 0)))\r
+ {\r
+ if((void *)-1 == (shm_addr = shmat(shm_id, (void *)0, 0)))\r
+ {\r
+ ERR( "error occured at shmat()\n");\r
+ break;\r
+ }\r
+\r
+ val = shmctl(shm_id, IPC_STAT, &shm_info);\r
+ if(val != -1)\r
+ {\r
+ INFO( "count of process that use shared memory : %d\n", shm_info.shm_nattch);\r
+ if(shm_info.shm_nattch > 0 && strcmp(tizen_target_path, (char*)shm_addr) == 0)\r
+ {\r
+ if(check_port_bind_listen(port+1) > 0){\r
+ shmdt(shm_addr);\r
+ continue;\r
+ }\r
+ shmdt(shm_addr);\r
+ maru_register_exit_msg(MARU_EXIT_UNKNOWN, (char*)"Can not execute this VM.\nThe same name is running now.");\r
+ exit(0);\r
+ }\r
+ else{\r
+ shmdt(shm_addr);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+#else /* _WIN32*/\r
+ u_int port;\r
+ char* base_port = NULL;\r
+ char* pBuf;\r
+ HANDLE hMapFile;\r
+ for(port=26100;port < 26200; port += 10)\r
+ {\r
+ base_port = g_strdup_printf("%d", port);\r
+ hMapFile = OpenFileMapping(\r
+ FILE_MAP_READ,\r
+ TRUE,\r
+ base_port);\r
+ if(hMapFile == NULL)\r
+ {\r
+ INFO("port %s is not used.\n", base_port);\r
+ continue;\r
+ }\r
+ else\r
+ {\r
+ pBuf = (char*)MapViewOfFile(hMapFile,\r
+ FILE_MAP_READ,\r
+ 0,\r
+ 0,\r
+ 50);\r
+ if (pBuf == NULL)\r
+ {\r
+ ERR("Could not map view of file (%d).\n", GetLastError());\r
+ CloseHandle(hMapFile);\r
+ }\r
+\r
+ if(strcmp(pBuf, tizen_target_path) == 0)\r
+ {\r
+ /*\r
+ if(check_port_bind_listen(port+1) > 0)\r
+ {\r
+ UnmapViewOfFile(pBuf);\r
+ CloseHandle(hMapFile);\r
+ continue;\r
+ }\r
+ */\r
+ maru_register_exit_msg(MARU_EXIT_UNKNOWN, "Can not execute this VM.\nThe same name is running now.");\r
+ UnmapViewOfFile(pBuf);\r
+ CloseHandle(hMapFile);\r
+ free(base_port);\r
+ exit(0);\r
+ }\r
+ else\r
+ UnmapViewOfFile(pBuf);\r
+ }\r
+\r
+ CloseHandle(hMapFile);\r
+ free(base_port);\r
+ }\r
+#endif\r
+}\r
+\r
+void make_shdmem(void)\r
+{\r
+#ifndef _WIN32\r
+ int shmid; \r
+ char *shared_memory;\r
+ shmid = shmget((key_t)tizen_base_port, MAXLEN, 0666|IPC_CREAT); \r
+ if (shmid == -1) \r
+ { \r
+ ERR("shmget failed\n"); \r
+ return; \r
+ } \r
+ shared_memory = shmat(shmid, (char*)0x00, 0); \r
+ if (shared_memory == (void *)-1) \r
+ { \r
+ ERR("shmat failed\n"); \r
+ return; \r
+ } \r
+ sprintf(shared_memory, "%s", tizen_target_path);\r
+ INFO( "shared memory key: %d value: %s\n", tizen_base_port, (char*)shared_memory);\r
+#else\r
+ HANDLE hMapFile;\r
+ char* pBuf;\r
+ char* port_in_use;\r
+ char *shared_memory;\r
+ shared_memory = g_strdup_printf("%s", tizen_target_path);\r
+ port_in_use = g_strdup_printf("%d", tizen_base_port);\r
+ hMapFile = CreateFileMapping(\r
+ INVALID_HANDLE_VALUE, // use paging file\r
+ NULL, // default security\r
+ PAGE_READWRITE, // read/write access\r
+ 0, // maximum object size (high-order DWORD)\r
+ 50, // maximum object size (low-order DWORD)\r
+ port_in_use); // name of mapping object\r
+ if (hMapFile == NULL)\r
+ {\r
+ ERR("Could not create file mapping object (%d).\n", GetLastError());\r
+ return;\r
+ }\r
+ pBuf = MapViewOfFile(hMapFile, // handle to map object\r
+ FILE_MAP_ALL_ACCESS, // read/write permission\r
+ 0,\r
+ 0,\r
+ 50);\r
+\r
+ if (pBuf == NULL)\r
+ {\r
+ ERR("Could not map view of file (%d).\n", GetLastError());\r
+ CloseHandle(hMapFile);\r
+ return;\r
+ }\r
+ \r
+ CopyMemory((PVOID)pBuf, shared_memory, strlen(shared_memory));\r
+ free(port_in_use);\r
+ free(shared_memory);\r
+#endif\r
+ return;\r
+}\r
+\r
+\r
+\r
+static void construct_main_window(int skin_argc, char* skin_argv[], int qemu_argc, char* qemu_argv[] )\r
+{\r
+ INFO("construct main window\n");\r
+\r
+ start_skin_server( skin_argc, skin_argv, qemu_argc, qemu_argv );\r
+\r
+ if (get_emul_skin_enable() == 1) { //this line is check for debugging, etc..\r
+ if ( 0 > start_skin_client(skin_argc, skin_argv) ) {\r
+ maru_register_exit_msg(MARU_EXIT_SKIN_SERVER_FAILED, NULL);\r
+ exit( -1 );\r
+ }\r
+ }\r
+\r
+ set_emul_caps_lock_state(0);\r
+ set_emul_num_lock_state(0);\r
+}\r
+\r
+static void parse_options(int argc, char* argv[], int* skin_argc, char*** skin_argv, int* qemu_argc, char*** qemu_argv)\r
+{\r
+ int i;\r
+ int j;\r
+\r
+// FIXME !!!\r
+// TODO:\r
+ \r
+ for(i = 1; i < argc; ++i)\r
+ {\r
+ if(strncmp(argv[i], "--skin-args", 11) == 0)\r
+ {\r
+ *skin_argv = &(argv[i + 1]);\r
+ break;\r
+ }\r
+ }\r
+ for(j = i; j < argc; ++j)\r
+ {\r
+ if(strncmp(argv[j], "--qemu-args", 11) == 0)\r
+ {\r
+ *skin_argc = j - i - 1;\r
+\r
+ *qemu_argc = argc - j - i + 1;\r
+ *qemu_argv = &(argv[j]);\r
+\r
+ argv[j] = argv[0];\r
+ }\r
+ }\r
+}\r
+\r
+static void get_bin_dir( char* exec_argv ) {\r
+\r
+ if ( !exec_argv ) {\r
+ return;\r
+ }\r
+\r
+ char* data = strdup( exec_argv );\r
+ if ( !data ) {\r
+ fprintf( stderr, "Fail to strdup for paring a binary directory.\n" );\r
+ return;\r
+ }\r
+\r
+ char* p = NULL;\r
+#ifdef _WIN32\r
+ p = strrchr( data, '\\' );\r
+ if ( !p ) {\r
+ p = strrchr( data, '/' );\r
+ }\r
+#else\r
+ p = strrchr( data, '/' );\r
+#endif\r
+ if ( !p ) {\r
+ free( data );\r
+ return;\r
+ }\r
+\r
+ strncpy( bin_dir, data, strlen( data ) - strlen( p ) );\r
+\r
+ free( data );\r
+\r
+}\r
+\r
+void set_image_and_log_path(char* qemu_argv)\r
+{\r
+ int i;\r
+ int j = 0;\r
+ int name_len = 0;\r
+ int prefix_len = 0;\r
+ int suffix_len = 0;\r
+ int max = 0;\r
+ char *path = malloc(MAXLEN);\r
+ name_len = strlen(qemu_argv);\r
+ prefix_len = strlen(IMAGE_PATH_PREFIX);\r
+ suffix_len = strlen(IMAGE_PATH_SUFFIX);\r
+ max = name_len - suffix_len;\r
+ for(i = prefix_len , j = 0; i < max; i++)\r
+ {\r
+ path[j++] = qemu_argv[i];\r
+ }\r
+ path[j] = '\0';\r
+ if(!g_path_is_absolute(path))\r
+ strcpy(tizen_target_path, g_get_current_dir());\r
+ else\r
+ strcpy(tizen_target_path, g_path_get_dirname(path));\r
+\r
+ strcpy(logpath, tizen_target_path);\r
+ strcat(logpath, LOGS_SUFFIX);\r
+#ifdef _WIN32\r
+ if(access(g_win32_locale_filename_from_utf8(logpath), R_OK) != 0) {\r
+ g_mkdir(g_win32_locale_filename_from_utf8(logpath), 0755); \r
+ }\r
+#else\r
+ if(access(logpath, R_OK) != 0) {\r
+ g_mkdir(logpath, 0755); \r
+ }\r
+#endif\r
+ strcat(logpath, LOGFILE);\r
+ set_log_path(logpath);\r
+}\r
+\r
+void redir_output(void)\r
+{\r
+ FILE *fp;\r
+\r
+ fp = freopen(logpath, "a+", stdout);\r
+ if(fp ==NULL)\r
+ fprintf(stderr, "log file open error\n");\r
+ fp = freopen(logpath, "a+", stderr);\r
+ if(fp ==NULL)\r
+ fprintf(stderr, "log file open error\n");\r
+\r
+ setvbuf(stdout, NULL, _IOLBF, BUFSIZ);\r
+ setvbuf(stderr, NULL, _IOLBF, BUFSIZ);\r
+}\r
+\r
+void extract_info(int qemu_argc, char** qemu_argv)\r
+{\r
+ int i;\r
+\r
+ for(i = 0; i < qemu_argc; ++i)\r
+ {\r
+ if(strstr(qemu_argv[i], IMAGE_PATH_PREFIX) != NULL) {\r
+ set_image_and_log_path(qemu_argv[i]);\r
+ break;\r
+ }\r
+ }\r
+ \r
+ tizen_base_port = get_sdb_base_port();\r
+}\r
+\r
+static void system_info(void)\r
+{\r
+#define DIV 1024\r
+\r
+ char timeinfo[64] = {0, };\r
+ struct tm *tm_time;\r
+ struct timeval tval;\r
+\r
+ INFO("* SDK Version : %s\n", build_version);\r
+ INFO("* Package %s\n", pkginfo_version);\r
+ INFO("* User name : %s\n", g_get_real_name());\r
+ INFO("* Host name : %s\n", g_get_host_name());\r
+\r
+ /* timestamp */\r
+ INFO("* Build date : %s\n", build_date);\r
+ gettimeofday(&tval, NULL);\r
+ tm_time = localtime(&(tval.tv_sec));\r
+ strftime(timeinfo, sizeof(timeinfo), "%Y/%m/%d %H:%M:%S", tm_time);\r
+ INFO("* Current time : %s\n", timeinfo);\r
+\r
+ /* Gets the version of the dynamically linked SDL library */\r
+ INFO("* Host sdl version : (%d, %d, %d)\n",\r
+ SDL_Linked_Version()->major, SDL_Linked_Version()->minor, SDL_Linked_Version()->patch);\r
+\r
+#if defined(CONFIG_WIN32)\r
+ /* Retrieves information about the current os */\r
+ OSVERSIONINFO osvi;\r
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFO));\r
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r
+\r
+ if (GetVersionEx(&osvi)) {\r
+ INFO("* MajorVersion : %d, MinorVersion : %d, BuildNumber : %d, PlatformId : %d, CSDVersion : %s\n",\r
+ osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber, osvi.dwPlatformId, osvi.szCSDVersion);\r
+ }\r
+\r
+ /* Retrieves information about the current system */\r
+ SYSTEM_INFO sysi;\r
+ ZeroMemory(&sysi, sizeof(SYSTEM_INFO));\r
+\r
+ GetSystemInfo(&sysi);\r
+ INFO("* Processor type : %d, Number of processors : %d\n", sysi.dwProcessorType, sysi.dwNumberOfProcessors);\r
+\r
+ MEMORYSTATUSEX memInfo;\r
+ memInfo.dwLength = sizeof(MEMORYSTATUSEX);\r
+ GlobalMemoryStatusEx(&memInfo);\r
+ INFO("* Total Ram : %llu kB, Free: %lld kB\n",\r
+ memInfo.ullTotalPhys / DIV, memInfo.ullAvailPhys / DIV);\r
+\r
+#elif defined(CONFIG_LINUX)\r
+ /* depends on building */\r
+ INFO("* Qemu build machine linux kernel version : (%d, %d, %d)\n",\r
+ LINUX_VERSION_CODE >> 16, (LINUX_VERSION_CODE >> 8) & 0xff, LINUX_VERSION_CODE & 0xff);\r
+\r
+ /* depends on launching */\r
+ struct utsname host_uname_buf;\r
+ if (uname(&host_uname_buf) == 0) {\r
+ INFO("* Host machine uname : %s %s %s %s %s\n", host_uname_buf.sysname, host_uname_buf.nodename,\r
+ host_uname_buf.release, host_uname_buf.version, host_uname_buf.machine);\r
+ }\r
+\r
+ struct sysinfo sys_info;\r
+ if (sysinfo(&sys_info) == 0) {\r
+ INFO("* Total Ram : %llu kB, Free: %llu kB\n",\r
+ sys_info.totalram * (unsigned long long)sys_info.mem_unit / DIV,\r
+ sys_info.freeram * (unsigned long long)sys_info.mem_unit / DIV);\r
+ }\r
+\r
+ /* pci device description */\r
+ INFO("* Pci devices :\n");\r
+ char lscmd[MAXLEN] = "lspci >> ";\r
+ strcat(lscmd, logpath);\r
+ int i = system(lscmd);\r
+ INFO("system function command : %s, system function returned value : %d\n", lscmd, i);\r
+\r
+#elif defined(CONFIG_DARWIN)\r
+ //TODO:\r
+#endif\r
+\r
+ INFO("\n");\r
+}\r
+\r
+void prepare_maru(void)\r
+{\r
+ INFO("Prepare maru specified feature\n");\r
+\r
+ INFO("call construct_main_window\n");\r
+\r
+ construct_main_window(skin_argc, skin_argv, qemu_argc, qemu_argv);\r
+\r
+ int guest_server_port = tizen_base_port + SDB_UDP_SENSOR_INDEX;\r
+ start_guest_server( guest_server_port );\r
+\r
+ mloop_ev_init();\r
+}\r
+\r
+int qemu_main(int argc, char** argv, char** envp);\r
+\r
+int main(int argc, char* argv[])\r
+{\r
+ parse_options(argc, argv, &skin_argc, &skin_argv, &qemu_argc, &qemu_argv);\r
+ get_bin_dir( qemu_argv[0] );\r
+ socket_init();\r
+ extract_info(qemu_argc, qemu_argv);\r
+\r
+ INFO("Emulator start !!!\n");\r
+ \r
+ atexit(maru_atexit);\r
+ \r
+ check_shdmem();\r
+ make_shdmem();\r
+ sdb_setup();\r
+ \r
+ system_info();\r
+\r
+ INFO("Prepare running...\n");\r
+ redir_output(); // Redirect stdout, stderr after debug_ch is initialized...\r
+\r
+ int i;\r
+\r
+ fprintf(stdout, "qemu args : ==========================================\n");\r
+ for(i = 0; i < qemu_argc; ++i)\r
+ {\r
+ fprintf(stdout, "%s ", qemu_argv[i]);\r
+ }\r
+ fprintf(stdout, "\n");\r
+ fprintf(stdout, "======================================================\n");\r
+\r
+ fprintf(stdout, "skin args : ==========================================\n");\r
+ for(i = 0; i < skin_argc; ++i)\r
+ {\r
+ fprintf(stdout, "%s ", skin_argv[i]);\r
+ }\r
+ fprintf(stdout, "\n");\r
+ fprintf(stdout, "======================================================\n");\r
+\r
+ INFO("qemu main start!\n");\r
+ qemu_main(qemu_argc, qemu_argv, NULL);\r
+\r
+ exit_emulator();\r
+\r
+ return 0;\r
+}\r
+\r
-/* Copyright (C) 2006-2010 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** 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.
-*/
-
-
-#ifdef _WIN32
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#else /* !_WIN32 */
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#endif /* !_WIN32 */
-
-#include "net/slirp.h"
-#include "qemu_socket.h"
-#include "sdb.h"
-#include "nbd.h"
-#include "tizen/src/debug_ch.h"
-
-//DEFAULT_DEBUG_CHANNEL(qemu);
-MULTI_DEBUG_CHANNEL(qemu, sdb);
-
-/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty
- * easily in QEMU since we use SIGALRM to implement periodic timers
- */
-
-#ifdef _WIN32
-# define QSOCKET_CALL(_ret,_cmd) \
- do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR )
-#else
-# define QSOCKET_CALL(_ret,_cmd) \
- do { \
- errno = 0; \
- do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR ); \
- } while (0);
-#endif
-
-#ifdef _WIN32
-
-#include <errno.h>
-
-static int winsock_error;
-
-#define WINSOCK_ERRORS_LIST \
- EE(WSA_INVALID_HANDLE,EINVAL,"invalid handle") \
-EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \
-EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \
-EE(WSAEINTR,EINTR,"interrupted function call") \
-EE(WSAEALREADY,EALREADY,"operation already in progress") \
-EE(WSAEBADF,EBADF,"bad file descriptor") \
-EE(WSAEACCES,EACCES,"permission denied") \
-EE(WSAEFAULT,EFAULT,"bad address") \
-EE(WSAEINVAL,EINVAL,"invalid argument") \
-EE(WSAEMFILE,EMFILE,"too many opened files") \
-EE(WSAEWOULDBLOCK,EWOULDBLOCK,"resource temporarily unavailable") \
-EE(WSAEINPROGRESS,EINPROGRESS,"operation now in progress") \
-EE(WSAEALREADY,EAGAIN,"operation already in progress") \
-EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \
-EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \
-EE(WSAEMSGSIZE,EMSGSIZE,"message too long") \
-EE(WSAEPROTOTYPE,EPROTOTYPE,"wrong protocol type for socket") \
-EE(WSAENOPROTOOPT,ENOPROTOOPT,"bad protocol option") \
-EE(WSAEADDRINUSE,EADDRINUSE,"address already in use") \
-EE(WSAEADDRNOTAVAIL,EADDRNOTAVAIL,"cannot assign requested address") \
-EE(WSAENETDOWN,ENETDOWN,"network is down") \
-EE(WSAENETUNREACH,ENETUNREACH,"network unreachable") \
-EE(WSAENETRESET,ENETRESET,"network dropped connection on reset") \
-EE(WSAECONNABORTED,ECONNABORTED,"software caused connection abort") \
-EE(WSAECONNRESET,ECONNRESET,"connection reset by peer") \
-EE(WSAENOBUFS,ENOBUFS,"no buffer space available") \
-EE(WSAEISCONN,EISCONN,"socket is already connected") \
-EE(WSAENOTCONN,ENOTCONN,"socket is not connected") \
-EE(WSAESHUTDOWN,ESHUTDOWN,"cannot send after socket shutdown") \
-EE(WSAETOOMANYREFS,ETOOMANYREFS,"too many references") \
-EE(WSAETIMEDOUT,ETIMEDOUT,"connection timed out") \
-EE(WSAECONNREFUSED,ECONNREFUSED,"connection refused") \
-EE(WSAELOOP,ELOOP,"cannot translate name") \
-EE(WSAENAMETOOLONG,ENAMETOOLONG,"name too long") \
-EE(WSAEHOSTDOWN,EHOSTDOWN,"host is down") \
-EE(WSAEHOSTUNREACH,EHOSTUNREACH,"no route to host") \
-
-typedef struct {
- int winsock;
- int unix;
- const char* string;
-} WinsockError;
-
-static const WinsockError _winsock_errors[] = {
-#define EE(w,u,s) { w, u, s },
- WINSOCK_ERRORS_LIST
-#undef EE
- { -1, -1, NULL }
-};
-
-/* this function reads the latest winsock error code and updates
- * errno to a matching value. It also returns the new value of
- * errno.
- */
-static int _fix_errno( void )
-{
- const WinsockError* werr = _winsock_errors;
- int unix = EINVAL; /* generic error code */
-
- winsock_error = WSAGetLastError();
-
- for ( ; werr->string != NULL; werr++ ) {
- if (werr->winsock == winsock_error) {
- unix = werr->unix;
- break;
- }
- }
- errno = unix;
- return -1;
-}
-
-#else
-static int _fix_errno( void )
-{
- return -1;
-}
-
-#endif
-
-#define SOCKET_CALL(cmd) \
- int ret; \
-QSOCKET_CALL(ret, (cmd)); \
-if (ret < 0) \
-return _fix_errno(); \
-return ret; \
-
-int socket_send(int fd, const void* buf, int buflen)
-{
- SOCKET_CALL(send(fd, buf, buflen, 0))
-}
-
-#ifdef _WIN32
-
- static void
-socket_close_handler( void* _fd )
-{
- int fd = (int)_fd;
- int ret;
- char buff[64];
-
- /* we want to drain the read side of the socket before closing it */
- do {
- ret = recv( fd, buff, sizeof(buff), 0 );
- } while (ret < 0 && WSAGetLastError() == WSAEINTR);
-
- if (ret < 0 && WSAGetLastError() == EWOULDBLOCK)
- return;
-
- qemu_set_fd_handler( fd, NULL, NULL, NULL );
- closesocket( fd );
-}
-
- void
-socket_close( int fd )
-{
- int old_errno = errno;
-
- shutdown( fd, SD_BOTH );
- /* we want to drain the socket before closing it */
- qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd );
-
- errno = old_errno;
-}
-
-#else /* !_WIN32 */
-
-#include <unistd.h>
-
- void
-socket_close( int fd )
-{
- int old_errno = errno;
-
- shutdown( fd, SHUT_RDWR );
- close( fd );
-
- errno = old_errno;
-}
-
-#endif /* !_WIN32 */
-
-int inet_strtoip(const char* str, uint32_t *ip)
-{
- int comp[4];
-
- if (sscanf(str, "%d.%d.%d.%d", &comp[0], &comp[1], &comp[2], &comp[3]) != 4)
- return -1;
-
- if ((unsigned)comp[0] >= 256 ||
- (unsigned)comp[1] >= 256 ||
- (unsigned)comp[2] >= 256 ||
- (unsigned)comp[3] >= 256)
- return -1;
-
- *ip = (uint32_t)((comp[0] << 24) | (comp[1] << 16) |
- (comp[2] << 8) | comp[3]);
- return 0;
-}
-
-static int check_port_bind_listen(u_int port)
-{
- struct sockaddr_in addr;
- int s, opt = 1;
- int ret = -1;
- socklen_t addrlen = sizeof(addr);
- memset(&addr, 0, addrlen);
-
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
- addr.sin_port = htons(port);
-
- if (((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) < 0) ||
-#ifndef _WIN32
- (setsockopt(s, SOL_SOCKET,SO_REUSEADDR, (char *)&opt, sizeof(int)) < 0) ||
-#endif
- (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) ||
- (listen(s, 1) < 0)) {
-
- /* fail */
- ret = -1;
- ERR( "port(%d) listen fail \n", port);
- }else{
- /*fsucess*/
- ret = 1;
- INFO( "port(%d) listen ok \n", port);
- }
-
-#ifdef _WIN32
- closesocket(s);
-#else
- close(s);
-#endif
-
- return ret;
-}
-
-int get_sdb_base_port(void)
-{
- int tries = 10;
- int success = 0;
- u_int port = 26100;
-
- if(tizen_base_port == 0){
-
- for ( ; tries > 0; tries--, port += 10 ) {
- if(check_port_bind_listen(port + 1) < 0 )
- continue;
-
- success = 1;
- break;
- }
-
- if (!success) {
- ERR( "it seems too many emulator instances are running on this machine. Aborting\n" );
- exit(1);
- }
-
- tizen_base_port = port;
- INFO( "sdb port is %d \n", tizen_base_port);
- }
-
- return tizen_base_port;
-}
-
-void sdb_setup(void)
-{
- int tries = 10;
- int success = 0;
- uint32_t guest_ip;
- char buf[64] = {0,};
-
- inet_strtoip("10.0.2.16", &guest_ip);
-
- for ( ; tries > 0; tries--, tizen_base_port += 10 ) {
- // redir form [tcp:26101:10.0.2.16:26101]
- sprintf(buf, "tcp:%d:10.0.2.16:26101", tizen_base_port + 1);
- if(net_slirp_redir((char*)buf) < 0)
- continue;
-
- INFO( "SDBD established on port %d\n", tizen_base_port + 1);
- success = 1;
- break;
- }
-
- INFO("redirect [%s] success\n", buf);
- if (!success) {
- ERR( "it seems too many emulator instances are running on this machine. Aborting\n" );
- exit(1);
- }
-
- INFO( "Port(%d/tcp) listen for SDB \n", tizen_base_port + 1);
-
- /* for sensort */
- sprintf(buf, "tcp:%d:10.0.2.16:3577", tizen_base_port + SDB_TCP_EMULD_INDEX );
- if(net_slirp_redir((char*)buf) < 0){
- ERR( "redirect [%s] fail \n", buf);
- }else{
- INFO("redirect [%s] success\n", buf);
- }
-}
-
-int sdb_loopback_client(int port, int type)
-{
- struct sockaddr_in addr;
- int s;
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
- s = socket(AF_INET, type, 0);
- if(s < 0) return -1;
-
- if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- close(s);
- return -1;
- }
-
- return s;
-
-}
-
-void notify_sdb_daemon_start(void) {
- int s;
- /*
- * send a simple message to the SDB host server to tell it we just started.
- * it should be listening on port 26099.
- */
- do {
- char tmp[32] = { 0 };
-
- // when connecting to loopback:26099, do not use tcp_socket_outgoing function
- // tcp_socket_outgoing may occur "dns name service not known" in case of network unavaliable status.
- s = sdb_loopback_client(SDB_HOST_PORT, SOCK_STREAM);
- if (s < 0) {
- INFO("can't create socket to talk to the SDB server \n");
- INFO("This emulator will be scaned by the SDB server \n");
- break;
- }
-
- /* length is hex: 0x13 = 19 */
- sprintf(tmp, "0013host:emulator:%d", tizen_base_port + 1);
-
- if (socket_send(s, tmp, 30) < 0) {
- ERR( "message sending to sdb server error!\n");
- }
-
- } while (0);
-
- if (s >= 0)
- socket_close(s);
-}
+/* Copyright (C) 2006-2010 The Android Open Source Project\r
+**\r
+** This software is licensed under the terms of the GNU General Public\r
+** License version 2, as published by the Free Software Foundation, and\r
+** may be copied, distributed, and modified under those terms.\r
+**\r
+** This program is distributed in the hope that it will be useful,\r
+** but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+** GNU General Public License for more details.\r
+*/\r
+\r
+\r
+#ifdef _WIN32\r
+#include <windows.h>\r
+#include <winsock2.h>\r
+#include <ws2tcpip.h>\r
+#else /* !_WIN32 */\r
+#include <sys/ioctl.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <netinet/tcp.h>\r
+#include <netdb.h>\r
+#endif /* !_WIN32 */\r
+\r
+#include "net/slirp.h"\r
+#include "qemu_socket.h"\r
+#include "sdb.h"\r
+#include "nbd.h"\r
+#include "tizen/src/debug_ch.h"\r
+\r
+//DEFAULT_DEBUG_CHANNEL(qemu);\r
+MULTI_DEBUG_CHANNEL(qemu, sdb);\r
+\r
+/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty\r
+ * easily in QEMU since we use SIGALRM to implement periodic timers\r
+ */\r
+\r
+#ifdef _WIN32\r
+# define QSOCKET_CALL(_ret,_cmd) \\r
+ do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR )\r
+#else\r
+# define QSOCKET_CALL(_ret,_cmd) \\r
+ do { \\r
+ errno = 0; \\r
+ do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR ); \\r
+ } while (0);\r
+#endif\r
+\r
+#ifdef _WIN32\r
+\r
+#include <errno.h>\r
+\r
+static int winsock_error;\r
+\r
+#define WINSOCK_ERRORS_LIST \\r
+ EE(WSA_INVALID_HANDLE,EINVAL,"invalid handle") \\r
+EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \\r
+EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \\r
+EE(WSAEINTR,EINTR,"interrupted function call") \\r
+EE(WSAEALREADY,EALREADY,"operation already in progress") \\r
+EE(WSAEBADF,EBADF,"bad file descriptor") \\r
+EE(WSAEACCES,EACCES,"permission denied") \\r
+EE(WSAEFAULT,EFAULT,"bad address") \\r
+EE(WSAEINVAL,EINVAL,"invalid argument") \\r
+EE(WSAEMFILE,EMFILE,"too many opened files") \\r
+EE(WSAEWOULDBLOCK,EWOULDBLOCK,"resource temporarily unavailable") \\r
+EE(WSAEINPROGRESS,EINPROGRESS,"operation now in progress") \\r
+EE(WSAEALREADY,EAGAIN,"operation already in progress") \\r
+EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \\r
+EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \\r
+EE(WSAEMSGSIZE,EMSGSIZE,"message too long") \\r
+EE(WSAEPROTOTYPE,EPROTOTYPE,"wrong protocol type for socket") \\r
+EE(WSAENOPROTOOPT,ENOPROTOOPT,"bad protocol option") \\r
+EE(WSAEADDRINUSE,EADDRINUSE,"address already in use") \\r
+EE(WSAEADDRNOTAVAIL,EADDRNOTAVAIL,"cannot assign requested address") \\r
+EE(WSAENETDOWN,ENETDOWN,"network is down") \\r
+EE(WSAENETUNREACH,ENETUNREACH,"network unreachable") \\r
+EE(WSAENETRESET,ENETRESET,"network dropped connection on reset") \\r
+EE(WSAECONNABORTED,ECONNABORTED,"software caused connection abort") \\r
+EE(WSAECONNRESET,ECONNRESET,"connection reset by peer") \\r
+EE(WSAENOBUFS,ENOBUFS,"no buffer space available") \\r
+EE(WSAEISCONN,EISCONN,"socket is already connected") \\r
+EE(WSAENOTCONN,ENOTCONN,"socket is not connected") \\r
+EE(WSAESHUTDOWN,ESHUTDOWN,"cannot send after socket shutdown") \\r
+EE(WSAETOOMANYREFS,ETOOMANYREFS,"too many references") \\r
+EE(WSAETIMEDOUT,ETIMEDOUT,"connection timed out") \\r
+EE(WSAECONNREFUSED,ECONNREFUSED,"connection refused") \\r
+EE(WSAELOOP,ELOOP,"cannot translate name") \\r
+EE(WSAENAMETOOLONG,ENAMETOOLONG,"name too long") \\r
+EE(WSAEHOSTDOWN,EHOSTDOWN,"host is down") \\r
+EE(WSAEHOSTUNREACH,EHOSTUNREACH,"no route to host") \\r
+\r
+typedef struct {\r
+ int winsock;\r
+ int unix;\r
+ const char* string;\r
+} WinsockError;\r
+\r
+static const WinsockError _winsock_errors[] = {\r
+#define EE(w,u,s) { w, u, s },\r
+ WINSOCK_ERRORS_LIST\r
+#undef EE\r
+ { -1, -1, NULL }\r
+};\r
+\r
+/* this function reads the latest winsock error code and updates\r
+ * errno to a matching value. It also returns the new value of\r
+ * errno.\r
+ */\r
+static int _fix_errno( void )\r
+{\r
+ const WinsockError* werr = _winsock_errors;\r
+ int unix = EINVAL; /* generic error code */\r
+\r
+ winsock_error = WSAGetLastError();\r
+\r
+ for ( ; werr->string != NULL; werr++ ) {\r
+ if (werr->winsock == winsock_error) {\r
+ unix = werr->unix;\r
+ break;\r
+ }\r
+ }\r
+ errno = unix;\r
+ return -1;\r
+}\r
+\r
+#else\r
+static int _fix_errno( void )\r
+{\r
+ return -1;\r
+}\r
+\r
+#endif\r
+\r
+#define SOCKET_CALL(cmd) \\r
+ int ret; \\r
+QSOCKET_CALL(ret, (cmd)); \\r
+if (ret < 0) \\r
+return _fix_errno(); \\r
+return ret; \\r
+\r
+int socket_send(int fd, const void* buf, int buflen)\r
+{\r
+ SOCKET_CALL(send(fd, buf, buflen, 0))\r
+}\r
+\r
+#ifdef _WIN32\r
+\r
+ static void\r
+socket_close_handler( void* _fd )\r
+{\r
+ int fd = (int)_fd;\r
+ int ret;\r
+ char buff[64];\r
+\r
+ /* we want to drain the read side of the socket before closing it */\r
+ do {\r
+ ret = recv( fd, buff, sizeof(buff), 0 );\r
+ } while (ret < 0 && WSAGetLastError() == WSAEINTR);\r
+\r
+ if (ret < 0 && WSAGetLastError() == EWOULDBLOCK)\r
+ return;\r
+\r
+ qemu_set_fd_handler( fd, NULL, NULL, NULL );\r
+ closesocket( fd );\r
+}\r
+\r
+ void\r
+socket_close( int fd )\r
+{\r
+ int old_errno = errno;\r
+\r
+ shutdown( fd, SD_BOTH );\r
+ /* we want to drain the socket before closing it */\r
+ qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd );\r
+\r
+ errno = old_errno;\r
+}\r
+\r
+#else /* !_WIN32 */\r
+\r
+#include <unistd.h>\r
+\r
+ void\r
+socket_close( int fd )\r
+{\r
+ int old_errno = errno;\r
+\r
+ shutdown( fd, SHUT_RDWR );\r
+ close( fd );\r
+\r
+ errno = old_errno;\r
+}\r
+\r
+#endif /* !_WIN32 */\r
+\r
+int inet_strtoip(const char* str, uint32_t *ip)\r
+{\r
+ int comp[4];\r
+\r
+ if (sscanf(str, "%d.%d.%d.%d", &comp[0], &comp[1], &comp[2], &comp[3]) != 4)\r
+ return -1;\r
+\r
+ if ((unsigned)comp[0] >= 256 ||\r
+ (unsigned)comp[1] >= 256 ||\r
+ (unsigned)comp[2] >= 256 ||\r
+ (unsigned)comp[3] >= 256)\r
+ return -1;\r
+\r
+ *ip = (uint32_t)((comp[0] << 24) | (comp[1] << 16) |\r
+ (comp[2] << 8) | comp[3]);\r
+ return 0;\r
+}\r
+\r
+static int check_port_bind_listen(u_int port)\r
+{\r
+ struct sockaddr_in addr;\r
+ int s, opt = 1;\r
+ int ret = -1;\r
+ socklen_t addrlen = sizeof(addr);\r
+ memset(&addr, 0, addrlen);\r
+\r
+ addr.sin_family = AF_INET;\r
+ addr.sin_addr.s_addr = INADDR_ANY;\r
+ addr.sin_port = htons(port);\r
+\r
+ if (((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) < 0) ||\r
+#ifndef _WIN32\r
+ (setsockopt(s, SOL_SOCKET,SO_REUSEADDR, (char *)&opt, sizeof(int)) < 0) ||\r
+#endif\r
+ (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) ||\r
+ (listen(s, 1) < 0)) {\r
+\r
+ /* fail */\r
+ ret = -1;\r
+ ERR( "port(%d) listen fail \n", port);\r
+ }else{\r
+ /*fsucess*/\r
+ ret = 1;\r
+ INFO( "port(%d) listen ok \n", port);\r
+ }\r
+\r
+#ifdef _WIN32\r
+ closesocket(s);\r
+#else\r
+ close(s);\r
+#endif\r
+\r
+ return ret;\r
+}\r
+\r
+int get_sdb_base_port(void)\r
+{\r
+ int tries = 10;\r
+ int success = 0;\r
+ u_int port = 26100;\r
+\r
+ if(tizen_base_port == 0){\r
+\r
+ for ( ; tries > 0; tries--, port += 10 ) {\r
+ if(check_port_bind_listen(port + 1) < 0 )\r
+ continue;\r
+\r
+ success = 1;\r
+ break;\r
+ }\r
+\r
+ if (!success) {\r
+ ERR( "it seems too many emulator instances are running on this machine. Aborting\n" );\r
+ exit(1);\r
+ }\r
+\r
+ tizen_base_port = port;\r
+ INFO( "sdb port is %d \n", tizen_base_port);\r
+ }\r
+\r
+ return tizen_base_port;\r
+}\r
+\r
+void sdb_setup(void)\r
+{\r
+ int tries = 10;\r
+ int success = 0;\r
+ uint32_t guest_ip;\r
+ char buf[64] = {0,};\r
+ inet_strtoip("10.0.2.16", &guest_ip);\r
+\r
+ for ( ; tries > 0; tries--, tizen_base_port += 10 ) {\r
+ // redir form [tcp:26101:10.0.2.16:26101]\r
+ sprintf(buf, "tcp:%d:10.0.2.16:26101", tizen_base_port + 1);\r
+ if(net_slirp_redir((char*)buf) < 0)\r
+ continue;\r
+\r
+ INFO( "SDBD established on port %d\n", tizen_base_port + 1);\r
+ success = 1;\r
+ break;\r
+ }\r
+\r
+ INFO("redirect [%s] success\n", buf);\r
+ if (!success) {\r
+ ERR( "it seems too many emulator instances are running on this machine. Aborting\n" );\r
+ exit(1);\r
+ }\r
+\r
+ INFO( "Port(%d/tcp) listen for SDB \n", tizen_base_port + 1);\r
+\r
+ /* for sensort */\r
+ sprintf(buf, "tcp:%d:10.0.2.16:3577", tizen_base_port + SDB_TCP_EMULD_INDEX );\r
+ if(net_slirp_redir((char*)buf) < 0){\r
+ ERR( "redirect [%s] fail \n", buf);\r
+ }else{\r
+ INFO("redirect [%s] success\n", buf);\r
+ }\r
+}\r
+\r
+int sdb_loopback_client(int port, int type)\r
+{\r
+ struct sockaddr_in addr;\r
+ int s;\r
+\r
+ memset(&addr, 0, sizeof(addr));\r
+ addr.sin_family = AF_INET;\r
+ addr.sin_port = htons(port);\r
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);\r
+\r
+ s = socket(AF_INET, type, 0);\r
+ if(s < 0) return -1;\r
+\r
+ if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {\r
+ close(s);\r
+ return -1;\r
+ }\r
+\r
+ return s;\r
+\r
+}\r
+\r
+void notify_sdb_daemon_start(void) {\r
+ int s;\r
+ /* \r
+ * send a simple message to the SDB host server to tell it we just started.\r
+ * it should be listening on port 26099.\r
+ */\r
+ do {\r
+ char tmp[32] = { 0 };\r
+\r
+ // when connecting to loopback:26099, do not use tcp_socket_outgoing function\r
+ // tcp_socket_outgoing may occur "dns name service not known" in case of network unavaliable status.\r
+ s = sdb_loopback_client(SDB_HOST_PORT, SOCK_STREAM);\r
+ if (s < 0) {\r
+ INFO("can't create socket to talk to the SDB server \n");\r
+ INFO("This emulator will be scaned by the SDB server \n");\r
+ break;\r
+ }\r
+\r
+ /* length is hex: 0x13 = 19 */\r
+ sprintf(tmp, "0013host:emulator:%d", tizen_base_port + 1);\r
+\r
+ if (socket_send(s, tmp, 30) < 0) {\r
+ ERR( "message sending to sdb server error!\n");\r
+ }\r
+\r
+ } while (0);\r
+\r
+ if (s >= 0)\r
+ socket_close(s);\r
+}\r