evdi : evdi interact with ecs
authorDaiYoung Kim <daiyoung777.kim@samsung.com>
Tue, 16 Apr 2013 09:14:50 +0000 (18:14 +0900)
committerDaiYoung Kim <daiyoung777.kim@samsung.com>
Tue, 16 Apr 2013 09:14:50 +0000 (18:14 +0900)
Signed-off-by: DaiYoung, Kim <daiyoung777.kim@samsung.com>
tizen/src/ecs.c [changed mode: 0644->0755]
tizen/src/ecs.h [changed mode: 0644->0755]
tizen/src/hw/maru_virtio_evdi.c
tizen/src/hw/maru_virtio_evdi.h

old mode 100644 (file)
new mode 100755 (executable)
index efad448..ddc44a7
@@ -24,6 +24,7 @@
 #include "qmp-commands.h"
 
 #include "ecs.h"
+#include "hw/maru_virtio_evdi.h"
 
 #define OUT_BUF_SIZE   4096
 #define READ_BUF_LEN   4096
@@ -124,6 +125,19 @@ static void ecs_client_close(ECS_Client* clii)
        }
 }
 
+
+bool send_to_all_client(const char* data, const int len)
+{
+       ECS_Client *clii;
+
+       QTAILQ_FOREACH(clii, &clients, next)
+       {
+               send_to_client(clii->client_fd, data);
+       }
+
+       return true;
+}
+
 void send_to_client(int fd, const char *str)
 {
     char c;
@@ -736,11 +750,33 @@ static void handle_ecs_command(JSONMessageParser *parser, QList *tokens, void *o
                return;
        }
        
+
+       // send to evdi
+       data = qdict_get_str(qobject_to_qdict(obj), COMMANDS_DATA);
+       LOG("print data: %s, %d", data, strlen(data));
+
+       int datalen = strlen(data);
+       send_to_evdi(route_ij, data, datalen);
+
+       /*
        if (!strcmp(type_name, "Battery")) {
                data = qdict_get_str(qobject_to_qdict(obj), COMMANDS_DATA);
-               LOG("print data: %s", data);
+               LOG("print data: %s, %d", data, strlen(data));
+
+               int datalen = strlen(data);
+               send_to_evdi(route_ij, data, datalen);
+               return;
+       }
+
+       if (!strcmp(type_name, "Telephony")) {
+               data = qdict_get_str(qobject_to_qdict(obj), COMMANDS_DATA);
+               LOG("print data: %s, %d", data, strlen(data));
+
+               int datalen = strlen(data);
+               send_to_evdi(route_ij, data, datalen);
                return;
        }
+       */
 
        handle_qmp_command(clii, type_name, get_data_object(obj));
 }
