2 * Emulator Control Server
4 * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
7 * Jinhyung choi <jinhyung2.choi@samsung.com>
8 * MunKyu Im <munkyu.im@samsung.com>
9 * Daiyoung Kim <daiyoung777.kim@samsung.com>
10 * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
37 #include "ui/console.h"
39 #include "qemu-common.h"
40 #include "qemu/queue.h"
41 #include "qemu/sockets.h"
42 #include "qemu/option.h"
43 #include "qemu/timer.h"
44 #include "qemu/main-loop.h"
45 #include "sysemu/char.h"
47 #include "qapi/qmp/qint.h"
51 #include "guest_server.h"
52 #include "emul_state.h"
54 #include "genmsg/ecs.pb-c.h"
57 MULTI_DEBUG_CHANNEL(qemu, ecs);
62 #define min(a,b) ((a)<(b)?(a):(b))
65 static QTAILQ_HEAD(ECS_ClientHead, ECS_Client)
66 clients = QTAILQ_HEAD_INITIALIZER(clients);
68 static ECS_State *current_ecs;
70 static void* keepalive_buf;
71 static int payloadsize;
73 static int g_client_id = 1;
75 static pthread_mutex_t mutex_clilist = PTHREAD_MUTEX_INITIALIZER;
77 static int suspend_state = 1;
79 void ecs_set_suspend_state(int state)
81 suspend_state = state;
84 int ecs_get_suspend_state(void)
89 int ecs_write(int fd, const uint8_t *buf, int len) {
90 TRACE("write buflen : %d, buf : %s", len, (char*)buf);
95 return send_all(fd, buf, len);
98 void ecs_client_close(ECS_Client* clii) {
102 pthread_mutex_lock(&mutex_clilist);
104 if (clii->client_fd > 0) {
105 INFO("ecs client closed with fd: %d", clii->client_fd);
106 closesocket(clii->client_fd);
108 FD_CLR(clii->client_fd, &clii->cs->reads);
110 clii->client_fd = -1;
113 QTAILQ_REMOVE(&clients, clii, next);
118 pthread_mutex_unlock(&mutex_clilist);
121 bool send_to_all_client(const char* data, const int len) {
122 TRACE("data len: %d, data: %s", len, data);
123 pthread_mutex_lock(&mutex_clilist);
127 QTAILQ_FOREACH(clii, &clients, next)
129 send_to_client(clii->client_fd, data, len);
131 pthread_mutex_unlock(&mutex_clilist);
136 void send_to_single_client(ECS_Client *clii, const char* data, const int len)
138 pthread_mutex_lock(&mutex_clilist);
139 send_to_client(clii->client_fd, data, len);
140 pthread_mutex_unlock(&mutex_clilist);
143 void send_to_client(int fd, const char* data, const int len)
145 ecs_write(fd, (const uint8_t*) data, len);
148 void read_val_short(const char* data, unsigned short* ret_val) {
149 memcpy(ret_val, data, sizeof(unsigned short));
152 void read_val_char(const char* data, unsigned char* ret_val) {
153 memcpy(ret_val, data, sizeof(unsigned char));
156 void read_val_str(const char* data, char* ret_val, int len) {
157 memcpy(ret_val, data, len);
160 bool ntf_to_control(const char* data, const int len) {
164 bool ntf_to_monitor(const char* data, const int len) {
168 void print_binary(const char* data, const int len) {
171 for(i = 0; i < len; i++) {
173 printf("%02x]\n", data[i]);
175 printf("%02x,", data[i]);
180 void ecs_make_header(QDict* obj, type_length length, type_group group,
181 type_action action) {
182 qdict_put(obj, "length", qint_from_int((int64_t )length));
183 qdict_put(obj, "group", qint_from_int((int64_t )group));
184 qdict_put(obj, "action", qint_from_int((int64_t )action));
187 static Monitor *monitor_create(void) {
190 mon = g_malloc0(sizeof(*mon));
192 ERR("monitor allocation failed.");
199 static void ecs_close(ECS_State *cs) {
201 INFO("### Good bye! ECS ###");
206 if (0 <= cs->listen_fd) {
207 INFO("close listen_fd: %d", cs->listen_fd);
208 closesocket(cs->listen_fd);
212 if (cs->mon != NULL) {
218 g_free(keepalive_buf);
221 if (cs->alive_timer != NULL) {
222 timer_del(cs->alive_timer);
223 cs->alive_timer = NULL;
226 QTAILQ_FOREACH(clii, &clients, next)
228 ecs_client_close(clii);
237 static ssize_t ecs_recv(int fd, char *buf, size_t len) {
238 struct msghdr msg = { NULL, };
242 char control[CMSG_SPACE(sizeof(int))];
246 iov[0].iov_base = buf;
247 iov[0].iov_len = len;
251 msg.msg_control = &msg_control;
252 msg.msg_controllen = sizeof(msg_control);
254 #ifdef MSG_CMSG_CLOEXEC
255 flags |= MSG_CMSG_CLOEXEC;
257 return recvmsg(fd, &msg, flags);
261 static ssize_t ecs_recv(int fd, char *buf, size_t len)
263 return qemu_recv(fd, buf, len, 0);
268 static void reset_sbuf(sbuf* sbuf)
270 memset(sbuf->_buf, 0, 4096);
275 static void ecs_read(ECS_Client *cli) {
278 int to_read_bytes = 0;
282 ERR("client is null.");
286 if (ioctl(cli->client_fd, FIONREAD, &to_read_bytes) < 0)
292 unsigned long to_read_bytes_long = 0;
293 if (ioctlsocket(cli->client_fd, FIONREAD, &to_read_bytes_long) < 0)
298 to_read_bytes = (int)to_read_bytes_long;
301 if (to_read_bytes == 0) {
302 ERR("ioctl FIONREAD: 0\n");
306 if (cli->sbuf._netlen == 0)
308 if (to_read_bytes < 4)
310 //LOG("insufficient data size to read");
314 long payloadsize = 0;
315 read = ecs_recv(cli->client_fd, (char*) &payloadsize, 4);
319 ERR("insufficient header size");
323 payloadsize = ntohl(payloadsize);
325 cli->sbuf._netlen = payloadsize;
327 TRACE("payload size: %ld\n", payloadsize);
332 if (to_read_bytes == 0)
336 to_read_bytes = min(to_read_bytes, cli->sbuf._netlen - cli->sbuf._use);
338 read = ecs_recv(cli->client_fd, (char*)(cli->sbuf._buf + cli->sbuf._use), to_read_bytes);
343 cli->sbuf._use += read;
346 if (cli->sbuf._netlen == cli->sbuf._use)
348 handle_protobuf_msg(cli, (char*)cli->sbuf._buf, cli->sbuf._use);
349 reset_sbuf(&cli->sbuf);
354 ecs_client_close(cli);
358 static void epoll_cli_add(ECS_State *cs, int fd) {
359 struct epoll_event events;
361 /* event control set for read event */
362 events.events = EPOLLIN;
365 if (epoll_ctl(cs->epoll_fd, EPOLL_CTL_ADD, fd, &events) < 0) {
366 ERR("Epoll control fails.in epoll_cli_add.");
371 static ECS_Client *ecs_find_client(int fd) {
374 QTAILQ_FOREACH(clii, &clients, next)
376 if (clii->client_fd == fd)
382 ECS_Client *find_client(unsigned char id, unsigned char type) {
385 QTAILQ_FOREACH(clii, &clients, next)
387 if (clii->client_id == id && clii->client_type == type)
393 static int ecs_add_client(ECS_State *cs, int fd) {
395 ECS_Client *clii = g_malloc0(sizeof(ECS_Client));
397 ERR("ECS_Client allocation failed.");
401 reset_sbuf(&clii->sbuf);
403 qemu_set_nonblock(fd);
405 clii->client_fd = fd;
407 clii->client_type = TYPE_NONE;
409 ecs_json_message_parser_init(&clii->parser, handle_qmp_command, clii);
412 epoll_cli_add(cs, fd);
414 FD_SET(fd, &cs->reads);
417 pthread_mutex_lock(&mutex_clilist);
419 QTAILQ_INSERT_TAIL(&clients, clii, next);
421 INFO("Add an ecs client. fd: %d", fd);
423 pthread_mutex_unlock(&mutex_clilist);
425 // send_ecs_version_check(clii);
430 static void ecs_accept(ECS_State *cs) {
431 struct sockaddr_in saddr;
433 struct sockaddr_un uaddr;
435 struct sockaddr *addr;
443 addr = (struct sockaddr *) &uaddr;
448 addr = (struct sockaddr *) &saddr;
450 fd = qemu_accept(cs->listen_fd, addr, &len);
451 if (0 > fd && EINTR != errno) {
453 } else if (0 <= fd) {
457 if (0 > ecs_add_client(cs, fd)) {
458 ERR("failed to add client.");
463 static void epoll_init(ECS_State *cs) {
464 struct epoll_event events;
466 cs->epoll_fd = epoll_create(MAX_EVENTS);
467 if (cs->epoll_fd < 0) {
468 closesocket(cs->listen_fd);
471 events.events = EPOLLIN;
472 events.data.fd = cs->listen_fd;
474 if (epoll_ctl(cs->epoll_fd, EPOLL_CTL_ADD, cs->listen_fd, &events) < 0) {
475 close(cs->listen_fd);
481 static void send_keep_alive_msg(ECS_Client *clii) {
482 send_to_single_client(clii, keepalive_buf, payloadsize);
485 static void make_keep_alive_msg(void) {
487 char msg [5] = {'s','e','l','f'};
489 ECS__Master master = ECS__MASTER__INIT;
490 ECS__KeepAliveReq req = ECS__KEEP_ALIVE_REQ__INIT;
492 req.time_str = (char*) g_malloc(5);
494 strncpy(req.time_str, msg, 4);
496 master.type = ECS__MASTER__TYPE__KEEPALIVE_REQ;
497 master.keepalive_req = &req;
499 len_pack = ecs__master__get_packed_size(&master);
500 payloadsize = len_pack + 4;
502 keepalive_buf = g_malloc(len_pack + 4);
503 if (!keepalive_buf) {
504 ERR("keep alive message creation is failed.");
508 ecs__master__pack(&master, keepalive_buf + 4);
510 len_pack = htonl(len_pack);
511 memcpy(keepalive_buf, &len_pack, 4);
514 static void alive_checker(void *opaque) {
518 if (NULL != current_ecs && !current_ecs->ecs_running) {
522 QTAILQ_FOREACH(clii, &clients, next)
524 if (1 == clii->keep_alive) {
525 INFO("get client fd %d - keep alive fail", clii->client_fd);
526 ecs_client_close(clii);
529 TRACE("set client fd %d - keep alive 1", clii->client_fd);
530 clii->keep_alive = 1;
531 send_keep_alive_msg(clii);
534 if (current_ecs == NULL) {
535 ERR("alive checking is failed because current ecs is null.");
539 timer_mod(current_ecs->alive_timer,
540 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + get_ticks_per_sec() * TIMER_ALIVE_S);
544 static int socket_initialize(ECS_State *cs, QemuOpts *opts) {
546 Error *local_err = NULL;
548 fd = inet_listen_opts(opts, 0, &local_err);
549 if (0 > fd || error_is_set(&local_err)) {
550 qerror_report_err(local_err);
551 error_free(local_err);
555 INFO("Listen fd is %d", fd);
557 qemu_set_nonblock(fd);
565 FD_SET(fd, &cs->reads);
568 make_keep_alive_msg();
570 cs->alive_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, alive_checker, cs);
572 timer_mod(cs->alive_timer,
573 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + get_ticks_per_sec() * TIMER_ALIVE_S);
579 static int ecs_loop(ECS_State *cs) {
582 nfds = epoll_wait(cs->epoll_fd, cs->events, MAX_EVENTS, 100);
590 perror("epoll wait error");
594 for (i = 0; i < nfds; i++) {
595 if (cs->events[i].data.fd == cs->listen_fd) {
599 ecs_read(ecs_find_client(cs->events[i].data.fd));
604 #elif defined(CONFIG_WIN32)
605 static int ecs_loop(ECS_State *cs)
609 fd_set temps = cs->reads;
614 if (select(0, &temps, 0, 0, &timeout) < 0) {
615 ERR("select error.");
619 for (index = 0; index < cs->reads.fd_count; index++) {
620 if (cs->reads.fd_array == NULL)
623 if (FD_ISSET(cs->reads.fd_array[index], &temps)) {
624 if (cs->reads.fd_array[index] == cs->listen_fd) {
629 ecs_read(ecs_find_client(cs->reads.fd_array[index]));
635 #elif defined(CONFIG_DARWIN)
636 static int ecs_loop(ECS_State *cs)
640 struct timeval timeout;
641 fd_set temps = cs->reads;
646 if ((res = select(MAX_FD_NUM + 1, &temps, NULL, NULL, &timeout)) < 0) {
647 ERR("select failed..");
651 for (index = 0; index < MAX_FD_NUM; index ++) {
652 if (FD_ISSET(index, &temps)) {
653 if (index == cs->listen_fd) {
658 ecs_read(ecs_find_client(index));
667 static void* ecs_initialize(void* args) {
669 ECS_State *cs = NULL;
670 QemuOpts *opts = NULL;
671 Error *local_err = NULL;
676 INFO("ecs starts initializing.");
678 opts = qemu_opts_create(qemu_find_opts(ECS_OPTS_NAME), ECS_OPTS_NAME, 1, &local_err);
679 if (error_is_set(&local_err)) {
680 qerror_report_err(local_err);
681 error_free(local_err);
685 qemu_opt_set(opts, "host", HOST_LISTEN_ADDR);
687 cs = g_malloc0(sizeof(ECS_State));
689 ERR("ECS_State allocation failed.");
692 port = get_emul_ecs_port();
693 INFO("ecs port: %d", port);
694 sprintf(host_port, "%d", port);
696 qemu_opt_set(opts, "port", host_port);
697 ret = socket_initialize(cs, opts);
699 ERR("Socket initialization is failed.");
704 mon = monitor_create();
706 ERR("monitor initialization failed.");
715 TRACE("ecs_loop entered.");
716 while (cs->ecs_running) {
723 TRACE("ecs_loop exited.");
729 INFO("ecs is closing.");
730 if (NULL != current_ecs) {
731 current_ecs->ecs_running = 0;
732 ecs_close(current_ecs);
735 pthread_mutex_destroy(&mutex_clilist);
740 int start_ecs(void) {
743 if (0 != pthread_create(&thread_id, NULL, ecs_initialize, NULL)) {
744 ERR("pthread creation failed.");
750 bool handle_protobuf_msg(ECS_Client* cli, char* data, int len)
752 ECS__Master* master = ecs__master__unpack(NULL, (size_t)len, (const uint8_t*)data);
756 if (master->type == ECS__MASTER__TYPE__INJECTOR_REQ)
758 ECS__InjectorReq* msg = master->injector_req;
761 msgproc_injector_req(cli, msg);
763 else if (master->type == ECS__MASTER__TYPE__MONITOR_REQ)
765 ECS__MonitorReq* msg = master->monitor_req;
768 msgproc_monitor_req(cli, msg);
770 else if (master->type == ECS__MASTER__TYPE__DEVICE_REQ)
772 cli->client_type = TYPE_ECP;
773 ECS__DeviceReq* msg = master->device_req;
776 msgproc_device_req(cli, msg);
778 else if (master->type == ECS__MASTER__TYPE__NFC_REQ)
780 ECS__NfcReq* msg = master->nfc_req;
784 pthread_mutex_lock(&mutex_clilist);
785 if(cli->client_type == TYPE_NONE) {
786 if (!strncmp(msg->category, MSG_TYPE_NFC, 3)) {
787 QTAILQ_REMOVE(&clients, cli, next);
788 cli->client_type = TYPE_ECP;
789 if(g_client_id > 255) {
792 cli->client_id = g_client_id++;
794 QTAILQ_INSERT_TAIL(&clients, cli, next);
796 else if (!strncmp(msg->category, MSG_TYPE_SIMUL_NFC, 9)) {
797 QTAILQ_REMOVE(&clients, cli, next);
798 cli->client_type = TYPE_SIMUL_NFC;
799 if(g_client_id > 255) {
802 cli->client_id = g_client_id++;
803 QTAILQ_INSERT_TAIL(&clients, cli, next);
806 ERR("unsupported category is found: %s", msg->category);
807 pthread_mutex_unlock(&mutex_clilist);
811 pthread_mutex_unlock(&mutex_clilist);
813 msgproc_nfc_req(cli, msg);
816 else if (master->type == ECS__MASTER__TYPE__CHECKVERSION_REQ)
818 ECS__CheckVersionReq* msg = master->checkversion_req;
821 msgproc_checkversion_req(cli, msg);
824 else if (master->type == ECS__MASTER__TYPE__KEEPALIVE_ANS)
826 ECS__KeepAliveAns* msg = master->keepalive_ans;
829 msgproc_keepalive_ans(cli, msg);
831 else if (master->type == ECS__MASTER__TYPE__TETHERING_REQ)
833 ECS__TetheringReq* msg = master->tethering_req;
836 msgproc_tethering_req(cli, msg);
839 ecs__master__free_unpacked(master, NULL);
842 ERR("invalid message type : %d", master->type);
843 ecs__master__free_unpacked(master, NULL);