#include <stdbool.h>
#include <pthread.h>
+#include <stdlib.h>
#include "hw/qdev.h"
#include "net/net.h"
next;
};
+#ifndef min
+#define min(a,b) ((a)<(b)?(a):(b))
+#endif
+
typedef struct mon_cmd_t {
const char *name;
const char *args_type;
QTAILQ_FOREACH(clii, &clients, next)
{
- send_to_client(clii->client_fd, data);
+ send_to_client(clii->client_fd, data, len);
}
pthread_mutex_unlock(&mutex_clilist);
return true;
}
-void send_to_client(int fd, const char *str) {
+
+void send_to_client(int fd, const char* data, const int len)
+{
+
+ ecs_write(fd, (const uint8_t*) data, len);
+}
+
+/*
+void send_to_client(int fd, const char* data, const int len)
+{
char c;
uint8_t outbuf[OUT_BUF_SIZE];
int outbuf_index = 0;
for (;;) {
- c = *str++;
+ c = *data++;
if (outbuf_index >= OUT_BUF_SIZE - 1) {
LOG("string is too long: overflow buffer.");
return;
}
ecs_write(fd, outbuf, outbuf_index);
}
+*/
#define QMP_ACCEPT_UNKNOWNS 1
static void ecs_monitor_flush(ECS_Client *clii, Monitor *mon) {
qdict_put(obj, "action", qint_from_int((int64_t )action));
}
-bool ntf_to_injector(const char* data, const int len) {
- type_length length = 0;
- type_group group = 0;
- type_action action = 0;
-
- const int catsize = 10;
- char cat[catsize + 1];
- memset(cat, 0, catsize + 1);
-
- read_val_str(data, cat, catsize);
- read_val_short(data + catsize, &length);
- read_val_char(data + catsize + 2, &group);
- read_val_char(data + catsize + 2 + 1, &action);
-
-
- const char* ijdata = (data + catsize + 2 + 1 + 1);
-
- char *encoded_ijdata = NULL;
- LOG("<< header cat = %s, length = %d, action=%d, group=%d", cat, length,
- action, group);
-
- if(!strcmp(cat, "telephony")) {
- base64_encode(ijdata, length, &encoded_ijdata);
- }
-
- QDict* obj_header = qdict_new();
- make_header(obj_header, length, group, action);
-
- QDict* objData = qdict_new();
- qobject_incref(QOBJECT(obj_header));
-
- qdict_put(objData, "cat", qstring_from_str(cat));
- qdict_put(objData, "header", obj_header);
- if(!strcmp(cat, "telephony")) {
- qdict_put(objData, "ijdata", qstring_from_str(encoded_ijdata));
- } else {
- qdict_put(objData, "ijdata", qstring_from_str(ijdata));
- }
-
- QDict* objMsg = qdict_new();
- qobject_incref(QOBJECT(objData));
-
- qdict_put(objMsg, "type", qstring_from_str("injector"));
- qdict_put(objMsg, "result", qstring_from_str("success"));
- qdict_put(objMsg, "data", objData);
-
- QString *json;
- json = qobject_to_json(QOBJECT(objMsg));
-
- assert(json != NULL);
-
- qstring_append_chr(json, '\n');
- const char* snddata = qstring_get_str(json);
-
- LOG("<< json str = %s", snddata);
-
- send_to_all_client(snddata, strlen(snddata));
-
- QDECREF(json);
-
- QDECREF(obj_header);
- QDECREF(objData);
- QDECREF(objMsg);
-
- return true;
-}
-
-bool send_injector_ntf(const char* data, const int len)
-{
- type_length length = 0;
- type_group group = 0;
- type_action action = 0;
-
- const int catsize = 10;
- char cat[catsize + 1];
- memset(cat, 0, catsize + 1);
-
- read_val_str(data, cat, catsize);
- read_val_short(data + catsize, &length);
- read_val_char(data + catsize + 2, &group);
- read_val_char(data + catsize + 2 + 1, &action);
-
-
- const char* ijdata = (data + catsize + 2 + 1 + 1);
- char *encoded_ijdata = NULL;
- LOG("<< header cat = %s, length = %d, action=%d, group=%d", cat, length,
- action, group);
-
- //if(!strcmp(cat, "telephony")) {
- // base64_encode(ijdata, length, &encoded_ijdata);
- //}
-
- ECS__Master master = ECS__MASTER__INIT;
- ECS__InjectorNtf ntf = ECS__INJECTOR_NTF__INIT;
-
- strncpy(ntf.category, cat, 10);
- ntf.length = length;
- ntf.group = group;
- ntf.action = action;
-
- memcpy(ntf.data.data, ijdata, length);
-
- master.injector_ntf = &ntf;
-
- int len_pack = ecs__master__get_packed_size(&master);
- void* buf = malloc(len_pack);
- ecs__master__pack(&master, buf);
-
- send_to_all_client(buf, len_pack);
-
- if (buf)
- {
- free(buf);
- }
-//
- return true;
-}
bool ntf_to_control(const char* data, const int len) {
return true;
static int ijcount = 0;
-static bool msgproc_start_req(ECS_Client* ccli, ECS__StartReq* msg)
-{
-
- return true;
-}
-
-static bool msgproc_injector_req(ECS_Client* ccli, ECS__InjectorReq* msg)
-{
- char cmd[10];
- memset(cmd, 0, 10);
- strcpy(cmd, msg->category);
- type_length length = (type_length) msg->length;
- type_group group = (type_group) (msg->group & 0xff);
- type_action action = (type_action) (msg->action & 0xff);
-
- const char* data = msg->data.data;
- //LOG(">> count= %d", ++ijcount);
- LOG(">> print len = %d, data\" %s\"", strlen(data), data);
- LOG(">> header = cmd = %s, length = %d, action=%d, group=%d", cmd, length,
- action, group);
-
- //int datalen = strlen(data);
- int datalen = msg->data.len;
- int sndlen = datalen + 14;
- char* sndbuf = (char*) malloc(sndlen + 1);
- if (!sndbuf) {
- return false;
- }
-
- memset(sndbuf, 0, sndlen + 1);
-
- // set data
- memcpy(sndbuf, cmd, 10);
- memcpy(sndbuf + 10, &length, 2);
- memcpy(sndbuf + 12, &group, 1);
- memcpy(sndbuf + 13, &action, 1);
- memcpy(sndbuf + 14, data, datalen);
-
- send_to_evdi(route_ij, sndbuf, sndlen);
-
- free(sndbuf);
-
- return true;
-}
-
-static bool msgproc_control_req(ECS_Client *ccli, ECS__ControlReq* msg)
-{
-
- return true;
-}
-
-static bool msgproc_monitor_req(ECS_Client *ccli, ECS__MonitorReq* msg)
-{
-
- return true;
-}
-
-static bool msgproc_screen_dump_req(ECS_Client *ccli, ECS__ScreenDumpReq* msg)
-{
-
- return true;
-}
static bool injector_command_proc(ECS_Client *clii, QObject *obj) {
QDict* header = qdict_get_qdict(qobject_to_qdict(obj), "header");
} else if (!strcmp(type_name, COMMAND_TYPE_DEVICE)) {
device_command_proc(clii, obj);
} else if (!strcmp(type_name, ECS_MSG_STARTINFO_REQ)) {
- ecs_startinfo_req(clii);
+ //ecs_startinfo_req(clii);
} else {
LOG("handler not found");
}
}
#endif
-static void ecs_read(ECS_Client *clii) {
- uint8_t buf[READ_BUF_LEN];
- int len, size;
- len = sizeof(buf);
- memset(buf, 0, READ_BUF_LEN);
- if (!clii || 0 > clii->client_fd) {
- LOG("read client info is NULL.");
+static void reset_sbuf(sbuf* sbuf)
+{
+ memset(sbuf->_buf, 0, 4096);
+ sbuf->_use = 0;
+ sbuf->_netlen = 0;
+}
+
+static void ecs_read(ECS_Client *cli) {
+
+ int read = 0;
+ int to_read_bytes = 0;
+ if (ioctl(cli->client_fd, FIONREAD, &to_read_bytes) < 0)
+ {
+ LOG("ioctl failed");
return;
}
- size = ecs_recv(clii->client_fd, (char*) buf, len);
- if (0 == size) {
- ecs_client_close(clii);
- } else if (0 < size) {
- LOG("read data: %s, len: %d, size: %d\n", buf, len, size);
-
- handle_protobuf_msg(clii, (char*)buf, size);
-
- //ecs_json_message_parser_feed(&clii->parser, (const char *) buf, size);
+ LOG("ioctl FIONREAD: %d\n", to_read_bytes);
+ if (to_read_bytes == 0)
+ goto fail;
+
+
+ if (cli->sbuf._netlen == 0)
+ {
+ if (to_read_bytes < 4)
+ {
+ LOG("insufficient data size to read");
+ return;
+ }
+
+ long payloadsize = 0;
+ read = ecs_recv(cli->client_fd, (char*) &payloadsize, 4);
+
+ if (read < 4)
+ {
+ LOG("insufficient header size");
+ goto fail;
+ }
+
+ payloadsize = ntohl(payloadsize);
+
+ cli->sbuf._netlen = payloadsize;
+
+ LOG("payload size: %ld\n", payloadsize);
+
+ to_read_bytes -= 4;
}
+
+ if (to_read_bytes == 0)
+ return;
+
+
+ to_read_bytes = min(to_read_bytes, cli->sbuf._netlen - cli->sbuf._use);
+
+ read = ecs_recv(cli->client_fd, (char*)(cli->sbuf._buf + cli->sbuf._use), to_read_bytes);
+ if (read == 0)
+ goto fail;
+
+
+ cli->sbuf._use += read;
+
+
+ if (cli->sbuf._netlen == cli->sbuf._use)
+ {
+ handle_protobuf_msg(cli, (char*)cli->sbuf._buf, cli->sbuf._use);
+ reset_sbuf(&cli->sbuf);
+ }
+
+ return;
+fail:
+ ecs_client_close(cli);
}
#ifndef _WIN32
return -1;
}
+ reset_sbuf(&clii->sbuf);
+
qemu_set_nonblock(fd);
clii->client_fd = fd;
welcome = WELCOME_MESSAGE;
- send_to_client(fd, welcome);
+ //send_to_client(fd, welcome);
pthread_mutex_unlock(&mutex_clilist);
return;
}
+ /*
QTAILQ_FOREACH(clii, &clients, next)
{
if (1 == clii->keep_alive) {
qemu_mod_timer(cs->alive_timer,
qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() * TIMER_ALIVE_S);
+ */
}
static int socket_initialize(ECS_State *cs, QemuOpts *opts) {
#include "qapi/qmp/qerror.h"
#include "qemu-common.h"
#include "ecs-json-streamer.h"
+#include "genmsg/ecs.pb-c.h"
#define ECS_DEBUG 1
#define READ_BUF_LEN 4096
+
+typedef struct sbuf
+{
+ int _netlen;
+ int _use;
+ char _buf[4096];
+}sbuf;
+
+
struct Monitor {
int suspend_cnt;
uint8_t outbuf[OUT_BUF_SIZE];
int client_id;
int keep_alive;
const char* type;
+
+ sbuf sbuf;
+
ECS_State *cs;
JSONMessageParser parser;
QTAILQ_ENTRY(ECS_Client) next;
bool handle_protobuf_msg(ECS_Client* cli, char* data, const int len);
+
bool ntf_to_injector(const char* data, const int len);
bool ntf_to_control(const char* data, const int len);
bool ntf_to_monitor(const char* data, const int len);
+
+bool send_to_ecp(ECS__Master* master);
+
+bool send_start_ans(int host_keyboard_onff);
bool send_injector_ntf(const char* data, const int len);
bool send_control_ntf(const char* data, const int len);
bool send_monitor_ntf(const char* data, const int len);
bool send_to_all_client(const char* data, const int len);
-void send_to_client(int fd, const char *str);
+void send_to_client(int fd, const char* data, const int len) ;
void make_header(QDict* obj, type_length length, type_group group, type_action action);
void read_val_str(const char* data, char* ret_val, int len);
+bool msgproc_start_req(ECS_Client* ccli, ECS__StartReq* msg);
+bool msgproc_injector_req(ECS_Client* ccli, ECS__InjectorReq* msg);
+bool msgproc_control_req(ECS_Client *ccli, ECS__ControlReq* msg);
+bool msgproc_monitor_req(ECS_Client *ccli, ECS__MonitorReq* msg);
+bool msgproc_screen_dump_req(ECS_Client *ccli, ECS__ScreenDumpReq* msg);
+
enum{
CONTROL_COMMAND_HOST_KEYBOARD_ONOFF_REQ = 1,
};
// messages
-void ecs_startinfo_req(ECS_Client *clii);
+//void ecs_startinfo_req(ECS_Client *clii);
void control_host_keyboard_onoff_req(ECS_Client *clii, QDict* data);
void set_sensor_data(int length, const char* data);
#include "hw/maru_virtio_evdi.h"\r
#include "skin/maruskin_operation.h"\r
\r
+// utility functions\r
+\r
+void* build_master(ECS__Master* master, int* payloadsize)\r
+{\r
+ int len_pack = ecs__master__get_packed_size(master);\r
+ *payloadsize = len_pack + 4;\r
+ LOG("pack size=%d", len_pack);\r
+ void* buf = g_malloc(len_pack + 4);\r
+ if (!buf)\r
+ return NULL;\r
+\r
+ ecs__master__pack(master, buf + 4);\r
+\r
+ len_pack = htonl(len_pack);\r
+ memcpy(buf, &len_pack, 4);\r
+\r
+ return buf;\r
+}\r
+\r
+bool send_to_ecp(ECS__Master* master)\r
+{\r
+ int payloadsize = 0;\r
+ void* buf = build_master(master, &payloadsize);\r
+ if (!buf)\r
+ {\r
+ LOG("invalid buf");\r
+ return false;\r
+ }\r
+\r
+ if (!send_to_all_client(buf, payloadsize))\r
+ return false;\r
+\r
+ if (buf)\r
+ {\r
+ g_free(buf);\r
+ }\r
+ return true;\r
+}\r
+\r
+\r
+// message handlers\r
+\r
+\r
+bool msgproc_start_req(ECS_Client* ccli, ECS__StartReq* msg)\r
+{\r
+ LOG("ecs_startinfo_req");\r
+\r
+\r
+ int hostkbd_status = mloop_evcmd_get_hostkbd_status();\r
+\r
+ LOG("hostkbd_status = %d", hostkbd_status);\r
+\r
+ send_start_ans(hostkbd_status);\r
+\r
+ return true;\r
+}\r
+\r
+bool msgproc_injector_req(ECS_Client* ccli, ECS__InjectorReq* msg)\r
+{\r
+ char cmd[10];\r
+ memset(cmd, 0, 10);\r
+ strcpy(cmd, msg->category);\r
+ type_length length = (type_length) msg->length;\r
+ type_group group = (type_group) (msg->group & 0xff);\r
+ type_action action = (type_action) (msg->action & 0xff);\r
+\r
+\r
+ int datalen = 0;\r
+ if (msg->has_data)\r
+ {\r
+ datalen = msg->data.len;\r
+ }\r
+ //LOG(">> count= %d", ++ijcount);\r
+\r
+ LOG(">> header = cmd = %s, length = %d, action=%d, group=%d", cmd, length,\r
+ action, group);\r
+\r
+\r
+ int sndlen = datalen + 14;\r
+ char* sndbuf = (char*) g_malloc(sndlen + 1);\r
+ if (!sndbuf) {\r
+ return false;\r
+ }\r
+\r
+ memset(sndbuf, 0, sndlen + 1);\r
+\r
+ // set data\r
+ memcpy(sndbuf, cmd, 10);\r
+ memcpy(sndbuf + 10, &length, 2);\r
+ memcpy(sndbuf + 12, &group, 1);\r
+ memcpy(sndbuf + 13, &action, 1);\r
+\r
+\r
+ if (msg->has_data)\r
+ {\r
+ if (msg->data.data && msg->data.len > 0)\r
+ {\r
+ const char* data = msg->data.data;\r
+ memcpy(sndbuf + 14, data, datalen);\r
+ LOG(">> print len = %d, data\" %s\"", strlen(data), data);\r
+ }\r
+ }\r
+\r
+\r
+ send_to_evdi(route_ij, sndbuf, sndlen);\r
+\r
+ g_free(sndbuf);\r
+\r
+ return true;\r
+}\r
+\r
+bool msgproc_control_req(ECS_Client *ccli, ECS__ControlReq* msg)\r
+{\r
+\r
+ return true;\r
+}\r
+\r
+bool msgproc_monitor_req(ECS_Client *ccli, ECS__MonitorReq* msg)\r
+{\r
+\r
+ return true;\r
+}\r
+\r
+bool msgproc_screen_dump_req(ECS_Client *ccli, ECS__ScreenDumpReq* msg)\r
+{\r
+\r
+ return true;\r
+}\r
+\r
+/*\r
void ecs_startinfo_req(ECS_Client *clii)\r
{\r
LOG("ecs_startinfo_req");\r
QDECREF(objData);\r
QDECREF(objMsg);\r
}\r
+*/\r
\r
void control_host_keyboard_onoff_req(ECS_Client *clii, QDict* data)\r
{\r
\r
QDECREF(objMsg);\r
}\r
+\r
+\r
+//\r
+\r
+bool ntf_to_injector(const char* data, const int len) {\r
+ type_length length = 0;\r
+ type_group group = 0;\r
+ type_action action = 0;\r
+\r
+ const int catsize = 10;\r
+ char cat[catsize + 1];\r
+ memset(cat, 0, catsize + 1);\r
+\r
+ read_val_str(data, cat, catsize);\r
+ read_val_short(data + catsize, &length);\r
+ read_val_char(data + catsize + 2, &group);\r
+ read_val_char(data + catsize + 2 + 1, &action);\r
+\r
+\r
+ const char* ijdata = (data + catsize + 2 + 1 + 1);\r
+\r
+ char *encoded_ijdata = NULL;\r
+ LOG("<< header cat = %s, length = %d, action=%d, group=%d", cat, length,\r
+ action, group);\r
+\r
+ if(!strcmp(cat, "telephony")) {\r
+ base64_encode(ijdata, length, &encoded_ijdata);\r
+ }\r
+\r
+ QDict* obj_header = qdict_new();\r
+ make_header(obj_header, length, group, action);\r
+\r
+ QDict* objData = qdict_new();\r
+ qobject_incref(QOBJECT(obj_header));\r
+\r
+ qdict_put(objData, "cat", qstring_from_str(cat));\r
+ qdict_put(objData, "header", obj_header);\r
+ if(!strcmp(cat, "telephony")) {\r
+ qdict_put(objData, "ijdata", qstring_from_str(encoded_ijdata));\r
+ } else {\r
+ qdict_put(objData, "ijdata", qstring_from_str(ijdata));\r
+ }\r
+\r
+ QDict* objMsg = qdict_new();\r
+ qobject_incref(QOBJECT(objData));\r
+\r
+ qdict_put(objMsg, "type", qstring_from_str("injector"));\r
+ qdict_put(objMsg, "result", qstring_from_str("success"));\r
+ qdict_put(objMsg, "data", objData);\r
+\r
+ QString *json;\r
+ json = qobject_to_json(QOBJECT(objMsg));\r
+\r
+ assert(json != NULL);\r
+\r
+ qstring_append_chr(json, '\n');\r
+ const char* snddata = qstring_get_str(json);\r
+\r
+ LOG("<< json str = %s", snddata);\r
+\r
+ send_to_all_client(snddata, strlen(snddata));\r
+\r
+ QDECREF(json);\r
+\r
+ QDECREF(obj_header);\r
+ QDECREF(objData);\r
+ QDECREF(objMsg);\r
+\r
+ return true;\r
+}\r
+\r
+bool send_start_ans(int host_keyboard_onff)\r
+{\r
+ ECS__Master master = ECS__MASTER__INIT;\r
+ ECS__StartAns ans = ECS__START_ANS__INIT;\r
+\r
+ ans.host_keyboard_onoff = host_keyboard_onff;\r
+\r
+ master.start_ans = &ans;\r
+\r
+ return send_to_ecp(&master);\r
+}\r
+\r
+bool send_injector_ntf(const char* data, const int len)\r
+{\r
+ type_length length = 0;\r
+ type_group group = 0;\r
+ type_action action = 0;\r
+\r
+ const int catsize = 10;\r
+ char cat[catsize + 1];\r
+ memset(cat, 0, catsize + 1);\r
+\r
+ read_val_str(data, cat, catsize);\r
+ read_val_short(data + catsize, &length);\r
+ read_val_char(data + catsize + 2, &group);\r
+ read_val_char(data + catsize + 2 + 1, &action);\r
+\r
+\r
+ const char* ijdata = (data + catsize + 2 + 1 + 1);\r
+\r
+ LOG("<< header cat = %s, length = %d, action=%d, group=%d", cat, length,action, group);\r
+\r
+ ECS__Master master = ECS__MASTER__INIT;\r
+ ECS__InjectorNtf ntf = ECS__INJECTOR_NTF__INIT;\r
+\r
+ ntf.category = (char*) g_malloc(catsize + 1);\r
+ strncpy(ntf.category, cat, 10);\r
+\r
+\r
+ ntf.length = length;\r
+ ntf.group = group;\r
+ ntf.action = action;\r
+\r
+ if (length > 0)\r
+ {\r
+ ntf.has_data = 1;\r
+\r
+ ntf.data.data = g_malloc(length);\r
+ ntf.data.len = length;\r
+ memcpy(ntf.data.data, ijdata, length);\r
+ }\r
+\r
+ master.type = ECS__MASTER__TYPE__INJECTOR_NTF;\r
+ master.injector_ntf = &ntf;\r
+\r
+ send_to_ecp(&master);\r
+\r
+ if (ntf.data.data && ntf.data.len > 0)\r
+ {\r
+ g_free(ntf.data.data);\r
+ }\r
+\r
+ if (ntf.category)\r
+ g_free(ntf.category);\r
+\r
+ return true;\r
+}\r
(ProtobufCMessageInit) ecs__start_req__init,
NULL,NULL,NULL /* reserved[123] */
};
-static const ProtobufCFieldDescriptor ecs__start_ans__field_descriptors[0] =
+static const ProtobufCFieldDescriptor ecs__start_ans__field_descriptors[1] =
{
+ {
+ "host_keyboard_onoff",
+ 1,
+ PROTOBUF_C_LABEL_OPTIONAL,
+ PROTOBUF_C_TYPE_INT32,
+ PROTOBUF_C_OFFSETOF(ECS__StartAns, has_host_keyboard_onoff),
+ PROTOBUF_C_OFFSETOF(ECS__StartAns, host_keyboard_onoff),
+ NULL,
+ NULL,
+ 0, /* packed */
+ 0,NULL,NULL /* reserved1,reserved2, etc */
+ },
};
static const unsigned ecs__start_ans__field_indices_by_name[] = {
+ 0, /* field[0] = host_keyboard_onoff */
+};
+static const ProtobufCIntRange ecs__start_ans__number_ranges[1 + 1] =
+{
+ { 1, 0 },
+ { 0, 1 }
};
-#define ecs__start_ans__number_ranges NULL
const ProtobufCMessageDescriptor ecs__start_ans__descriptor =
{
PROTOBUF_C_MESSAGE_DESCRIPTOR_MAGIC,
"ECS__StartAns",
"ECS",
sizeof(ECS__StartAns),
- 0,
+ 1,
ecs__start_ans__field_descriptors,
ecs__start_ans__field_indices_by_name,
- 0, ecs__start_ans__number_ranges,
+ 1, ecs__start_ans__number_ranges,
(ProtobufCMessageInit) ecs__start_ans__init,
NULL,NULL,NULL /* reserved[123] */
};
struct _ECS__StartAns
{
ProtobufCMessage base;
+ protobuf_c_boolean has_host_keyboard_onoff;
+ int32_t host_keyboard_onoff;
};
#define ECS__START_ANS__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&ecs__start_ans__descriptor) \
- }
+ , 0,0 }
struct _ECS__Master
vio_evdi = VIRTIO_EVDI(vdev);
- virtio_init(vdev, EVDI_DEVICE_NAME, VIRTIO_ID_EVDI, 0);
+ virtio_init(vdev, TYPE_VIRTIO_EVDI, VIRTIO_ID_EVDI, 0); //EVDI_DEVICE_NAME
if (vio_evdi == NULL) {
ERR("failed to initialize evdi device\n");
}
message StartAns {
-
+ optional int32 host_keyboard_onoff = 1;
}
message Master {
--- /dev/null
+#!/bin/sh
+
+
+protoc-c --c_out=../genmsg ecs.proto