From: DaiYoung Kim Date: Tue, 16 Apr 2013 09:14:50 +0000 (+0900) Subject: evdi : evdi interact with ecs X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.1~875^2~21 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ca6625fd3c99f4e8b62304ac4ff7a0cdaf8ab2e5;p=sdk%2Femulator%2Fqemu.git evdi : evdi interact with ecs Signed-off-by: DaiYoung, Kim --- diff --git a/tizen/src/ecs.c b/tizen/src/ecs.c old mode 100644 new mode 100755 index efad448dee..ddc44a7dab --- a/tizen/src/ecs.c +++ b/tizen/src/ecs.c @@ -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)); } diff --git a/tizen/src/ecs.h b/tizen/src/ecs.h old mode 100644 new mode 100755 index 7fb1f30148..4c16ffc27d --- a/tizen/src/ecs.h +++ b/tizen/src/ecs.h @@ -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__ */ diff --git a/tizen/src/hw/maru_virtio_evdi.c b/tizen/src/hw/maru_virtio_evdi.c index 01d54ebf51..7985f0e234 100755 --- a/tizen/src/hw/maru_virtio_evdi.c +++ b/tizen/src/hw/maru_virtio_evdi.c @@ -26,25 +26,28 @@ * */ +#include + #include "maru_device_ids.h" #include "maru_virtio_evdi.h" #include "debug_ch.h" +#include "../ecs.h" MULTI_DEBUG_CHANNEL(qemu, virtio-evdi); #define VIRTIO_EVDI_DEVICE_NAME "virtio-evdi" -#define __MAX_BUF_SIZE 1024 enum { IOTYPE_INPUT = 0, IOTYPE_OUTPUT = 1 }; -struct msg_info { - char buf[__MAX_BUF_SIZE]; - uint32_t use; -}; + +#ifndef min +#define min(a,b) ((a)<(b)?(a):(b)) +#endif + typedef struct VirtIO_EVDI{ VirtIODevice vdev; @@ -58,8 +61,172 @@ typedef struct VirtIO_EVDI{ VirtIO_EVDI* vio_evdi; -static int g_cnt = 0; + +// + +typedef struct MsgInfo +{ + msg_info info; + QTAILQ_ENTRY(MsgInfo) next; +}MsgInfo; + +static QTAILQ_HEAD(MsgInfoRecvHead , MsgInfo) evdi_recv_msg_queue = + QTAILQ_HEAD_INITIALIZER(evdi_recv_msg_queue); + + +static QTAILQ_HEAD(MsgInfoSendHead , MsgInfo) evdi_send_msg_queue = + QTAILQ_HEAD_INITIALIZER(evdi_send_msg_queue); + + +// + +typedef struct EvdiBuf { + VirtQueueElement elem; + + QTAILQ_ENTRY(EvdiBuf) next; +} EvdiBuf; + +static QTAILQ_HEAD(EvdiMsgHead , EvdiBuf) evdi_in_queue = + QTAILQ_HEAD_INITIALIZER(evdi_in_queue); + + +static pthread_mutex_t recv_buf_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t send_buf_mutex = PTHREAD_MUTEX_INITIALIZER; + +/* +bool queue_evdi_buf(VirtIO_EVDI* evdi) +{ + int sg_idx; + EvdiBuf* ebuf = malloc(sizeof(EvdiBuf)); + + while (sg_idx = virtqueue_pop(evdi->rvq, &ebuf->elem)) + + INFO(">> QueueEvdiBuf : sg_idx = %d\n", sg_idx); + + + pthread_mutex_lock(&recv_buf_mutex); + + QTAILQ_INSERT_TAIL(&evdi_in_queue, ebuf, next); + qemu_bh_schedule(evdi->bh); + + pthread_mutex_unlock(&recv_buf_mutex); +} +*/ +/* +void reset_msg_info(msg_info* info) +{ + info->route = route_ij; + info->use = 0; + info->count = 0; + info->index = 0; + +} +*/ + +bool send_to_evdi(const uint32_t route, char* data, const uint32_t len) +{ + int size; + int left = len; + int count = 0; + char* readptr = data; + + while (left > 0) + { + MsgInfo* _msg = (MsgInfo*) malloc(sizeof(MsgInfo)); + if (!_msg) + return false; + + memset(&_msg->info, 0, sizeof(msg_info)); + + size = min(left, __MAX_BUF_SIZE); + memcpy(_msg->info.buf, readptr, size); + readptr += size; + _msg->info.use = size; + _msg->info.index = count; + + pthread_mutex_lock(&recv_buf_mutex); + + QTAILQ_INSERT_TAIL(&evdi_recv_msg_queue, _msg, next); + + pthread_mutex_unlock(&recv_buf_mutex); + + left -= size; + count ++; + } + + qemu_bh_schedule(vio_evdi->bh); + + return true; +} + + +//static int g_cnt = 0; + +static void flush_evdi_recv_queue(void) +{ + int index; + TRACE("nothing to do.\n"); + + if (unlikely(!virtio_queue_ready(vio_evdi->rvq))) { + INFO("virtio queue is not ready\n"); + return; + } + + if (unlikely(virtio_queue_empty(vio_evdi->rvq))) { + TRACE("virtqueue is empty\n"); + return; + } + + + pthread_mutex_lock(&recv_buf_mutex); + + while (!QTAILQ_EMPTY(&evdi_recv_msg_queue)) + { + MsgInfo* msginfo = QTAILQ_FIRST(&evdi_recv_msg_queue); + if (!msginfo) + break; + + VirtQueueElement elem; + index = virtqueue_pop(vio_evdi->rvq, &elem); + if (index == 0) + { + ERR("unexpected empty queue"); + break; + } + + INFO(">> virtqueue_pop. index: %d, out_num : %d, in_num : %d\n", index, elem.out_num, elem.in_num); + + memcpy(elem.in_sg[0].iov_base, &msginfo->info, sizeof(struct msg_info)); + + INFO(">> send to guest use = %d, msg = %s, iov_len = %d \n", + msginfo->info.use, msginfo->info.buf, elem.in_sg[0].iov_len); + + virtqueue_push(vio_evdi->rvq, &elem, sizeof(msg_info)); + virtio_notify(&vio_evdi->vdev, vio_evdi->rvq); + + QTAILQ_REMOVE(&evdi_recv_msg_queue, msginfo, next); + if (msginfo) + free(msginfo); + } + + pthread_mutex_unlock(&recv_buf_mutex); + +} + +static void virtio_evdi_recv(VirtIODevice *vdev, VirtQueue *vq) +{ + INFO(">> evdirecv : virtio_evdi_recv\n"); + + if (!QTAILQ_EMPTY(&evdi_recv_msg_queue)) + return; + + flush_evdi_recv_queue(); + + INFO("enf of virtio_evdi_recv\n"); +} + +/* static void virtio_evdi_recv(VirtIODevice *vdev, VirtQueue *vq) { int index = 0; @@ -108,7 +275,45 @@ static void virtio_evdi_recv(VirtIODevice *vdev, VirtQueue *vq) INFO("enf of virtio_evdi_recv\n"); } +*/ +static void virtio_evdi_send(VirtIODevice *vdev, VirtQueue *vq) +{ + VirtIO_EVDI *vevdi = (VirtIO_EVDI *)vdev; + int index = 0; + struct msg_info _msg; + + if (virtio_queue_empty(vevdi->svq)) { + INFO("<< virtqueue is empty.\n"); + return; + } + + VirtQueueElement elem; + + while ((index = virtqueue_pop(vq, &elem))) { + + INFO("<< virtqueue pop. index: %d, out_num : %d, in_num : %d\n", index, elem.out_num, elem.in_num); + + if (index == 0) { + INFO("<< virtqueue break\n"); + break; + } + + INFO("<< use=%d, iov_len = %d\n", _msg.use, elem.out_sg[0].iov_len); + + memset(&_msg, 0x00, sizeof(_msg)); + memcpy(&_msg, elem.out_sg[0].iov_base, elem.out_sg[0].iov_len); + + INFO("<< recv from guest len = %d, msg = %s \n", _msg.use, _msg.buf); + + send_to_all_client(_msg.buf, _msg.use); + } + + virtqueue_push(vq, &elem, sizeof(VirtIO_EVDI)); + virtio_notify(&vio_evdi->vdev, vq); +} + +/* static void virtio_evdi_send(VirtIODevice *vdev, VirtQueue *vq) { VirtIO_EVDI *vevdi = (VirtIO_EVDI *)vdev; @@ -144,11 +349,7 @@ static void virtio_evdi_send(VirtIODevice *vdev, VirtQueue *vq) virtqueue_push(vq, &elem, sizeof(VirtIO_EVDI)); virtio_notify(&vio_evdi->vdev, vq); } - -static void maru_virtio_evdi_notify(void) -{ - TRACE("nothing to do.\n"); -} +*/ static uint32_t virtio_evdi_get_features(VirtIODevice *vdev, uint32_t request_feature) @@ -159,7 +360,7 @@ static uint32_t virtio_evdi_get_features(VirtIODevice *vdev, static void maru_evdi_bh(void *opaque) { - maru_virtio_evdi_notify(); + flush_evdi_recv_queue(); } VirtIODevice *virtio_evdi_init(DeviceState *dev) diff --git a/tizen/src/hw/maru_virtio_evdi.h b/tizen/src/hw/maru_virtio_evdi.h index ad88b682d4..ecdb6cb19d 100755 --- a/tizen/src/hw/maru_virtio_evdi.h +++ b/tizen/src/hw/maru_virtio_evdi.h @@ -14,9 +14,39 @@ extern "C" { #include "hw/virtio.h" + +/* device protocol */ + +#define __MAX_BUF_SIZE 1024 + +enum +{ + route_qemu = 0, + route_control_server = 1, + route_monitor = 2, + route_ij = 3 +}; + +typedef unsigned int CSCliSN; + +typedef struct msg_info { + char buf[__MAX_BUF_SIZE]; + + uint32_t route; + uint32_t use; + uint16_t count; + uint16_t index; + + CSCliSN cclisn; +}msg_info; + +/* device protocol */ + + VirtIODevice *virtio_evdi_init(DeviceState *dev); void virtio_evdi_exit(VirtIODevice *vdev); +bool send_to_evdi(const uint32_t route, char* data, const uint32_t len); #ifdef __cplusplus }