qemu: supports storing sdb server list & sending suspend/resume message 23/10723/1
authorJinhyung Choi <jinhyung2.choi@samsung.com>
Fri, 27 Sep 2013 04:12:09 +0000 (13:12 +0900)
committerKitae Kim <kt920.kim@samsung.com>
Thu, 10 Oct 2013 07:24:06 +0000 (16:24 +0900)
Change-Id: I8e71e07de47731ba77bf16a0a1d0299c69f64294
Signed-off-by: Jinhyung Choi <jinhyung2.choi@samsung.com>
tizen/src/guest_server.c
tizen/src/guest_server.h

index a9e44365d15e742624fef835578b70d41cd2e5f9..c8e0d536a5b80d317f173ef167a9269496fd9704 100644 (file)
 #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();
 }
index 0d55667c8b1a4643c02ca679c9609d1c9d1f6b5d..795f54bc531f34bbddd44f1acad6a765719597b5 100644 (file)
@@ -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_ */