Don't look up pid/tid on YAGL_LOG_FUNC_SET
[sdk/emulator/qemu.git] / tizen / src / util / net_helper.c
1 /*
2  * Net helper
3  *
4  * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
5  *
6  * Contact:
7  *  MunKyu Im       <munkyu.im@samsung.com>
8  *  Jinhyung Choi   <jinh0.choi@samsung.com>
9  *  SeokYeon Hwnag  <syeon.hwang@samsung.com>
10  *  Sangho Park     <sangho.p@samsung.com>
11  *
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.
16  *
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.
21  *
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.
25  *
26  * Contributors:
27  * - S-Core Co., Ltd
28  *
29  */
30
31 #include "net_helper.h"
32
33 #include "qemu/osdep.h"
34 #include "qemu/sockets.h"
35 #include "net/slirp.h"
36 #include "block/nbd.h"
37 #include "qemu/error-report.h"
38
39 #include "emulator.h"
40 #include "emulator_common.h"
41 #include "emul_state.h"
42
43 #include "hw/virtio/maru_virtio_input.h"
44 #include "hw/maru_pm.h"
45 #include "ecs/ecs.h"
46 #include "new_debug_ch.h"
47
48 DECLARE_DEBUG_CHANNEL(net_helper);
49
50 #define BUF_SIZE 64
51 #define MAX_TRIAL 20
52 #define MAX_USER_NAME_LEN 36
53
54 int emul_vm_base_socket;
55 static bool sdb_daemon_is_initialized = false;
56 static QemuThread thread_id;
57
58 int inet_strtoip(const char*  str, uint32_t  *ip)
59 {
60     int  comp[4];
61
62     if (sscanf(str, "%d.%d.%d.%d", &comp[0], &comp[1], &comp[2], &comp[3]) != 4)
63         return -1;
64
65     if ((unsigned)comp[0] >= 256 ||
66             (unsigned)comp[1] >= 256 ||
67             (unsigned)comp[2] >= 256 ||
68             (unsigned)comp[3] >= 256)
69         return -1;
70
71     *ip = (uint32_t)((comp[0] << 24) | (comp[1] << 16) |
72             (comp[2] << 8)  |  comp[3]);
73     return 0;
74 }
75
76 int check_port_bind_listen(uint32_t port)
77 {
78     struct sockaddr_in addr;
79     int ret = -1;
80     addr.sin_family = AF_INET;
81     addr.sin_port = htons(port);
82     addr.sin_addr.s_addr = INADDR_ANY;
83
84     ret = qemu_socket(PF_INET, SOCK_STREAM, 0);
85     if (ret < 0) {
86         LOG_SEVERE("socket creation failed.\n");
87         return -1;
88     }
89
90     qemu_set_nonblock(ret);
91
92     if (socket_set_fast_reuse(ret) != 0) {
93         LOG_SEVERE("It cannot be reach here.\n");
94         closesocket(ret);
95         return -1;
96     }
97
98     if (bind(ret, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
99         LOG_INFO("bind failed for port: %d, errno: %d\n", port, errno);
100         closesocket(ret);
101         return -1;
102     }
103
104     if (listen(ret, 1) != 0) {
105         LOG_SEVERE("listen failed :%s-%d\n", strerror(errno), errno);
106         closesocket(ret);
107         return -1;
108     }
109
110     return ret;
111 }
112
113 static int prepare_network_port(uint32_t base_port)
114 {
115     int ret = -1;
116
117     /* no need to redir if network is tap */
118     if (!is_netclient_tap_attached()) {
119         if (!hostfwd_try_add(0, NULL, base_port + SDB_TCP_INDEX,
120                 NULL, SDB_GUEST_PORT)) {
121             LOG_INFO("TCP port %"PRIu32" is aleady occupied",
122                     base_port + SDB_TCP_INDEX);
123
124             return -1;
125         }
126
127         if (!hostfwd_try_add(0, NULL, base_port + GDB_TCP_INDEX,
128                 NULL, GDB_GUEST_PORT)) {
129             LOG_INFO("TCP port %"PRIu32" is aleady occupied",
130                     base_port + GDB_TCP_INDEX);
131             hostfwd_try_remove(0, NULL, base_port + SDB_TCP_INDEX);
132
133             return -1;
134         }
135     }
136
137     if ((ret = check_port_bind_listen(base_port + ECS_TCP_INDEX)) < 0) {
138         LOG_INFO("TCP port %"PRIu32" is aleady occupied",
139                 base_port + ECS_TCP_INDEX);
140
141         if (!is_netclient_tap_attached()) {
142             hostfwd_try_remove(0, NULL, base_port + SDB_TCP_INDEX);
143             hostfwd_try_remove(0, NULL, base_port + GDB_TCP_INDEX);
144         }
145
146         return -1;
147     }
148
149     g_assert(ret >= 0);
150
151     // save ecs socket fd as global variable
152     // FIXME: should not use global variable.
153     emul_vm_base_socket = ret;
154
155     return ret;
156 }
157
158 static void start_sdb_noti_server(int server_port);
159
160 void init_sdb_and_vm_base_port(void)
161 {
162     uint32_t port = -1;
163
164     for (port = START_VM_BASE_PORT ; port < END_VM_BASE_PORT; port += 10) {
165         if (prepare_network_port(port) < 0) {
166             continue;
167         }
168
169         break;
170     }
171
172     if (port >= END_VM_BASE_PORT) {
173         error_report("It seems too many emulator instances are "
174                 "running on this machine. Aborting.");
175         exit(1);
176     }
177
178     LOG_INFO("Emulator base port is %"PRIu32".\n", port);
179
180     start_sdb_noti_server(port + SDB_UDP_NOTI_PORT_INDEX);
181
182     vm_base_port = port;
183 }
184
185 /*
186  * SDB Notification server
187  */
188
189 #define RECV_BUF_SIZE 32
190 typedef struct SDB_Noti_Server {
191     int server_fd;
192     GIOChannel *server_chan;
193     guint server_tag;
194 } SDB_Noti_Server;
195
196 typedef struct SDB_Client {
197     int port;
198     struct sockaddr_in addr;
199     char serial[RECV_BUF_SIZE];
200
201     QTAILQ_ENTRY(SDB_Client) next;
202 } SDB_Client;
203
204 static QTAILQ_HEAD(SDB_ClientHead, SDB_Client)
205 clients = QTAILQ_HEAD_INITIALIZER(clients);
206
207 static SDB_Noti_Server *current_server;
208 static QemuMutex mutex_clients;
209 static QemuMutex mutex_request;
210
211 static void remove_sdb_client(SDB_Client* client)
212 {
213     if (client == NULL) {
214         return;
215     }
216
217     qemu_mutex_lock(&mutex_clients);
218
219     QTAILQ_REMOVE(&clients, client, next);
220
221     qemu_mutex_unlock(&mutex_clients);
222
223     g_free(client);
224 }
225
226 static void send_to_sdb_client(SDB_Client* client, int state)
227 {
228     struct sockaddr_in sock_addr;
229     int s, slen = sizeof(sock_addr);
230     int serial_len = 0;
231     char buf[BUF_SIZE];
232
233     if ((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) == -1){
234           LOG_INFO("socket creation error! %d\n", errno);
235           return;
236     }
237
238     memset(&sock_addr, 0, sizeof(sock_addr));
239
240     sock_addr.sin_family = AF_INET;
241     sock_addr.sin_port = htons(client->port);
242     sock_addr.sin_addr = (client->addr).sin_addr;
243
244     if (connect(s, (struct sockaddr*)&sock_addr, slen) == -1) {
245         LOG_INFO("connect error! remove this client.\n");
246         remove_sdb_client(client);
247         closesocket(s);
248         return;
249     }
250
251     memset(buf, 0, sizeof(buf));
252
253     serial_len = strlen(client->serial);
254
255     // send message "[4 digit message length]host:sync:emulator-26101:[0|1]"
256     snprintf(buf, sizeof(buf), "%04xhost:sync:%s:%01d", (serial_len + 12), client->serial, state);
257
258     LOG_INFO("send %s to client %s\n", buf, inet_ntoa(client->addr.sin_addr));
259
260     if (send(s, buf, sizeof(buf), 0) == -1)
261     {
262         LOG_INFO("send error! remove this client.\n");
263         remove_sdb_client(client);
264     }
265
266     closesocket(s);
267 }
268
269 void notify_all_sdb_clients(int state)
270 {
271     qemu_mutex_lock(&mutex_clients);
272     SDB_Client *client, *next;
273
274     QTAILQ_FOREACH_SAFE(client, &clients, next, next)
275     {
276         send_to_sdb_client(client, state);
277     }
278     qemu_mutex_unlock(&mutex_clients);
279
280 }
281
282 static void add_sdb_client(struct sockaddr_in* addr, int port, const char* serial)
283 {
284     SDB_Client *cli = NULL;
285     SDB_Client *client = NULL, *next;
286
287     if (addr == NULL) {
288         LOG_INFO("SDB_Client client's address is EMPTY.\n");
289         return;
290     } else if (serial == NULL || strlen(serial) <= 0) {
291         LOG_INFO("SDB_Client client's serial is EMPTY.\n");
292         return;
293     } else if (strlen(serial) > RECV_BUF_SIZE) {
294         LOG_INFO("SDB_Client client's serial is too long. %s\n", serial);
295         return;
296     }
297
298     qemu_mutex_lock(&mutex_clients);
299     QTAILQ_FOREACH_SAFE(cli, &clients, next, next)
300     {
301         if (!strcmp(serial, cli->serial) && !strcmp(inet_ntoa(addr->sin_addr), inet_ntoa((cli->addr).sin_addr))) {
302             LOG_INFO("Client cannot be duplicated.\n");
303             qemu_mutex_unlock(&mutex_clients);
304             return;
305         }
306     }
307     qemu_mutex_unlock(&mutex_clients);
308
309     client = g_malloc0(sizeof(SDB_Client));
310     if (NULL == client) {
311         LOG_INFO("SDB_Client allocation failed.\n");
312         return;
313     }
314
315     memcpy(&client->addr, addr, sizeof(struct sockaddr_in));
316     client->port = port;
317     strncpy(client->serial, serial, sizeof(client->serial));
318     client->serial[sizeof(client->serial) - 1] = 0;
319
320     qemu_mutex_lock(&mutex_clients);
321
322     QTAILQ_INSERT_TAIL(&clients, client, next);
323
324     qemu_mutex_unlock(&mutex_clients);
325
326     LOG_INFO("Added new sdb client. ip: %s, port: %d, serial: %s\n", inet_ntoa((client->addr).sin_addr), client->port, client->serial);
327
328     send_to_sdb_client(client, runstate_check(RUN_STATE_SUSPENDED));
329 }
330
331 #define SDB_SERVER_PORT 26097
332 static void register_sdb_server(char* readbuf, struct sockaddr_in* client_addr)
333 {
334     int port = 0;
335     char token[] = "\n";
336     char* ret = NULL;
337     char* serial = NULL;
338
339     ret = strtok(readbuf, token);
340     if (ret == NULL) {
341         LOG_INFO("command is not found.");
342         return;
343     }
344
345     serial = strtok(NULL, token);
346     if (serial == NULL) {
347         LOG_INFO("serial is not found.");
348         return;
349     }
350
351     port = SDB_SERVER_PORT;
352
353     add_sdb_client(client_addr, port, serial);
354 }
355
356 #define PRESS     1
357 #define RELEASE   2
358 #define POWER_KEY 116
359 static void wakeup_guest(void)
360 {
361     // FIXME: Temporarily working model.
362     // It must be fixed as the way it works.
363     maru_hwkey_event(PRESS, POWER_KEY);
364     maru_hwkey_event(RELEASE, POWER_KEY);
365 }
366
367 static void suspend_lock_state(int state)
368 {
369     ecs_suspend_lock_state(state);
370 }
371
372 static bool is_ready(void)
373 {
374     FILE *fp;
375     char state_name[BUF_SIZE] = { 0, };
376 #ifndef CONFIG_WIN32
377     const char *sdb_path = "../../../../../tools/sdb";
378     const char *bin_dir = get_bin_path();
379     char *cmd_get_state = g_strdup_printf("\"%s%s\" -s emulator-%d get-state 2> /dev/null",
380             bin_dir, sdb_path, get_vm_device_serial_number());
381 #else
382     const char *sdb_path = "..\\..\\..\\..\\..\\tools\\sdb.exe";
383     const char *bin_dir = get_bin_path();
384     char *cmd_get_state = g_strdup_printf("\"%s%s\" -s emulator-%d get-state 2> NUL",
385             bin_dir, sdb_path, get_vm_device_serial_number());
386 #endif
387     fp = popen(cmd_get_state, "r");
388     if (fp == NULL) {
389         LOG_WARNING("Failed to run command\n");
390         g_free(cmd_get_state);
391         return false;
392     }
393
394     if (fgets(state_name, sizeof(state_name), fp)) {
395         g_strstrip(state_name);
396         if (strncmp(state_name, "device", 6) == 0) {
397             g_free(cmd_get_state);
398             pclose(fp);
399             LOG_INFO("device is ready to get command");
400             return true;
401         }
402     }
403
404     g_free(cmd_get_state);
405     pclose(fp);
406     return false;
407 }
408
409 static void *get_user_home_path(void *args)
410 {
411     FILE *fp;
412     char user_name[MAX_USER_NAME_LEN] = { 0, } ;
413     int trial = 0;
414     int sleep_time = 500; // msec
415 #ifndef CONFIG_WIN32
416     const char *sdb_path = "../../../../../tools/sdb";
417 #else
418     const char *sdb_path = "..\\..\\..\\..\\..\\tools\\sdb.exe";
419 #endif
420     const char *bin_dir = get_bin_path();
421
422     qemu_mutex_lock(&mutex_request);
423
424     if (get_platform_default_home()) {
425         qemu_mutex_unlock(&mutex_request);
426         return NULL;
427     }
428 #ifndef CONFIG_WIN32
429     char *cmd_root_off = g_strdup_printf("\"%s%s\" -s emulator-%d root off 2> /dev/null",
430             bin_dir, sdb_path, get_vm_device_serial_number());
431     char *cmd_get_home = g_strdup_printf("\"%s%s\" -s emulator-%d shell id -un 2> /dev/null",
432             bin_dir, sdb_path, get_vm_device_serial_number());
433 #else
434     char *cmd_root_off = g_strdup_printf("\"%s%s\" -s emulator-%d root off 2> NUL",
435             bin_dir, sdb_path, get_vm_device_serial_number());
436     char *cmd_get_home = g_strdup_printf("\"%s%s\" -s emulator-%d shell id -un 2> NUL",
437             bin_dir, sdb_path, get_vm_device_serial_number());
438 #endif
439     while (true) {
440         if (trial >= MAX_TRIAL) {
441             sleep_time = 2000;
442         } else {
443             trial++;
444         }
445 #ifdef CONFIG_WIN32
446         Sleep(sleep_time);
447 #else
448         usleep(sleep_time * 1000);
449 #endif
450          if (!is_ready()) {
451              continue;
452          }
453
454         //FIXME: (sdb) cannot check sdb root status
455         fp = popen(cmd_root_off, "r");
456         if (fp == NULL) {
457             LOG_WARNING("Failed to run command\n");
458             g_free(cmd_root_off);
459             cmd_root_off = NULL;
460             break;
461         }
462         if (cmd_root_off != NULL) {
463             g_free(cmd_root_off);
464             cmd_root_off = NULL;
465         }
466         pclose(fp);
467
468         fp = popen(cmd_get_home, "r");
469         if (fp == NULL) {
470             LOG_WARNING("Failed to run command\n");
471             break;
472         }
473
474         if (fgets(user_name, sizeof(user_name), fp)) {
475             g_strstrip(user_name);
476             if (strlen(user_name) > 0) {
477                 char *path = g_strdup_printf("/home/%s/", user_name);
478                 set_platform_default_home(path);
479                 g_free(path);
480                 pclose(fp);
481                 break;
482             }
483         }
484
485         pclose(fp);
486     }
487     g_free(cmd_get_home);
488
489     if (!get_platform_default_home()) {
490         set_platform_default_home("/tmp/");
491     }
492
493     LOG_INFO("platform_default_user_home: %s\n", get_platform_default_home());
494
495     qemu_mutex_unlock(&mutex_request);
496
497     return NULL;
498 }
499
500 static void command_handler(char* readbuf, struct sockaddr_in* client_addr)
501 {
502     char command[RECV_BUF_SIZE];
503     memset(command, '\0', sizeof(command));
504
505     parse_val(readbuf, 0x0a, command);
506
507     LOG_TRACE("----------------------------------------\n");
508     LOG_TRACE("command:%s\n", command);
509     if (strcmp(command, "2\n" ) == 0) {
510         sdb_daemon_is_initialized = true;
511         if (!get_platform_default_home()) {
512             qemu_thread_create(&thread_id, "get_platform_default_home",
513                     get_user_home_path, NULL, QEMU_THREAD_DETACHED);
514         }
515     } else if (strcmp(command, "5\n") == 0) {
516         register_sdb_server(readbuf, client_addr);
517         set_sdb_connection(true);
518     } else if (strcmp(command, "6\n") == 0) {
519         wakeup_guest();
520     } else if (strcmp(command, "7\n") == 0) {
521         suspend_lock_state(SUSPEND_LOCK);
522     } else if (strcmp(command, "8\n") == 0) {
523         suspend_lock_state(SUSPEND_UNLOCK);
524     } else {
525         LOG_INFO("!!! unknown command : %s\n", command);
526     }
527     LOG_TRACE("========================================\n");
528 }
529
530 static void close_clients(void)
531 {
532     qemu_mutex_lock(&mutex_clients);
533     SDB_Client * client, *next;
534
535     QTAILQ_FOREACH_SAFE(client, &clients, next, next)
536     {
537         QTAILQ_REMOVE(&clients, client, next);
538
539         if (NULL != client)
540         {
541             g_free(client);
542         }
543     }
544
545     qemu_mutex_unlock(&mutex_clients);
546 }
547
548 static void close_server(void)
549 {
550     if (current_server == NULL) {
551         return;
552     }
553
554     close_clients();
555
556     if (current_server->server_fd > 0) {
557         if (current_server->server_tag) {
558             g_source_remove(current_server->server_tag);
559             current_server->server_tag = 0;
560         }
561         if (current_server->server_chan) {
562             g_io_channel_unref(current_server->server_chan);
563         }
564         closesocket(current_server->server_fd);
565     }
566
567     g_free(current_server);
568
569     qemu_mutex_destroy(&mutex_clients);
570 }
571
572 static gboolean sdb_noti_read(GIOChannel *channel, GIOCondition cond, void *opaque)
573 {
574     int recv_cnt = 0;
575     struct sockaddr_in client_addr;
576     socklen_t client_len = sizeof(client_addr);
577     char readbuf[RECV_BUF_SIZE + 1];
578     SDB_Noti_Server *server = opaque;
579
580     memset(&readbuf, 0, sizeof(readbuf));
581
582     recv_cnt = recvfrom(server->server_fd, readbuf, RECV_BUF_SIZE, 0,
583                         (struct sockaddr*) &client_addr, &client_len);
584
585     if (recv_cnt > 0) {
586         command_handler((char*)readbuf, &client_addr);
587     } else if (recv_cnt == 0) {
588         LOG_INFO("noti server recvfrom returned 0.\n");
589     } else {
590 #ifdef _WIN32
591         errno = WSAGetLastError();
592 #endif
593         LOG_TRACE("recvfrom error case (it can be from non-blocking socket): %d", errno);
594     }
595
596     return TRUE;
597 }
598
599 static int create_UDP_server(SDB_Noti_Server *server, int port)
600 {
601     struct sockaddr_in server_addr;
602     int opt = 1;
603
604     if ((server->server_fd = qemu_socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
605         LOG_INFO("create listen socket error:%d\n", errno);
606         return -1;
607     }
608
609     memset(&server_addr, '\0', sizeof(server_addr));
610     server_addr.sin_family = PF_INET;
611     server_addr.sin_addr.s_addr = INADDR_ANY;
612     server_addr.sin_port = htons(port);
613
614     qemu_set_nonblock(server->server_fd);
615
616     if (qemu_setsockopt(server->server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {
617         LOG_INFO("setsockopt SO_REUSEADDR is failed.: %d\n", errno);
618         return -1;
619     }
620
621     if (bind(server->server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
622         LOG_INFO("sdb noti server bind error: %d", errno);
623         return -1;
624     }
625
626     return 0;
627 }
628
629 static GIOChannel *io_channel_from_socket(int fd)
630 {
631     GIOChannel *chan;
632
633     if (fd == -1) {
634         return NULL;
635     }
636
637 #ifdef _WIN32
638     chan = g_io_channel_win32_new_socket(fd);
639 #else
640     chan = g_io_channel_unix_new(fd);
641 #endif
642
643     g_io_channel_set_encoding(chan, NULL, NULL);
644     g_io_channel_set_buffered(chan, FALSE);
645
646     return chan;
647 }
648
649 static void sdb_noti_server_notify_exit(Notifier *notifier, void *data)
650 {
651     LOG_INFO("shutdown sdb notification server.\n");
652     close_server();
653 }
654
655 static Notifier sdb_noti_server_exit = { .notify = sdb_noti_server_notify_exit };
656
657 static void start_sdb_noti_server(int server_port)
658 {
659     SDB_Noti_Server *server;
660     int ret;
661
662     LOG_INFO("start sdb noti server thread.\n");
663
664     server = g_malloc0(sizeof(SDB_Noti_Server));
665     if (server == NULL) {
666         LOG_INFO("SDB Notification server allocation is failed.\n");
667         return;
668     }
669
670     ret = create_UDP_server(server, server_port);
671     if (ret < 0) {
672         LOG_INFO("failed to create UDP server\n");
673         close_server();
674         g_free(server);
675         server = NULL;
676         return;
677     }
678
679     qemu_mutex_init(&mutex_clients);
680     qemu_mutex_init(&mutex_request);
681
682     server->server_chan = io_channel_from_socket(server->server_fd);
683     server->server_tag = g_io_add_watch(server->server_chan, G_IO_IN, sdb_noti_read, server);
684
685     current_server = server;
686
687     LOG_INFO("success to bind port[127.0.0.1:%d/udp] for sdb noti server in host \n", server_port);
688
689     emulator_add_exit_notifier(&sdb_noti_server_exit);
690 }
691
692 bool is_sdb_daemon_initialized(void)
693 {
694     return sdb_daemon_is_initialized;
695 }