update source for tizen_2.1
[sdk/emulator/qemu.git] / tizen / src / skin / maruskin_server.c
1 /*
2  * socket server for emulator skin
3  *
4  * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:
7  * GiWoong Kim <giwoong.kim@samsung.com>
8  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
9  * HyunJun Son
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
24  *
25  * Contributors:
26  * - S-Core Co., Ltd
27  *
28  */
29
30
31 #include "maru_common.h"
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <unistd.h>
36 #include <string.h>
37 #include <sys/types.h>
38 #include <sys/time.h>
39 #include <pthread.h>
40 #include "maruskin_server.h"
41 #include "maruskin_operation.h"
42 #include "qemu-thread.h"
43 #include "emul_state.h"
44 #include "maruskin_client.h"
45 #include "emulator.h"
46 #include "maru_err_table.h"
47
48 #ifndef CONFIG_USE_SHM
49 #include "maru_sdl.h"
50 #endif
51
52 #ifdef CONFIG_WIN32
53 #include <windows.h>
54 #include <winsock2.h>
55 #include <ws2tcpip.h>
56
57 #define socket_error() WSAGetLastError()
58
59 #else
60 #include <arpa/inet.h>
61 #include <netinet/in.h>
62 #include <sys/socket.h>
63
64 #define socket_error() errno
65
66 #endif
67
68 #include "debug_ch.h"
69
70 MULTI_DEBUG_CHANNEL(qemu, skin_server);
71
72 #define MAX_REQ_ID 0x7fffffff
73 #define RECV_BUF_SIZE 32
74 #define RECV_HEADER_SIZE 12
75
76 #define SEND_HEADER_SIZE 10
77 #define SEND_BIG_BUF_SIZE 1024 * 1024 * 2
78 #define SEND_BUF_SIZE 512
79
80 #define HEART_BEAT_INTERVAL 1
81 #define HEART_BEAT_FAIL_COUNT 10
82 #define HEART_BEAT_EXPIRE_COUNT 10
83
84 #if 0 // do not restarting skin process ( prevent from abnormal behavior killing a skin process in Windows )
85 #define RESTART_CLIENT_MAX_COUNT 1
86 #else
87 #define RESTART_CLIENT_MAX_COUNT 0
88 #endif
89
90 #define PORT_RETRY_COUNT 50
91
92 #define TEST_HB_IGNORE "test.hb.ignore"
93 #define SKIN_CONFIG_PROP ".skinconfig.properties"
94
95 extern char tizen_target_path[];
96
97 enum {
98     /* This values must match the Java definitions
99         in Skin process */
100
101     RECV_START = 1,
102     RECV_MOUSE_EVENT = 10,
103     RECV_KEY_EVENT = 11,
104     RECV_HARD_KEY_EVENT = 12,
105     RECV_CHANGE_LCD_STATE = 13,
106     RECV_OPEN_SHELL = 14,
107     RECV_HOST_KBD = 15,
108     RECV_SCREEN_SHOT = 16,
109     RECV_DETAIL_INFO = 17,
110     RECV_RAM_DUMP = 18,
111     RECV_GUESTMEMORY_DUMP = 19,
112     RECV_RESPONSE_HEART_BEAT = 900,
113     RECV_CLOSE = 998,
114     RECV_RESPONSE_SHUTDOWN = 999,
115 };
116
117 enum {
118     /* This values must match the Java definitions
119     in Skin process */
120
121     SEND_HEART_BEAT = 1,
122     SEND_SCREEN_SHOT = 2,
123     SEND_DETAIL_INFO = 3,
124     SEND_RAMDUMP_COMPLETE = 4,
125     SEND_BOOTING_PROGRESS = 5,
126     SEND_BRIGHTNESS_VALUE = 6,
127     SEND_SENSOR_DAEMON_START = 800,
128     SEND_SHUTDOWN = 999,
129 };
130
131 static int seq_req_id = 0;
132
133 static uint16_t svr_port = 0;
134 static int server_sock = 0;
135 static int client_sock = 0;
136 static int stop_server = 0;
137 static int is_sensord_initialized = 0;
138 static int ready_server = 0;
139 static int ignore_heartbeat = 0;
140 static int is_force_close_client = 0;
141
142 static int is_started_heartbeat = 0;
143 static int stop_heartbeat = 0;
144 static int recv_heartbeat_count = 0;
145 static pthread_t thread_id_heartbeat;
146
147 static pthread_mutex_t mutex_send_data = PTHREAD_MUTEX_INITIALIZER;
148 static pthread_mutex_t mutex_recv_heartbeat_count = PTHREAD_MUTEX_INITIALIZER;
149 pthread_mutex_t mutex_screenshot = PTHREAD_MUTEX_INITIALIZER;
150 pthread_cond_t cond_screenshot = PTHREAD_COND_INITIALIZER;
151
152 static int skin_argc = 0;
153 static char** skin_argv = NULL;
154 static int qmu_argc = 0;
155 static char** qmu_argv = NULL;
156
157 static void parse_skin_args(void);
158 static void parse_skinconfig_prop(void);
159 static void* run_skin_server(void* args);
160
161 static int recv_n(int client_sock, char* read_buf, int recv_len);
162 static int send_n(int client_sock, unsigned char* data, int length, int big_data);
163
164 static void make_header(int client_sock,
165     short send_cmd, int data_length, char* sendbuf, int print_log);
166 static int send_skin_header_only(int client_sock,
167     short send_cmd, int print_log);
168 static int send_skin_data(int client_sock,
169     short send_cmd, unsigned char* data, int length, int big_data);
170
171
172 static void* do_heart_beat(void* args);
173 static int start_heart_beat(void);
174 static void stop_heart_beat(void);
175
176 int start_skin_server(int argc, char** argv,
177     int qemu_argc, char** qemu_argv)
178 {
179     skin_argc = argc;
180     skin_argv = argv;
181
182     parse_skinconfig_prop();
183
184     // arguments have higher priority than '.skinconfig.properties'
185     parse_skin_args();
186
187     INFO("ignore_heartbeat:%d\n", ignore_heartbeat);
188
189     qmu_argc = qemu_argc;
190     qmu_argv = qemu_argv;
191
192     QemuThread qemu_thread;
193
194     qemu_thread_create( &qemu_thread, run_skin_server, NULL,
195             QEMU_THREAD_JOINABLE);
196
197     return 1;
198
199 }
200
201 void shutdown_skin_server(void)
202 {
203     INFO("shutdown_skin_server\n");
204
205     int close_server_socket = 0;
206     int success_send = 0;
207
208     if (client_sock) {
209         INFO("send shutdown to skin.\n");
210         if (0 > send_skin_header_only(client_sock, SEND_SHUTDOWN, 1)) {
211             ERR("fail to send SEND_SHUTDOWN to skin.\n");
212             close_server_socket = 1;
213         } else {
214             success_send = 1;
215             /* skin sent RECV_RESPONSE_SHUTDOWN */
216         }
217     }
218
219     if (success_send) {
220
221         int count = 0;
222         int max_sleep_count = 10;
223
224         while (1) {
225
226             if (max_sleep_count < count) {
227                 close_server_socket = 1;
228                 break;
229             }
230
231             if (stop_server) {
232                 INFO("skin client sent normal shutdown response.\n");
233                 break;
234             } else {
235 #ifdef CONFIG_WIN32
236                 Sleep(1); /* 1ms */
237 #else
238                 usleep(1000);
239 #endif
240                 count++;
241             }
242         }
243     }
244
245     pthread_cond_destroy(&cond_screenshot);
246     pthread_mutex_destroy(&mutex_screenshot);
247
248     stop_server = 1;
249     is_force_close_client = 1;
250
251     if (client_sock) {
252 #ifdef CONFIG_WIN32
253         closesocket(client_sock);
254 #else
255         close(client_sock);
256 #endif
257         client_sock = 0;
258     }
259
260     if (close_server_socket) {
261         INFO("skin client did not send normal shutdown response.\n");
262         if (server_sock) {
263 #ifdef CONFIG_WIN32
264             closesocket(server_sock);
265 #else
266             close(server_sock);
267 #endif
268             server_sock = 0;
269         }
270     }
271
272     pthread_mutex_destroy(&mutex_send_data);
273     pthread_mutex_destroy(&mutex_recv_heartbeat_count);
274 }
275
276 void notify_sensor_daemon_start(void)
277 {
278     INFO("notify_sensor_daemon_start\n");
279
280     is_sensord_initialized = 1;
281     if (client_sock) {
282         if (0 > send_skin_header_only(
283             client_sock, SEND_SENSOR_DAEMON_START, 1)) {
284
285             ERR("fail to send SEND_SENSOR_DAEMON_START to skin.\n");
286         }
287     }
288 }
289
290 void notify_ramdump_completed(void)
291 {
292     INFO("ramdump completed!\n");
293
294     if (client_sock) {
295         if (0 > send_skin_header_only(
296             client_sock, SEND_RAMDUMP_COMPLETE, 1)) {
297
298             ERR("fail to send SEND_RAMDUMP_COMPLETE to skin.\n");
299         }
300     }
301 }
302
303 void notify_booting_progress(int progress_value)
304 {
305 #define PROGRESS_DATA_LENGTH 4
306
307     char progress_data[PROGRESS_DATA_LENGTH] = { 0, };
308     int len = 1;
309
310     TRACE("notify_booting_progress\n");
311
312     /* percentage */
313     if (progress_value < 0) {
314         progress_value = 0;
315         len = 1;
316     } else if (progress_value < 10) {
317         len = 1;
318     } else if (progress_value < 100) {
319         len = 2;
320     } else {
321         progress_value = 100;
322         len = 3;
323     }
324
325     snprintf(progress_data, len + 1, "%d", progress_value);
326     TRACE("booting...%s\%\n", progress_data);
327
328     if (client_sock) {
329         if (0 > send_skin_data(client_sock,
330             SEND_BOOTING_PROGRESS, (unsigned char *)progress_data, len + 1, 0)) {
331
332             ERR("fail to send SEND_BOOTING_PROGRESS to skin.\n");
333         }
334
335 #ifdef CONFIG_WIN32
336         Sleep(1); /* 1ms */
337 #else
338         usleep(1000);
339 #endif
340     }
341 }
342
343 void notify_brightness(bool on)
344 {
345     char brightness_data[2] = { 0, };
346     int brightness_value = 1;
347
348     if (on == FALSE) {
349         brightness_value = 0;
350     }
351
352     snprintf(brightness_data, 2, "%d", brightness_value);
353     TRACE("brightness value = %s\n", brightness_data);
354
355     if (client_sock) {
356         if (0 > send_skin_data(client_sock,
357             SEND_BRIGHTNESS_VALUE, (unsigned char *)brightness_data, 2, 0)) {
358
359             ERR("fail to send SEND_BRIGHTNESS_VALUE to skin.\n");
360         }
361     }
362 }
363
364 int is_ready_skin_server(void)
365 {
366     return ready_server;
367 }
368
369 int get_skin_server_port(void)
370 {
371     return svr_port;
372 }
373
374 static void parse_skinconfig_prop(void)
375 {
376     int target_path_len = strlen( tizen_target_path );
377     char skin_config_path[target_path_len + 32];
378
379     memset( skin_config_path, 0, target_path_len + 32 );
380     strcpy( skin_config_path, tizen_target_path );
381 #ifdef CONFIG_WIN32
382     strcat( skin_config_path, "\\" );
383 #else
384     strcat( skin_config_path, "/" );
385 #endif
386     strcat( skin_config_path, SKIN_CONFIG_PROP );
387
388     FILE* fp = fopen( skin_config_path, "r" );
389
390     if ( !fp ) {
391         INFO( "There is no %s. skin_config_path:%s\n", SKIN_CONFIG_PROP, skin_config_path );
392         return;
393     }
394
395     fseek( fp, 0L, SEEK_END );
396     int buf_size = ftell( fp );
397     rewind( fp );
398
399     if ( 0 >= buf_size ) {
400         INFO( "%s contents is empty.\n", SKIN_CONFIG_PROP );
401         fclose( fp );
402         return;
403     }
404
405     char* buf = g_malloc0( buf_size );
406     if ( !buf ) {
407         ERR( "Fail to malloc for %s\n", SKIN_CONFIG_PROP );
408         fclose( fp );
409         return;
410     }
411
412     int read_cnt = 0;
413     int total_cnt = 0;
414
415     while ( 1 ) {
416
417         if ( total_cnt == buf_size ) {
418             break;
419         }
420
421         read_cnt = fread( (void*) ( buf + read_cnt ), 1, buf_size - total_cnt, fp );
422         if ( 0 > read_cnt ) {
423             break;
424         } else {
425             total_cnt += read_cnt;
426         }
427
428     }
429
430     fclose( fp );
431
432     INFO( "====== %s ======\n%s\n====================================\n", SKIN_CONFIG_PROP, buf );
433
434     char hb_ignore_prop[32];
435     memset( hb_ignore_prop, 0, 32 );
436     strcat( hb_ignore_prop, TEST_HB_IGNORE );
437     strcat( hb_ignore_prop, "=true" );
438
439     char* line_str = strtok( buf, "\n" );
440
441     while ( 1 ) {
442
443         if ( line_str ) {
444
445             TRACE( "prop line_str:%s\n", line_str );
446
447             if ( 0 == strcmp( line_str, hb_ignore_prop ) ) {
448                 ignore_heartbeat = 1;
449                 INFO( "ignore heartbeat by %s\n", SKIN_CONFIG_PROP );
450             }
451
452         } else {
453             break;
454         }
455
456         line_str = strtok( NULL, "\n" );
457
458     }
459
460     g_free( buf );
461
462 }
463
464 static void parse_skin_args(void)
465 {
466     int i;
467
468     for (i = 0; i < skin_argc; i++) {
469
470         char* arg = NULL;
471         arg = strdup(skin_argv[i]);
472
473         if (arg) {
474
475             char* key = strtok(arg, "=");
476             char* value = strtok(NULL, "=");
477
478             INFO("skin params key:%s, value:%s\n", key, value);
479
480             if (0 == strcmp(TEST_HB_IGNORE, key)) {
481                 if (0 == strcmp("true", value)) {
482                     ignore_heartbeat = 1;
483                 } else if (0 == strcmp("false", value)) {
484                     ignore_heartbeat = 0;
485                 }
486             }
487
488             free(arg);
489
490         } else {
491             ERR("fail to strdup.");
492         }
493
494     }
495
496 }
497
498 static void print_fail_log(void)
499 {
500     ERR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
501     ERR("! Fail to initialize for skin server operation. Shutdown QEMU !\n");
502     ERR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
503 }
504
505 static void* run_skin_server(void* args)
506 {
507     struct sockaddr server_addr, client_addr;
508     socklen_t server_len, client_len;
509     int shutdown_qemu = 0;
510
511     INFO("run skin server\n");
512
513     if (0 > (server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) {
514         ERR("create listen socket error\n");
515         perror("create listen socket error : ");
516
517         print_fail_log();
518         shutdown_qemu_gracefully();
519
520         return NULL;
521     }
522
523     memset( &server_addr, '\0', sizeof( server_addr ) );
524     ( (struct sockaddr_in *) &server_addr )->sin_family = AF_INET;
525     memcpy( &( (struct sockaddr_in *) &server_addr )->sin_addr, "\177\000\000\001", 4 ); // 127.0.0.1
526     ( (struct sockaddr_in *) &server_addr )->sin_port = htons( 0 );
527
528     server_len = sizeof( server_addr );
529
530     if (0 != bind(server_sock, &server_addr, server_len)) {
531         ERR("skin server bind error\n");
532         perror("skin server bind error : ");
533
534         if (server_sock) {
535 #ifdef CONFIG_WIN32
536             closesocket(server_sock);
537 #else
538             close(server_sock);
539 #endif
540             server_sock = 0;
541         }
542
543         print_fail_log();
544         shutdown_qemu_gracefully();
545
546         return NULL;
547     }
548
549     memset( &server_addr, '\0', sizeof( server_addr ) );
550     getsockname( server_sock, (struct sockaddr *) &server_addr, &server_len );
551     svr_port = ntohs( ( (struct sockaddr_in *) &server_addr )->sin_port );
552
553     INFO("success to bind port[127.0.0.1:%d/tcp] for skin_server in host \n", svr_port);
554
555     if (0 > listen( server_sock, 4)) {
556         ERR("skin_server listen error\n");
557         perror("skin_server listen error : ");
558
559         if (server_sock) {
560 #ifdef CONFIG_WIN32
561             closesocket(server_sock);
562 #else
563             close(server_sock);
564 #endif
565             server_sock = 0;
566         }
567
568         print_fail_log();
569         shutdown_qemu_gracefully();
570
571         return NULL;
572     }
573
574     client_len = sizeof(client_addr);
575
576     char recvbuf[RECV_BUF_SIZE];
577
578     INFO("skin server start...port:%d\n", svr_port);
579
580     while (1) {
581
582         if (stop_server) {
583             INFO("close server socket normally.\n");
584             break;
585         }
586
587         ready_server = 1;
588
589         if( !is_started_heartbeat ) {
590             if ( !start_heart_beat() ) {
591                 ERR( "Fail to start heartbeat thread.\n" );
592                 shutdown_qemu = 1;
593                 break;
594             }
595         }
596
597         INFO( "start accepting socket...\n" );
598
599         if ( 0 > ( client_sock = accept( server_sock, (struct sockaddr *) &client_addr, &client_len ) ) ) {
600             ERR("skin_server accept error\n");
601             perror("skin_server accept error : ");
602
603             continue;
604         }
605
606         INFO( "accept client : client_sock:%d\n", client_sock );
607
608         while ( 1 ) {
609
610             if ( stop_server ) {
611                 INFO( "stop receiving current client socket.\n" );
612                 break;
613             }
614
615             stop_heartbeat = 0;
616             memset( &recvbuf, 0, RECV_BUF_SIZE );
617
618             int read_cnt = recv_n( client_sock, recvbuf, RECV_HEADER_SIZE );
619
620             if (0 > read_cnt) {
621                 if (is_force_close_client) {
622                     INFO( "force close client socket.\n" );
623                     is_force_close_client = 0;
624                 } else {
625                     ERR("skin_server read error (%d): %d\n",
626                         socket_error(), read_cnt);
627                     perror("skin_server read error : ");
628                 }
629
630                 break;
631
632             } else {
633
634                 if (0 == read_cnt) {
635                     ERR("read_cnt is 0.\n");
636                     break;
637                 }
638
639                 int log_cnt;
640                 char log_buf[512];
641                 memset(log_buf, 0, 512);
642
643                 log_cnt = sprintf(log_buf, "== RECV read_cnt:%d ", read_cnt);
644
645                 int uid = 0;
646                 int req_id = 0;
647                 short cmd = 0;
648                 short length = 0;
649
650                 char* packet = recvbuf;
651
652                 memcpy(&uid, packet, sizeof(uid));
653                 packet += sizeof(uid);
654                 memcpy(&req_id, packet, sizeof(req_id));
655                 packet += sizeof(req_id);
656                 memcpy(&cmd, packet, sizeof(cmd));
657                 packet += sizeof(cmd);
658                 memcpy(&length, packet, sizeof(length));
659
660                 uid = ntohl(uid);
661                 req_id = ntohl(req_id);
662                 cmd = ntohs(cmd);
663                 length = ntohs(length);
664
665                 log_cnt += sprintf(log_buf + log_cnt,
666                     "uid:%d, req_id:%d, cmd:%d, length:%d ", uid, req_id, cmd, length);
667
668                 if ( 0 < length ) {
669
670                     if ( RECV_BUF_SIZE < length ) {
671                         ERR( "length is bigger than RECV_BUF_SIZE\n" );
672                         continue;
673                     }
674
675                     memset( &recvbuf, 0, length );
676
677                     int recv_cnt = recv_n( client_sock, recvbuf, length );
678
679                     log_cnt += sprintf( log_buf + log_cnt, "data read_cnt:%d ", recv_cnt );
680
681                     if ( 0 > recv_cnt ) {
682                         ERR( "skin_server read data\n" );
683                         perror( "skin_server read data : " );
684                         break;
685                     } else if ( 0 == recv_cnt ) {
686                         ERR( "data read_cnt is 0.\n" );
687                         break;
688                     } else if ( recv_cnt != length ) {
689                         ERR( "read_cnt is not equal to length.\n" );
690                         break;
691                     }
692
693                 }
694
695                 switch ( cmd ) {
696                 case RECV_START: {
697                     log_cnt += sprintf( log_buf + log_cnt, "RECV_START ==\n" );
698                     INFO( log_buf );
699
700                     if ( 0 >= length ) {
701                         ERR( "there is no data looking at 0 length." );
702                         continue;
703                     }
704
705                     /* keep it consistent with emulator-skin definition */
706                     uint64 handle_id = 0;
707                     int lcd_size_width = 0;
708                     int lcd_size_height = 0;
709                     int scale = 0;
710                     double scale_ratio = 0.0;
711                     short rotation = 0;
712
713                     char* p = recvbuf;
714                     memcpy( &handle_id, p, sizeof( handle_id ) );
715                     p += sizeof( handle_id );
716                     memcpy( &lcd_size_width, p, sizeof( lcd_size_width ) );
717                     p += sizeof( lcd_size_width );
718                     memcpy( &lcd_size_height, p, sizeof( lcd_size_height ) );
719                     p += sizeof( lcd_size_height );
720                     memcpy( &scale, p, sizeof( scale ) );
721                     p += sizeof( scale );
722                     memcpy( &rotation, p, sizeof( rotation ) );
723
724                     int low_id = (int)handle_id;
725                     int high_id = (int)(handle_id >> 32);
726                     low_id = ntohl(high_id);
727                     high_id = ntohl(low_id);
728                     handle_id = high_id;
729                     handle_id = (handle_id << 32) | low_id;
730
731                     lcd_size_width = ntohl( lcd_size_width );
732                     lcd_size_height = ntohl( lcd_size_height );
733                     scale = ntohl( scale );
734                     scale_ratio = ( (double) scale ) / 100;
735                     rotation = ntohs( rotation );
736
737                     set_emul_win_scale( scale_ratio );
738
739                     start_display( handle_id, lcd_size_width, lcd_size_height, scale_ratio, rotation );
740
741                     break;
742                 }
743                 case RECV_MOUSE_EVENT: {
744                     log_cnt += sprintf( log_buf + log_cnt, "RECV_MOUSE_EVENT ==\n" );
745                     TRACE( log_buf );
746
747                     if ( 0 >= length ) {
748                         ERR( "there is no data looking at 0 length." );
749                         continue;
750                     }
751
752                     /* keep it consistent with emulator-skin definition */
753                     int button_type = 0;
754                     int event_type = 0;
755                     int host_x = 0;
756                     int host_y = 0;
757                     int guest_x = 0;
758                     int guest_y = 0;
759                     int z = 0;
760
761                     char* p = recvbuf;
762                     memcpy( &button_type, p, sizeof( button_type ) );
763                     p += sizeof( button_type );
764                     memcpy( &event_type, p, sizeof( event_type ) );
765                     p += sizeof( event_type );
766                     memcpy( &host_x, p, sizeof( host_x ) );
767                     p += sizeof( host_x );
768                     memcpy( &host_y, p, sizeof( host_y ) );
769                     p += sizeof( host_y );
770                     memcpy( &guest_x, p, sizeof( guest_x ) );
771                     p += sizeof( guest_x );
772                     memcpy( &guest_y, p, sizeof( guest_y ) );
773                     p += sizeof( guest_y );
774                     memcpy( &z, p, sizeof( z ) );
775
776                     button_type = ntohl( button_type );
777                     event_type = ntohl( event_type );
778                     host_x = ntohl( host_x );
779                     host_y = ntohl( host_y );
780                     guest_x = ntohl( guest_x );
781                     guest_y = ntohl( guest_y );
782                     z = ntohl( z );
783
784                     do_mouse_event(button_type, event_type,
785                         host_x, host_y, guest_x, guest_y, z);
786                     break;
787                 }
788                 case RECV_KEY_EVENT: {
789                     log_cnt += sprintf( log_buf + log_cnt, "RECV_KEY_EVENT ==\n" );
790                     TRACE( log_buf );
791
792                     if ( 0 >= length ) {
793                         ERR( "there is no data looking at 0 length." );
794                         continue;
795                     }
796
797                     /* keep it consistent with emulator-skin definition */
798                     int event_type = 0;
799                     int keycode = 0;
800                     int state_mask = 0;
801                     int key_location = 0;
802
803                     char* p = recvbuf;
804                     memcpy( &event_type, p, sizeof( event_type ) );
805                     p += sizeof( event_type );
806                     memcpy( &keycode, p, sizeof( keycode ) );
807                     p += sizeof( keycode );
808                     memcpy( &state_mask, p, sizeof( state_mask ) );
809                     p += sizeof( state_mask );
810                     memcpy( &key_location, p, sizeof( key_location ) );
811
812                     event_type = ntohl( event_type );
813                     keycode = ntohl( keycode );
814                     state_mask = ntohl( state_mask );
815                     key_location = ntohl( key_location );
816
817                     do_key_event(event_type, keycode, state_mask, key_location);
818                     break;
819                 }
820                 case RECV_HARD_KEY_EVENT: {
821                     log_cnt += sprintf( log_buf + log_cnt, "RECV_HARD_KEY_EVENT ==\n" );
822                     TRACE( log_buf );
823
824                     if ( 0 >= length ) {
825                         ERR( "there is no data looking at 0 length." );
826                         continue;
827                     }
828
829                     /* keep it consistent with emulator-skin definition */
830                     int event_type = 0;
831                     int keycode = 0;
832
833                     char* p = recvbuf;
834                     memcpy( &event_type, p, sizeof( event_type ) );
835                     p += sizeof( event_type );
836                     memcpy( &keycode, p, sizeof( keycode ) );
837
838                     event_type = ntohl( event_type );
839                     keycode = ntohl( keycode );
840
841                     do_hardkey_event( event_type, keycode );
842                     break;
843                 }
844                 case RECV_CHANGE_LCD_STATE: {
845                     log_cnt += sprintf( log_buf + log_cnt, "RECV_CHANGE_LCD_STATE ==\n" );
846                     TRACE( log_buf );
847
848                     if ( 0 >= length ) {
849                         ERR( "there is no data looking at 0 length." );
850                         continue;
851                     }
852
853                     /* keep it consistent with emulator-skin definition */
854                     int scale = 0;
855                     double scale_ratio = 0.0;
856                     short rotation_type = 0;
857
858                     char* p = recvbuf;
859                     memcpy( &scale, p, sizeof( scale ) );
860                     p += sizeof( scale );
861                     memcpy( &rotation_type, p, sizeof( rotation_type ) );
862
863                     scale = ntohl( scale );
864                     scale_ratio = ( (double) scale ) / 100;
865                     rotation_type = ntohs( rotation_type );
866
867                     if ( get_emul_win_scale() != scale_ratio ) {
868                         do_scale_event( scale_ratio );
869                     }
870
871                     if ( is_sensord_initialized == 1 && get_emul_rotation() != rotation_type ) {
872                         do_rotation_event( rotation_type );
873                     }
874
875 #ifndef CONFIG_USE_SHM
876                     maruskin_sdl_resize(); // send sdl event
877 #endif
878                     break;
879                 }
880                 case RECV_SCREEN_SHOT: {
881                     log_cnt += sprintf( log_buf + log_cnt, "RECV_SCREEN_SHOT ==\n" );
882                     TRACE( log_buf );
883
884                     QemuSurfaceInfo* info = get_screenshot_info();
885
886                     if ( info ) {
887                         send_skin_data( client_sock, SEND_SCREEN_SHOT, info->pixel_data, info->pixel_data_length, 1 );
888                         free_screenshot_info( info );
889                     } else {
890                         ERR( "Fail to get screenshot data.\n" );
891                     }
892
893                     break;
894                 }
895                 case RECV_DETAIL_INFO: {
896                     log_cnt += sprintf( log_buf + log_cnt, "RECV_DETAIL_INFO ==\n" );
897                     TRACE( log_buf );
898
899                     DetailInfo* detail_info = get_detail_info( qmu_argc, qmu_argv );
900
901                     if ( detail_info ) {
902                         send_skin_data( client_sock, SEND_DETAIL_INFO, (unsigned char*) detail_info->data,
903                             detail_info->data_length, 0 );
904                         free_detail_info( detail_info );
905                     } else {
906                         ERR( "Fail to get detail info.\n" );
907                     }
908
909                     break;
910                 }
911                 case RECV_RAM_DUMP: {
912                     log_cnt += sprintf(log_buf + log_cnt, "RECV_RAM_DUMP ==\n");
913                     TRACE(log_buf);
914
915                     do_ram_dump();
916                     break;
917                 }
918                 case RECV_GUESTMEMORY_DUMP: {
919                     log_cnt += sprintf(log_buf + log_cnt, "RECV_GUESTMEMORY_DUMP ==\n");
920                     TRACE(log_buf);
921
922                     do_guestmemory_dump();
923                     break;
924                 }
925                 case RECV_RESPONSE_HEART_BEAT: {
926                     log_cnt += sprintf(log_buf + log_cnt, "RECV_RESPONSE_HEART_BEAT ==\n");
927 #if 0
928                     TRACE(log_buf);
929 #endif
930                     TRACE("recv HB req_id:%d\n", req_id);
931
932                     pthread_mutex_lock(&mutex_recv_heartbeat_count);
933                     recv_heartbeat_count = 0;
934                     pthread_mutex_unlock(&mutex_recv_heartbeat_count);
935
936                     break;
937                 }
938                 case RECV_OPEN_SHELL: {
939                     log_cnt += sprintf(log_buf + log_cnt, "RECV_OPEN_SHELL ==\n");
940                     TRACE(log_buf);
941
942                     do_open_shell();
943                     break;
944                 }
945                 case RECV_HOST_KBD: {
946                     char on = 0;
947
948                     log_cnt += sprintf(log_buf + log_cnt, "RECV_HOST_KBD ==\n");
949                     TRACE(log_buf);
950
951                     if (length <= 0) {
952                         INFO("there is no data looking at 0 length.\n");
953                         continue;
954                     }
955
956                     memcpy(&on, recvbuf, sizeof(on));
957                     onoff_host_kbd(on);
958                     break;
959                 }
960
961                 case RECV_CLOSE: {
962                     log_cnt += sprintf(log_buf + log_cnt, "RECV_CLOSE ==\n");
963                     TRACE(log_buf);
964
965                     request_close();
966                     break;
967                 }
968                 case RECV_RESPONSE_SHUTDOWN: {
969                     log_cnt += sprintf( log_buf + log_cnt, "RECV_RESPONSE_SHUTDOWN ==\n" );
970                     INFO( log_buf );
971
972                     stop_server = 1;
973                     break;
974                 }
975                 default: {
976                     log_cnt += sprintf( log_buf + log_cnt, "!!! unknown command : %d\n", cmd );
977                     TRACE( log_buf );
978
979                     ERR( "!!! unknown command : %d\n", cmd );
980                     break;
981                 }
982                 }
983
984             }
985
986         }
987
988     }
989
990     stop_heart_beat();
991
992     /* clean up */
993     if (server_sock) {
994 #ifdef CONFIG_WIN32
995         closesocket(server_sock);
996 #else
997         close(server_sock);
998 #endif
999         server_sock = 0;
1000     }
1001
1002     if (shutdown_qemu) {
1003         print_fail_log();
1004         shutdown_qemu_gracefully();
1005     }
1006
1007     return NULL;
1008 }
1009
1010 static int recv_n(int sockfd, char* read_buf, int recv_len)
1011 {
1012     int total_cnt = 0;
1013     int recv_cnt = 0;
1014
1015     while (1) {
1016         recv_cnt = recv(sockfd,
1017             (void*)(read_buf + recv_cnt), (recv_len - recv_cnt), 0);
1018
1019         if (0 > recv_cnt) {
1020             return recv_cnt;
1021         } else if (0 == recv_cnt) {
1022             if (total_cnt == recv_len) {
1023                 return total_cnt;
1024             } else {
1025                 continue;
1026             }
1027         } else {
1028             total_cnt += recv_cnt;
1029
1030             if (total_cnt == recv_len) {
1031                 return total_cnt;
1032             } else {
1033                 continue;
1034             }
1035         }
1036     }
1037
1038     return 0;
1039 }
1040
1041 static void make_header(int sockfd,
1042     short send_cmd, int data_length, char* sendbuf, int print_log)
1043 {
1044     memset(sendbuf, 0, SEND_HEADER_SIZE);
1045
1046     int request_id = (MAX_REQ_ID == seq_req_id) ? 0 : ++seq_req_id;
1047     if (print_log) {
1048         TRACE("== SEND skin request_id:%d, send_cmd:%d ==\n", request_id, send_cmd);
1049     }
1050     request_id = htonl(request_id);
1051
1052     short cmd = send_cmd;
1053     cmd = htons(cmd);
1054
1055     int length = data_length;
1056     length = htonl(length);
1057
1058     char* p = sendbuf;
1059     memcpy(p, &request_id, sizeof(request_id));
1060     p += sizeof(request_id);
1061     memcpy(p, &cmd, sizeof(cmd));
1062     p += sizeof(cmd);
1063     memcpy(p, &length, sizeof(length));
1064 }
1065
1066 static int send_n(int sockfd,
1067     unsigned char* data, int length, int big_data)
1068 {
1069     int send_cnt = 0;
1070     int total_cnt = 0;
1071
1072     int buf_size = (big_data != 0) ?
1073         SEND_BIG_BUF_SIZE : SEND_BUF_SIZE;
1074
1075     /* use malloc instead of general array definition
1076     to avoid seg fault in 'alloca' in MinGW env, only using big buf size */
1077     char* databuf = (char*)g_malloc0(buf_size);
1078
1079     if (big_data != 0) {
1080         TRACE("big_data send_n start. length:%d\n", length);
1081     } else {
1082         TRACE("send_n start. length:%d\n", length);
1083     }
1084
1085     while (1) {
1086         if (total_cnt == length) {
1087             break;
1088         }
1089
1090         if (buf_size < (length - total_cnt)) {
1091             send_cnt = buf_size;
1092         } else {
1093             send_cnt = (length - total_cnt);
1094         }
1095
1096         memset(databuf, 0, send_cnt);
1097         memcpy(databuf, (char*) (data + total_cnt), send_cnt);
1098
1099         send_cnt = send(sockfd, databuf, send_cnt, 0);
1100
1101         if (0 > send_cnt) {
1102             ERR("send_n error. error code:%d\n", send_cnt);
1103             return send_cnt;
1104         } else {
1105             total_cnt += send_cnt;
1106         }
1107     }
1108
1109     g_free(databuf);
1110
1111     TRACE("send_n finished.\n");
1112
1113     return total_cnt;
1114 }
1115
1116 static int send_skin_header_only(int sockfd, short send_cmd, int print_log)
1117 {
1118     char headerbuf[SEND_HEADER_SIZE] = { 0, };
1119
1120     make_header(sockfd, send_cmd, 0, headerbuf, print_log);
1121
1122     /* send */
1123     pthread_mutex_lock(&mutex_send_data);
1124
1125     int send_count = send(sockfd, headerbuf, SEND_HEADER_SIZE, 0);
1126
1127     pthread_mutex_unlock(&mutex_send_data);
1128
1129     return send_count;
1130 }
1131
1132 static int send_skin_data(int sockfd,
1133     short send_cmd, unsigned char* data, int length, int big_data)
1134 {
1135
1136     char headerbuf[SEND_HEADER_SIZE] = { 0, };
1137
1138     if (data == NULL) {
1139         ERR("send data is NULL.\n");
1140         return -1;
1141     }
1142
1143     make_header(sockfd, send_cmd, length, headerbuf, 1);
1144
1145     /* send */
1146     pthread_mutex_lock(&mutex_send_data);
1147
1148     int header_cnt = send(sockfd, headerbuf, SEND_HEADER_SIZE, 0);
1149     if (0 > header_cnt) {
1150         ERR("send header for data is NULL.\n");
1151         pthread_mutex_unlock(&mutex_send_data);
1152
1153         return header_cnt;
1154     }
1155
1156     int send_cnt = send_n(sockfd, data, length, big_data);
1157
1158     pthread_mutex_unlock(&mutex_send_data);
1159
1160     TRACE("send_n result:%d\n", send_cnt);
1161
1162     return send_cnt;
1163 }
1164
1165 static void* do_heart_beat(void* args)
1166 {
1167     is_started_heartbeat = 1;
1168
1169     int send_fail_count = 0;
1170     int restart_client_count = 0;
1171     int need_restart_skin_client = 0;
1172     int shutdown = 0;
1173
1174     unsigned int booting_handicap_cnt = 0;
1175     unsigned int hb_interval = HEART_BEAT_INTERVAL * 1000;
1176
1177     while ( 1 ) {
1178         if (booting_handicap_cnt < 5) {
1179             booting_handicap_cnt++;
1180
1181 #ifdef CONFIG_WIN32
1182             Sleep(hb_interval * 10); /* 10sec */
1183 #else
1184             usleep(hb_interval * 1000 * 10);
1185 #endif
1186         } else {
1187 #ifdef CONFIG_WIN32
1188             Sleep(hb_interval); /* 1sec */
1189 #else
1190             usleep(hb_interval * 1000);
1191 #endif
1192         }
1193
1194         if (stop_heartbeat) {
1195             INFO("[HB] stop heart beat.\n");
1196             break;
1197         }
1198
1199         if ( client_sock ) {
1200             TRACE( "send HB\n" );
1201             if ( 0 > send_skin_header_only( client_sock, SEND_HEART_BEAT, 0 ) ) {
1202                 send_fail_count++;
1203             } else {
1204                 send_fail_count = 0;
1205             }
1206         } else {
1207             /* fail to get socket in accepting or client is not yet accepted */
1208             send_fail_count++;
1209             TRACE( "[HB] client socket is NULL yet.\n" );
1210         }
1211
1212         if ( HEART_BEAT_FAIL_COUNT < send_fail_count ) {
1213             ERR( "[HB] fail to send heart beat to skin. fail count:%d\n", HEART_BEAT_FAIL_COUNT );
1214             need_restart_skin_client = 1;
1215         }
1216
1217         pthread_mutex_lock( &mutex_recv_heartbeat_count );
1218         recv_heartbeat_count++;
1219         if ( 1 < recv_heartbeat_count ) {
1220             TRACE( "[HB] recv_heartbeat_count:%d\n", recv_heartbeat_count );
1221         }
1222         pthread_mutex_unlock( &mutex_recv_heartbeat_count );
1223
1224         if ( HEART_BEAT_EXPIRE_COUNT < recv_heartbeat_count ) {
1225             ERR( "received heartbeat count is expired.\n" );
1226             need_restart_skin_client = 1;
1227         }
1228
1229         if ( need_restart_skin_client ) {
1230
1231             if ( RESTART_CLIENT_MAX_COUNT <= restart_client_count ) {
1232                 shutdown = 1;
1233                 break;
1234             } else {
1235
1236                 if ( is_requested_shutdown_qemu_gracefully() ) {
1237                     INFO( "requested shutdown_qemu_gracefully, do not retry starting skin client process.\n" );
1238                     break;
1239                 } else {
1240
1241                     send_fail_count = 0;
1242                     recv_heartbeat_count = 0;
1243                     need_restart_skin_client = 0;
1244                     restart_client_count++;
1245
1246                     INFO( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" );
1247                     INFO( "!!! restart skin client process !!!\n" );
1248                     INFO( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" );
1249
1250                     is_force_close_client = 1;
1251                     if ( client_sock ) {
1252 #ifdef CONFIG_WIN32
1253                         closesocket( client_sock );
1254 #else
1255                         close( client_sock );
1256 #endif
1257                         client_sock = 0;
1258                     }
1259
1260                     start_skin_client( skin_argc, skin_argv );
1261
1262                 }
1263
1264             }
1265
1266         }
1267
1268     }
1269
1270     if ( shutdown ) {
1271
1272         INFO( "[HB] shutdown skin_server by heartbeat thread.\n" );
1273
1274         is_force_close_client = 1;
1275         if ( client_sock ) {
1276 #ifdef CONFIG_WIN32
1277             closesocket( client_sock );
1278 #else
1279             close( client_sock );
1280 #endif
1281             client_sock = 0;
1282         }
1283
1284         stop_server = 1;
1285         if ( server_sock ) {
1286 #ifdef CONFIG_WIN32
1287             closesocket( server_sock );
1288 #else
1289             close( server_sock );
1290 #endif
1291             server_sock = 0;
1292         }
1293
1294         ERR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
1295         ERR("!!! Fail to operate with heartbeat from skin client. Shutdown QEMU !!!\n");
1296         ERR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
1297
1298         maru_register_exit_msg(MARU_EXIT_HB_TIME_EXPIRED, NULL);
1299         shutdown_qemu_gracefully();
1300
1301     }
1302
1303     return NULL;
1304
1305 }
1306
1307 static int start_heart_beat(void)
1308 {
1309     if (is_started_heartbeat) {
1310         return 1;
1311     }
1312
1313     if (ignore_heartbeat) {
1314         return 1;
1315     } else {
1316         if (0 != pthread_create(&thread_id_heartbeat, NULL, do_heart_beat, NULL)) {
1317             ERR("[HB] fail to create heartbean pthread.\n");
1318             return 0;
1319         } else {
1320             return 1;
1321         }
1322     }
1323 }
1324
1325 static void stop_heart_beat(void)
1326 {
1327     stop_heartbeat = 1;
1328 }