From: Jinhyung Choi Date: Fri, 27 Sep 2013 04:12:09 +0000 (+0900) Subject: qemu: supports storing sdb server list & sending suspend/resume message X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.1~700 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a43e3caa0f76aabc725f7e1946b8b9ea96bb9daa;p=sdk%2Femulator%2Fqemu.git qemu: supports storing sdb server list & sending suspend/resume message Change-Id: I8e71e07de47731ba77bf16a0a1d0299c69f64294 Signed-off-by: Jinhyung Choi --- diff --git a/tizen/src/guest_server.c b/tizen/src/guest_server.c index a9e44365d1..c8e0d536a5 100644 --- a/tizen/src/guest_server.c +++ b/tizen/src/guest_server.c @@ -52,32 +52,134 @@ #include "debug_ch.h" #include "sdb.h" #include "maru_common.h" +#include "hw/maru_virtio_hwkey.h" MULTI_DEBUG_CHANNEL(qemu, guest_server); #define RECV_BUF_SIZE 32 -static void* run_guest_server(void* args); - static int svr_port = 0; static int server_sock = 0; -static int parse_val(char *buff, unsigned char data, char *parsbuf); +/* + * SDB server data + */ +typedef struct GS_Client { + int port; + char addr[RECV_BUF_SIZE]; + + QTAILQ_ENTRY(GS_Client) next; +} GS_Client; -pthread_t start_guest_server(int server_port) +static QTAILQ_HEAD(GS_ClientHead, GS_Client) +clients = QTAILQ_HEAD_INITIALIZER(clients); + +static pthread_mutex_t mutex_clilist = PTHREAD_MUTEX_INITIALIZER; + +static void add_sdb_client(const char* addr, int port) { - svr_port = server_port; + GS_Client *client = g_malloc0(sizeof(GS_Client)); + if (NULL == client) { + INFO("GS_Client allocation failed.\n"); + return; + } - pthread_t thread_id; + if (addr == NULL || strlen(addr) <= 0) { + INFO("GS_Client client's address is EMPTY.\n"); + return; + } else if (strlen(addr) > RECV_BUF_SIZE) { + INFO("GS_Client client's address is too long. %s\n", addr); + return; + } - if (0 != pthread_create(&thread_id, NULL, run_guest_server, NULL)) { - ERR("fail to create guest_server pthread.\n"); - } else { - INFO("created guest server thread\n"); + strcpy(client->addr, addr); + client->port = port; + + pthread_mutex_lock(&mutex_clilist); + + QTAILQ_INSERT_TAIL(&clients, client, next); + + pthread_mutex_unlock(&mutex_clilist); + + INFO("Added new sdb client. ip: %s, port: %d\n", client->addr, client->port); +} + +static void remove_sdb_client(GS_Client* client) +{ + pthread_mutex_lock(&mutex_clilist); + + QTAILQ_REMOVE(&clients, client, next); + if (NULL != client) { + g_free(client); } - return thread_id; + pthread_mutex_unlock(&mutex_clilist); +} + +static void send_to_client(GS_Client* client, int state) +{ + struct sockaddr_in sock_addr; + int s, slen = sizeof(sock_addr); + char buf [32]; + + if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1){ + INFO("socket error!\n"); + return; + } + + memset(&sock_addr, 0, sizeof(sock_addr)); + + sock_addr.sin_family = AF_INET; + sock_addr.sin_port = htons(client->port); + if (inet_aton(client->addr, &sock_addr.sin_addr) == 0) { + INFO("inet_aton() failed\n"); + } + + memset(buf, 0, sizeof(buf)); + + sprintf(buf, "%d\n", state); + + if (sendto(s, buf, sizeof(buf), 0, (struct sockaddr*)&sock_addr, slen) == -1) + { + INFO("sendto error! remove this client.\n"); + remove_sdb_client(client); + } + + close(s); +} + +void notify_all_sdb_clients(int state) +{ + pthread_mutex_lock(&mutex_clilist); + GS_Client *client; + + QTAILQ_FOREACH(client, &clients, next) + { + send_to_client(client, state); + } + pthread_mutex_unlock(&mutex_clilist); + +} + +static int parse_val(char* buff, unsigned char data, char* parsbuf) +{ + int count = 0; + + while (1) { + if (count > 12) { + return -1; + } + + if (buff[count] == data) { + count++; + strncpy(parsbuf, buff, count); + return count; + } + count++; + } + + return 0; } /* @@ -104,7 +206,7 @@ static gchar *get_old_tizen_sdk_data_path(void) 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"); + INFO("failed to allocate memory.\n"); return NULL; } g_strlcpy(tizen_sdk_data_path, home_dir, tizen_sdk_data_len); @@ -128,7 +230,7 @@ static gchar *get_old_tizen_sdk_data_path(void) 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"); + INFO("failed to allocate memory.\n"); return NULL; } @@ -162,14 +264,14 @@ static gchar *get_tizen_sdk_data_path(void) emul_bin_path = get_bin_path(); if (!emul_bin_path) { - ERR("failed to get emulator path.\n"); + INFO("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"); + INFO("failed to allocate sdk-data buffer.\n"); return NULL; } @@ -212,7 +314,7 @@ static gchar *get_tizen_sdk_data_path(void) } // legacy mode - ERR("Failed to open [sdk.info].\n"); + INFO("Failed to open [sdk.info].\n"); return get_old_tizen_sdk_data_path(); } @@ -231,14 +333,14 @@ static char* get_emulator_sdcard_path(void) tizen_sdk_data = get_tizen_sdk_data_path(); if (!tizen_sdk_data) { - ERR("failed to get tizen-sdk-data path.\n"); + INFO("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"); + INFO("failed to allocate memory.\n"); return NULL; } @@ -251,78 +353,126 @@ static char* get_emulator_sdcard_path(void) return emulator_sdcard_path; } -static void* run_guest_server(void* args) +static void handle_sdcard(char* readbuf) { - uint16_t port = svr_port; - int opt = 1, read_cnt = 0; - char readbuf[RECV_BUF_SIZE]; - struct sockaddr_in server_addr, client_addr; - socklen_t client_len; - - INFO("start guest server thread.\n"); - - if ((server_sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { - ERR("create listen socket error\n"); - perror("create listen socket error\n"); -#ifdef _WIN32 - if (server_sock) { - closesocket(server_sock); - } -#else - if (server_sock) { - close(server_sock); + char token[] = "\n"; + char* ret = NULL; + ret = strtok(readbuf, token); + ret = strtok(NULL, token); + + if (atoi(ret) == 0) { + /* umount sdcard */ + //mloop_evcmd_usbdisk(NULL); + mloop_evcmd_sdcard(NULL); + } else if (atoi(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 */ + ret = strtok(NULL, token); + + g_strlcat(sdcard_img_path, ret, sizeof(sdcard_img_path)); + TRACE("sdcard path: %s\n", sdcard_img_path); + + //mloop_evcmd_usbdisk(sdcard_img_path); + mloop_evcmd_sdcard(sdcard_img_path); + + g_free(sdcard_path); + } else { + INFO("failed to get sdcard path!!\n"); } -#endif - server_sock = 0; - return NULL; + } else { + INFO("!!! unknown command : %s\n", ret); } +} - memset(&server_addr, '\0', sizeof(server_addr)); - server_addr.sin_family = PF_INET; - server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - server_addr.sin_port = htons(port); +static void register_sdb_server(char* readbuf) +{ + int port = 0; + char token[] = "\n"; + char* ret = NULL; + char* addr = NULL; + ret = strtok(readbuf, token); + addr = strtok(NULL, token); + if (addr == NULL) + return; + ret = strtok(NULL, token); + if (ret == NULL) + return; + port = atoi(ret); + + add_sdb_client(addr, port); +} - setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); +#define PRESS 1 +#define RELEASE 2 +#define POWER_KEY 116 +static void wakeup_guest(void) +{ + // FIXME: Temporarily working model. + // It must be fixed as the way it works. + maru_hwkey_event(PRESS, POWER_KEY); + maru_hwkey_event(RELEASE, POWER_KEY); +} - if (bind(server_sock, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) { - ERR("guest server bind error: "); - perror("bind"); -#ifdef _WIN32 - if (server_sock) { - closesocket(server_sock); - } -#else - if (server_sock) { - close(server_sock); - } -#endif - server_sock = 0; - return NULL; +static void command_handler(char* readbuf) +{ + char command[RECV_BUF_SIZE]; + memset(command, '\0', sizeof(command)); + + parse_val(readbuf, 0x0a, command); + + TRACE("----------------------------------------\n"); + TRACE("command:%s\n", command); + if (strcmp(command, "2\n" ) == 0) { + notify_sdb_daemon_start(); + } else if (strcmp(command, "3\n" ) == 0) { + notify_sensor_daemon_start(); + notify_ecs_server_start(); + } else if (strcmp(command, "4\n") == 0) { + handle_sdcard(readbuf); + } else if (strcmp(command, "5\n") == 0) { + register_sdb_server(readbuf); + } else if (strcmp(command, "6\n") == 0) { + wakeup_guest(); } else { - INFO("success to bind port[127.0.0.1:%d/udp] for guest_server in host \n", port); + INFO("!!! unknown command : %s\n", command); } + TRACE("========================================\n"); +} + +static void server_process(void) +{ + int read_cnt = 0; + struct sockaddr_in client_addr; + socklen_t client_len; + char readbuf[RECV_BUF_SIZE]; client_len = sizeof(client_addr); - INFO("guest server start...port:%d\n", port); while (1) { memset(&readbuf, 0, RECV_BUF_SIZE); if (server_sock == 0) { INFO("server_sock is closed\n"); - return NULL; + return; } read_cnt = recvfrom(server_sock, readbuf, RECV_BUF_SIZE, 0, (struct sockaddr*) &client_addr, &client_len); if (read_cnt < 0) { - ERR("fail to recvfrom in guest_server.\n"); + INFO("fail to recvfrom in guest_server.\n"); perror("fail to recvfrom in guest_server.:"); break; } else { if (read_cnt == 0) { - ERR("read_cnt is 0.\n"); + INFO("read_cnt is 0.\n"); break; } @@ -330,65 +480,34 @@ static void* run_guest_server(void* args) TRACE("read_cnt:%d\n", read_cnt); TRACE("readbuf:%s\n", readbuf); - char command[RECV_BUF_SIZE]; - memset(command, '\0', sizeof(command)); - - parse_val(readbuf, 0x0a, command); - - TRACE("----------------------------------------\n"); - if (strcmp(command, "2\n" ) == 0) { - TRACE("command:%s\n", command); - notify_sdb_daemon_start(); - } else if (strcmp(command, "3\n" ) == 0) { - TRACE("command:%s\n", command); - notify_sensor_daemon_start(); - notify_ecs_server_start(); - } else if (strcmp(command, "4\n") == 0) { - /* sdcard mount/umount msg recv from emuld */ - INFO("command:%s\n", command); - char token[] = "\n"; - char* ret = NULL; - ret = strtok(readbuf, token); - ret = strtok(NULL, token); - - if (atoi(ret) == 0) { - /* umount sdcard */ - //mloop_evcmd_usbdisk(NULL); - mloop_evcmd_sdcard(NULL); - } else if (atoi(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 */ - ret = strtok(NULL, token); - - g_strlcat(sdcard_img_path, ret, sizeof(sdcard_img_path)); - TRACE("sdcard path: %s\n", sdcard_img_path); - - //mloop_evcmd_usbdisk(sdcard_img_path); - mloop_evcmd_sdcard(sdcard_img_path); - - g_free(sdcard_path); - } else { - ERR("failed to get sdcard path!!\n"); - } - } else { - ERR("!!! unknown command : %s\n", ret); - } - } else { - ERR("!!! unknown command : %s\n", command); - } + command_handler(readbuf); + } + } +} + +static void close_clients(void) +{ + GS_Client * client; - TRACE("========================================\n"); + pthread_mutex_lock(&mutex_clilist); + + QTAILQ_FOREACH(client, &clients, next) + { + QTAILQ_REMOVE(&clients, client, next); + + if (NULL != client) + { + g_free(client); } } -#ifdef CONFIG_WIN32 + pthread_mutex_unlock(&mutex_clilist); +} + +static void close_server(void) +{ + close_clients(); +#ifdef _WIN32 if (server_sock) { closesocket(server_sock); } @@ -398,44 +517,71 @@ static void* run_guest_server(void* args) } #endif server_sock = 0; +} + +static void* run_guest_server(void* args) +{ + uint16_t port = svr_port; + int opt = 1; + struct sockaddr_in server_addr; + + INFO("start guest server thread.\n"); + + if ((server_sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + INFO("create listen socket error\n"); + perror("create listen socket error\n"); + + close_server(); + + return NULL; + } + + memset(&server_addr, '\0', sizeof(server_addr)); + server_addr.sin_family = PF_INET; + server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + server_addr.sin_port = htons(port); + + setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + if (bind(server_sock, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) { + INFO("guest server bind error: "); + perror("bind"); + + close_server(); + + return NULL; + } else { + INFO("success to bind port[127.0.0.1:%d/udp] for guest_server in host \n", port); + } + + INFO("guest server start...port:%d\n", port); + + server_process(); + + close_server(); return NULL; } -static int parse_val(char* buff, unsigned char data, char* parsbuf) +pthread_t start_guest_server(int server_port) { - int count = 0; - - while (1) { - if (count > 12) { - return -1; - } + svr_port = server_port; - if (buff[count] == data) { - count++; - strncpy(parsbuf, buff, count); - return count; - } + pthread_t thread_id; - count++; + if (0 != pthread_create(&thread_id, NULL, run_guest_server, NULL)) { + INFO("fail to create guest_server pthread.\n"); + } else { + INFO("created guest server thread\n"); } - return 0; + return thread_id; + } void shutdown_guest_server(void) { INFO("shutdown_guest_server.\n"); -#ifdef _WIN32 - if (server_sock) { - closesocket(server_sock); - } -#else - if (server_sock) { - close(server_sock); - } -#endif - - server_sock = 0; + close_server(); } diff --git a/tizen/src/guest_server.h b/tizen/src/guest_server.h index 0d55667c8b..795f54bc53 100644 --- a/tizen/src/guest_server.h +++ b/tizen/src/guest_server.h @@ -37,4 +37,6 @@ pthread_t start_guest_server( int server_port ); void shutdown_guest_server( void ); +void notify_all_sdb_clients(int state); + #endif /* GUEST_SERVER_H_ */