old mode 100644 (file)
new mode 100755 (executable)
index 7fb1f30..4c16ffc
@@ -36,6 +36,7 @@ int stop_ecs(void);
 void ecs_vprintf(const char *type, const char *fmt, va_list ap);
 void ecs_printf(const char *type, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
 
+bool send_to_all_client(const char* data, const int len);
 void send_to_client(int fd, const char *str);
 
 #endif /* __ECS_H__ */
index 01d54eb..7985f0e 100755 (executable)
  *\r
  */\r
 \r
+#include <pthread.h>\r
+\r
 #include "maru_device_ids.h"\r
 #include "maru_virtio_evdi.h"\r
 #include "debug_ch.h"\r
+#include "../ecs.h"\r
 \r
 MULTI_DEBUG_CHANNEL(qemu, virtio-evdi);\r
 \r
 #define VIRTIO_EVDI_DEVICE_NAME "virtio-evdi"\r
 \r
-#define __MAX_BUF_SIZE 1024\r
 \r
 enum {\r
        IOTYPE_INPUT = 0,\r
        IOTYPE_OUTPUT = 1\r
 };\r
 \r
-struct msg_info {\r
-       char buf[__MAX_BUF_SIZE];\r
-       uint32_t use;\r
-};\r
+\r
+#ifndef min\r
+#define min(a,b) ((a)<(b)?(a):(b))\r
+#endif\r
+\r
 \r
 typedef struct VirtIO_EVDI{\r
     VirtIODevice    vdev;\r
@@ -58,10 +61,174 @@ typedef struct VirtIO_EVDI{
 \r
 VirtIO_EVDI* vio_evdi;\r
 \r
-static int g_cnt = 0;\r
+\r
+//\r
+\r
+typedef struct MsgInfo\r
+{\r
+       msg_info info;\r
+       QTAILQ_ENTRY(MsgInfo) next;\r
+}MsgInfo;\r
+\r
+static QTAILQ_HEAD(MsgInfoRecvHead , MsgInfo) evdi_recv_msg_queue =\r
+    QTAILQ_HEAD_INITIALIZER(evdi_recv_msg_queue);\r
+\r
+\r
+static QTAILQ_HEAD(MsgInfoSendHead , MsgInfo) evdi_send_msg_queue =\r
+    QTAILQ_HEAD_INITIALIZER(evdi_send_msg_queue);\r
+\r
+\r
+//\r
+\r
+typedef struct EvdiBuf {\r
+    VirtQueueElement elem;\r
+\r
+    QTAILQ_ENTRY(EvdiBuf) next;\r
+} EvdiBuf;\r
+\r
+static QTAILQ_HEAD(EvdiMsgHead , EvdiBuf) evdi_in_queue =\r
+    QTAILQ_HEAD_INITIALIZER(evdi_in_queue);\r
+\r
+\r
+static pthread_mutex_t recv_buf_mutex = PTHREAD_MUTEX_INITIALIZER;\r
+static pthread_mutex_t send_buf_mutex = PTHREAD_MUTEX_INITIALIZER;\r
+\r
+/*\r
+bool queue_evdi_buf(VirtIO_EVDI* evdi)\r
+{\r
+       int sg_idx;\r
+       EvdiBuf* ebuf = malloc(sizeof(EvdiBuf));\r
+\r
+       while (sg_idx = virtqueue_pop(evdi->rvq, &ebuf->elem))\r
+\r
+        INFO(">> QueueEvdiBuf : sg_idx = %d\n", sg_idx);\r
+\r
+\r
+       pthread_mutex_lock(&recv_buf_mutex);\r
+\r
+       QTAILQ_INSERT_TAIL(&evdi_in_queue, ebuf, next);\r
+       qemu_bh_schedule(evdi->bh);\r
+\r
+       pthread_mutex_unlock(&recv_buf_mutex);\r
+}\r
+*/\r
+/*\r
+void reset_msg_info(msg_info* info)\r
+{\r
+       info->route = route_ij;\r
+       info->use = 0;\r
+       info->count = 0;\r
+       info->index = 0;\r
+\r
+}\r
+*/\r
+\r
+bool send_to_evdi(const uint32_t route, char* data, const uint32_t len)\r
+{\r
+       int size;\r
+       int left = len;\r
+       int count = 0;\r
+       char* readptr = data;\r
+\r
+       while (left > 0)\r
+       {\r
+               MsgInfo* _msg = (MsgInfo*) malloc(sizeof(MsgInfo));\r
+               if (!_msg)\r
+                       return false;\r
+\r
+               memset(&_msg->info, 0, sizeof(msg_info));\r
+\r
+               size = min(left, __MAX_BUF_SIZE);\r
+               memcpy(_msg->info.buf, readptr, size);\r
+               readptr += size;\r
+               _msg->info.use = size;\r
+               _msg->info.index = count;\r
+\r
+               pthread_mutex_lock(&recv_buf_mutex);\r
+\r
+               QTAILQ_INSERT_TAIL(&evdi_recv_msg_queue, _msg, next);\r
+\r
+               pthread_mutex_unlock(&recv_buf_mutex);\r
+\r
+               left -= size;\r
+               count ++;\r
+       }\r
+\r
+       qemu_bh_schedule(vio_evdi->bh);\r
+\r
+       return true;\r
+}\r
+\r
+\r
+//static int g_cnt = 0;\r
+\r
+static void flush_evdi_recv_queue(void)\r
+{\r
+       int index;\r
+       TRACE("nothing to do.\n");\r
+\r
+    if (unlikely(!virtio_queue_ready(vio_evdi->rvq))) {\r
+        INFO("virtio queue is not ready\n");\r
+        return;\r
+    }\r
+\r
+       if (unlikely(virtio_queue_empty(vio_evdi->rvq))) {\r
+               TRACE("virtqueue is empty\n");\r
+               return;\r
+       }\r
+\r
+\r
+       pthread_mutex_lock(&recv_buf_mutex);\r
+\r
+       while (!QTAILQ_EMPTY(&evdi_recv_msg_queue))\r
+       {\r
+                MsgInfo* msginfo = QTAILQ_FIRST(&evdi_recv_msg_queue);\r
+                if (!msginfo)\r
+                        break;\r
+\r
+                VirtQueueElement elem;\r
+                index = virtqueue_pop(vio_evdi->rvq, &elem);\r
+                if (index == 0)\r
+                {\r
+                        ERR("unexpected empty queue");\r
+                        break;\r
+                }\r
+\r
+                INFO(">> virtqueue_pop. index: %d, out_num : %d, in_num : %d\n", index, elem.out_num, elem.in_num);\r
+\r
+                memcpy(elem.in_sg[0].iov_base, &msginfo->info, sizeof(struct msg_info));\r
+\r
+                INFO(">> send to guest use = %d, msg = %s, iov_len = %d \n",\r
+                                               msginfo->info.use, msginfo->info.buf, elem.in_sg[0].iov_len);\r
+\r
+                virtqueue_push(vio_evdi->rvq, &elem, sizeof(msg_info));\r
+                virtio_notify(&vio_evdi->vdev, vio_evdi->rvq);\r
+\r
+                QTAILQ_REMOVE(&evdi_recv_msg_queue, msginfo, next);\r
+                if (msginfo)\r
+                        free(msginfo);\r
+       }\r
+\r
+       pthread_mutex_unlock(&recv_buf_mutex);\r
+\r
+}\r
+\r
 \r
 static void virtio_evdi_recv(VirtIODevice *vdev, VirtQueue *vq)\r
 {\r
+      INFO(">> evdirecv : virtio_evdi_recv\n");\r
+\r
+    if (!QTAILQ_EMPTY(&evdi_recv_msg_queue))\r
+       return;\r
+\r
+    flush_evdi_recv_queue();\r
+\r
+    INFO("enf of virtio_evdi_recv\n");\r
+}\r
+\r
+/*\r
+static void virtio_evdi_recv(VirtIODevice *vdev, VirtQueue *vq)\r
+{\r
     int index = 0;\r
 \r
     struct msg_info _msg;\r
@@ -108,6 +275,7 @@ static void virtio_evdi_recv(VirtIODevice *vdev, VirtQueue *vq)
     INFO("enf of virtio_evdi_recv\n");\r
 }\r
 \r
+*/\r
 \r
 static void virtio_evdi_send(VirtIODevice *vdev, VirtQueue *vq)\r
 {\r
@@ -115,6 +283,43 @@ static void virtio_evdi_send(VirtIODevice *vdev, VirtQueue *vq)
     int index = 0;\r
     struct msg_info _msg;\r
 \r
+    if (virtio_queue_empty(vevdi->svq)) {\r
+        INFO("<< virtqueue is empty.\n");\r
+        return;\r
+    }\r
+\r
+    VirtQueueElement elem;\r
+\r
+    while ((index = virtqueue_pop(vq, &elem))) {\r
+\r
+               INFO("<< virtqueue pop. index: %d, out_num : %d, in_num : %d\n", index,  elem.out_num, elem.in_num);\r
+\r
+               if (index == 0) {\r
+                       INFO("<< virtqueue break\n");\r
+                       break;\r
+               }\r
+\r
+               INFO("<< use=%d, iov_len = %d\n", _msg.use, elem.out_sg[0].iov_len);\r
+\r
+               memset(&_msg, 0x00, sizeof(_msg));\r
+               memcpy(&_msg, elem.out_sg[0].iov_base, elem.out_sg[0].iov_len);\r
+\r
+               INFO("<< recv from guest len = %d, msg = %s \n", _msg.use, _msg.buf);\r
+\r
+               send_to_all_client(_msg.buf, _msg.use);\r
+    }\r
+\r
+       virtqueue_push(vq, &elem, sizeof(VirtIO_EVDI));\r
+       virtio_notify(&vio_evdi->vdev, vq);\r
+}\r
+\r
+/*\r
+static void virtio_evdi_send(VirtIODevice *vdev, VirtQueue *vq)\r
+{\r
+       VirtIO_EVDI *vevdi = (VirtIO_EVDI *)vdev;\r
+    int index = 0;\r
+    struct msg_info _msg;\r
+\r
     INFO("<< evdisend : virtio_evdi_send \n");\r
     if (virtio_queue_empty(vevdi->svq)) {\r
         INFO("<< evdisend : virtqueue is empty.\n");\r
@@ -144,11 +349,7 @@ static void virtio_evdi_send(VirtIODevice *vdev, VirtQueue *vq)
        virtqueue_push(vq, &elem, sizeof(VirtIO_EVDI));\r
        virtio_notify(&vio_evdi->vdev, vq);\r
 }\r
-\r
-static void maru_virtio_evdi_notify(void)\r
-{\r
-       TRACE("nothing to do.\n");\r
-}\r
+*/\r
 \r
 static uint32_t virtio_evdi_get_features(VirtIODevice *vdev,\r
                                             uint32_t request_feature)\r
@@ -159,7 +360,7 @@ static uint32_t virtio_evdi_get_features(VirtIODevice *vdev,
 \r
 static void maru_evdi_bh(void *opaque)\r
 {\r
-    maru_virtio_evdi_notify();\r
+       flush_evdi_recv_queue();\r
 }\r
 \r
 VirtIODevice *virtio_evdi_init(DeviceState *dev)\r
index ad88b68..ecdb6cb 100755 (executable)
@@ -14,9 +14,39 @@ extern "C" {
 \r
 #include "hw/virtio.h"\r
 \r
+\r
+/* device protocol */\r
+\r
+#define __MAX_BUF_SIZE 1024\r
+\r
+enum\r
+{\r
+       route_qemu = 0,\r
+       route_control_server = 1,\r
+       route_monitor = 2,\r
+       route_ij = 3\r
+};\r
+\r
+typedef unsigned int CSCliSN;\r
+\r
+typedef struct msg_info {\r
+       char buf[__MAX_BUF_SIZE];\r
+\r
+       uint32_t route;\r
+       uint32_t use;\r
+       uint16_t count;\r
+       uint16_t index;\r
+\r
+       CSCliSN cclisn;\r
+}msg_info;\r
+\r
+/* device protocol */\r
+\r
+\r
 VirtIODevice *virtio_evdi_init(DeviceState *dev);\r
 \r
 void virtio_evdi_exit(VirtIODevice *vdev);\r
+bool send_to_evdi(const uint32_t route, char* data, const uint32_t len);\r
 \r
 #ifdef __cplusplus\r
 }\r