Remove unused directories and files in video_in_hal
[staging/basesystem.git] / service / system / logger_service / server / realtimeUsbLog / src / ss_logger_realtime_usb.cpp
1 /*
2  * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 ///////////////////////////////////////////////////////////////////////////////
18 /// \ingroup  tag_NS_InterfaceunifiedLogCapture
19 /// \brief    This file contains the standard set functions called by the NS
20 //            dispatcher on application initialization, cleanup and wakeup.
21 ///
22 ///////////////////////////////////////////////////////////////////////////////
23 // System Headers
24 #include <fcntl.h>
25 #include <stdio.h>
26 #include <unistd.h>
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <sys/param.h>
31 #include <sys/time.h>
32 #include <mqueue.h>
33 #include <errno.h>
34 #include <string.h>
35 #include <dirent.h>
36 #include <time.h>
37 #include <loggerservicedebug_loggerservicelog.h>
38 #include <native_service/frameworkunified_multithreading.h>
39 #include <system_service/ss_system_manager_if.h>
40 #include <system_service/ss_system_manager_notifications.h>
41 #include <native_service/frameworkunified_timer.h>
42 #include <system_service/ss_devicedetection_service_notifications.h>
43 #include <system_service/ss_devicedetection_service.h>
44 #include <system_service/ss_devicedetection_service_protocol.h>
45 #include <system_service/ss_devicedetection_service_ifc.h>
46 #include <native_service/frameworkunified_application.h>
47 #include <native_service/frameworkunified_framework_if.h>
48 #include <native_service/frameworkunified_service_protocol.h>
49 #include <native_service/frameworkunified_types.h>
50 #include <queue>
51 #include <string>
52
53 // System definition
54 #ifndef TN_LOGGERRTIME
55 #define TN_LOGGERRTIME     "LoggerRtime"
56 #define PR_LOGGERRTIME_S   PR_TSS_S
57 #define PR_LOGGERRTIME     PR_TSS
58 #endif  // TN_LOGGERRTIME
59 // Queue resource
60 #define USB_REALTIME_MSGMAX 256
61 #define USB_REALTIME_SIZMAX 4096
62 #define USB_REALTIME_QNAME  "/PlRtLogger"
63 // Folder path
64 #define USB_RT_FOLDERPATH_ "/REALTIME_"
65
66 // older path
67 #define USB_RT_TMP_PATH "/tmp"
68 // File name
69 #define USB_RT_LOGNAME_TMP "usbrt_tmp.log"
70 #define ENC_BUF_MAX_SIZE   (1024*8)
71
72 #ifdef RELEASE_BUILD
73 // encrypt values
74 #define DEV_ENC_EXTENSION  ".enc1"
75 #define REL_ENC_EXTENSION  ".enc2"
76 #define ALIGNMENT_SIZE 4
77 #endif  // RELEASE_BUILD
78
79 // File path
80 #define USB_RT_LOGNAME_ "loggerservice_usb__realtime"
81 // Max size of each log file
82 #define USB_RT_FILE_SIZE (1024*1024)
83 // Num of logs to write in std::queue at one time
84 #define QUELOG_WRITE_BLOCK_NUM 300
85 // Max of logs to save in std::queue
86 #define QUELOG_SAVE_MAX   12000
87 #define QUELOG_DELNUM   (QUELOG_WRITE_BLOCK_NUM*2)  // num of deletion at one time
88 // TIMER ID
89 #define USB_RT_TIMER_EV  0x89
90 #define USB_RT_TIMER_SYNC 1   // kind
91 #define USB_RT_TIMER_CYCLE 10000  // cycle of timeout(msec)
92
93 static HANDLE g_rt_tid = NULL;
94 static int g_wfd = -1;
95 static mqd_t g_qid = (mqd_t) - 1;
96 static int g_num_of_file = 1;
97 static char g_mnt_path[MAXPATHLEN];
98 static char g_fld_path[MAXPATHLEN];
99 static char g_log_path[MAXPATHLEN];
100 static char *g_log_name;
101 static bool g_need_sync = false;
102 static size_t g_filesize = 0;
103
104 //static queue<string> g_saveq;
105 static std::queue<std::string> g_saveq;
106
107 static DeviceDetectionServiceIf g_devDetect;
108 static bool g_usb_available = false;
109
110 static char g_log_tmp_path[MAXPATHLEN];
111
112 EFrameworkunifiedStatus rtUsbLogThread(HANDLE hApp);
113 EFrameworkunifiedStatus rtUsbLogTShutdown(HANDLE hApp);
114 EFrameworkunifiedStatus OnPowerOnOffNotification(HANDLE hApp);
115
116 EFrameworkunifiedStatus StartTimer(HANDLE hApp, const UI_32 timeout);
117 EFrameworkunifiedStatus CancelTimer(void);
118
119 // DeviceDetection Related funcs
120 EFrameworkunifiedStatus OnDeviceDetectionAvailability(HANDLE hApp);
121 EFrameworkunifiedStatus OnDeviceDetectionOpenSessionACK(HANDLE hApp);
122 EFrameworkunifiedStatus onDeviceDetectionCloseSessionACK(HANDLE hApp);
123 EFrameworkunifiedStatus onUsbDetectCallback(HANDLE hApp);
124
125 EFrameworkunifiedStatus EncryptAndCopyFile(void);
126
127 EFrameworkunifiedStatus StartRtUsbLogThread(HANDLE hApp) {
128   FrameworkunifiedChildThreadAttr attr;
129   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
130
131   if (g_rt_tid != NULL) {
132     return eFrameworkunifiedStatusOK;
133   }
134
135   // Create Realtime USB Logging Thread and start
136   memset(&attr, 0, sizeof(FrameworkunifiedChildThreadAttr));
137   // One time while to break on Error
138   if (eFrameworkunifiedStatusOK
139       != (l_eStatus = FrameworkunifiedCreateChildThreadAttrSetSched(&attr,
140                                                        eFrameworkunifiedSchedPolicyTSS,
141                                                        PR_LOGGERRTIME))) {
142     return l_eStatus;
143   }
144   g_rt_tid = FrameworkunifiedCreateChildThreadWithAttribute(hApp, TN_LOGGERRTIME,
145                                                rtUsbLogThread,
146                                                rtUsbLogTShutdown, &attr);
147   if (g_rt_tid == NULL) {
148     l_eStatus = eFrameworkunifiedStatusFail;
149   } else {
150     l_eStatus = FrameworkunifiedStartChildThread(hApp, g_rt_tid, 0, (PVOID) NULL);
151   }
152
153   return l_eStatus;
154 }
155
156 EFrameworkunifiedStatus StopRtUsbLogThread(HANDLE hApp) {
157   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
158
159   // Close fd to sync
160   if (g_wfd != -1) {
161     if (0 != close(g_wfd)) {
162       l_eStatus = eFrameworkunifiedStatusFail;
163     }
164     EncryptAndCopyFile();
165   }
166   // Close message queue
167   if (g_qid != (mqd_t) - 1) {
168     if (0 != mq_close(g_qid)) {
169       l_eStatus = eFrameworkunifiedStatusFail;
170     }
171   }
172   // Terminate Thread
173   if (eFrameworkunifiedStatusOK != FrameworkunifiedStopChildThread(hApp, g_rt_tid, 0, NULL)) {
174     l_eStatus = eFrameworkunifiedStatusFail;
175   }
176   if (eFrameworkunifiedStatusOK != FrameworkunifiedDestroyChildThread(hApp, g_rt_tid)) {
177     l_eStatus = eFrameworkunifiedStatusFail;
178   }
179
180   return l_eStatus;
181 }
182
183 EFrameworkunifiedStatus OnPowerOnOffNotification(HANDLE hApp) {
184   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
185   T_SS_SM_UserModeOnOffNotification_StructType onoff_mode;
186
187   l_eStatus = FrameworkunifiedGetMsgDataOfSize(hApp, (PVOID) &onoff_mode,
188                                   sizeof(onoff_mode));
189   if (eFrameworkunifiedStatusOK != l_eStatus) {
190     fprintf(stderr, "%s: Failed to fetch OnOff Mode\n", __FUNCTION__);
191     return l_eStatus;
192   }
193   if (!onoff_mode.isUserModeOn) {  // ACC-OFF
194     // Close fd to sync
195     if (g_wfd >= 0) {
196       syncfs(g_wfd);
197       if (0 != close(g_wfd)) {
198         l_eStatus = eFrameworkunifiedStatusFail;
199       }
200       EncryptAndCopyFile();
201       g_wfd = -2;  // ACC-OFF detected
202     }
203   }
204   return l_eStatus;
205 }
206
207 static int getStartFileNum(void) {
208   int start = 0;
209   int num;
210   DIR *dirp;
211   struct dirent entry;
212   struct dirent *next;
213
214   if ((dirp = opendir(g_fld_path)) == NULL) {
215     fprintf(stderr, "%s: Failed in opendir, errno=%d\n", __FUNCTION__, errno);
216     return -1;
217   }
218   for (;;) {
219     if (readdir_r(dirp, &entry, &next) != 0) {
220       fprintf(stderr, "%s: Failed in readdir_r, errno=%d\n", __FUNCTION__,
221               errno);
222       closedir(dirp);
223       return -1;
224     }
225     if (next == NULL) {  // NO more
226       break;
227     }
228     if (strncmp(entry.d_name, g_log_name, strlen(g_log_name)) != 0) {
229       continue;
230     }
231     num = atoi(entry.d_name + strlen(g_log_name));
232     if (num > start) {
233       start = num;
234     }
235   }
236   closedir(dirp);
237   start++;
238
239   return start;
240 }
241
242 EFrameworkunifiedStatus WriteAndSwitchLogFile(const char* data, ssize_t size) {
243   ssize_t wrotelen;
244   char logpath[MAXPATHLEN];
245
246   wrotelen = write(g_wfd, data, size);
247   if (wrotelen != size) {
248     close(g_wfd);
249     g_wfd = -1;
250     g_filesize = 0;
251     EncryptAndCopyFile();
252     fprintf(stderr, "%s: Failed to write, size=%d, wrotelen=%d, errno=%d\n",
253
254 //            __FUNCTION__, static_cast<int32_t>size, static_cast<int32_t>wrotelen, errno);
255             __FUNCTION__, static_cast<int32_t>(size), static_cast<int32_t>(wrotelen), errno);
256
257     return eFrameworkunifiedStatusFail;
258   } else {
259     g_filesize += wrotelen;
260     g_need_sync = true;
261     if (static_cast<int>(g_filesize) >= USB_RT_FILE_SIZE) {
262       g_filesize = 0;
263       close(g_wfd);
264       EncryptAndCopyFile();
265       g_num_of_file++;
266
267
268 //      snprintf(logpath, "%s/%s", g_log_tmp_path, USB_RT_LOGNAME_TMP);
269       snprintf(logpath, MAXPATHLEN, "%s/%s", g_log_tmp_path, USB_RT_LOGNAME_TMP);
270
271       if ((g_wfd = open(logpath, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0644))
272           == -1) {
273         fprintf(stderr, "%s: Failed to open file %s, errno=%d\n", __FUNCTION__,
274                 logpath, errno);
275         return eFrameworkunifiedStatusFail;
276       }
277     }
278   }
279   return eFrameworkunifiedStatusOK;
280 }
281
282 EFrameworkunifiedStatus OnMessageQueueReceived(HANDLE hApp) {
283   ssize_t len, len2;
284   char msg[USB_REALTIME_SIZMAX], msg2[USB_REALTIME_SIZMAX];
285   char logpath[MAXPATHLEN];
286   unsigned int prior;
287   struct stat stbuf;
288
289 //  string work_str;
290   std::string work_str;
291
292   bool pushed = false;
293   const struct timespec tspec = { 0, 0 };
294
295   // write loop
296   while (1) {
297     pushed = false;
298     if (g_qid == (mqd_t) - 1) {  // Already ACC-OFFed
299       return eFrameworkunifiedStatusOK;
300     }
301     len = mq_timedreceive(g_qid, msg, sizeof(msg), &prior, &tspec);
302     if (len == (ssize_t) - 1) {  // NO more data
303       if (errno != ETIMEDOUT) {
304         fprintf(stderr, "%s: Unexpected error %d\n", __FUNCTION__, errno);
305       }
306       break;
307     }
308     // Remove overflowed log
309     if (g_saveq.size() > QUELOG_SAVE_MAX) {
310       int delnum = g_saveq.size() - QUELOG_SAVE_MAX + QUELOG_DELNUM;
311       for (int i = 0; i < delnum; i++) {
312         g_saveq.pop();
313       }
314     }
315     // check if file is opened
316     if (g_wfd == -1) {
317       /*
318        * Make folder and open log file
319        */
320       // save dequeued log
321
322 //      g_saveq.push(string((const char*) msg, len));
323       g_saveq.push(std::string((const char*) msg, len));
324
325       pushed = true;  // request pushed or NON-log message -> NO NEED to write this data to log file
326       // Check USB mounted
327       if (!g_usb_available) {
328         // No mount event is received
329         continue;
330       }
331       // Check USB mounted
332       if (stat(g_mnt_path, &stbuf) != 0) {
333         // No mount path found
334         continue;
335       }
336       // Check and make subfolder
337       int mkdres = mkdir(g_fld_path, 0666);
338       if (mkdres == 0) {
339         g_num_of_file = 1;
340       } else if (mkdres == -1 && errno == EEXIST) {
341         // Decide file number to start(Check current log files)
342         g_num_of_file = getStartFileNum();
343         if (g_num_of_file <= 0) {
344           fprintf(stderr, "%s: Failed in getStartFileNum\n", __FUNCTION__);
345           continue;
346         }
347       } else {
348         fprintf(stderr, "%s: Failed to mkdir %s, errno=%d\n", __FUNCTION__,
349                 g_fld_path, errno);
350         continue;
351       }
352
353       // Open File
354       g_filesize = 0;
355
356
357 //      snprintf(logpath, "%s/%s", g_log_tmp_path, USB_RT_LOGNAME_TMP);
358       snprintf(logpath, MAXPATHLEN, "%s/%s", g_log_tmp_path, USB_RT_LOGNAME_TMP);
359
360       if ((g_wfd = open(logpath, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0644))
361           == -1) {
362         fprintf(stderr, "%s: Failed to open file %s, errno=%d\n", __FUNCTION__,
363                 logpath, errno);
364         continue;
365       }
366     } else if (g_wfd == -2) {
367       // Already ACC-OFF, Just throw the logs away
368       continue;
369     }
370     // Write out saved log if any
371     int written_once = QUELOG_WRITE_BLOCK_NUM;  // num of written at once
372     while (1) {
373       if (g_saveq.empty()) {
374         break;
375       }
376       if (written_once >= QUELOG_WRITE_BLOCK_NUM) {
377         written_once = 0;
378         while (1) {
379           // read request queue
380           len2 = mq_timedreceive(g_qid, msg2, sizeof(msg2), &prior, &tspec);
381           if (len2 == (ssize_t) - 1) {  // NO MORE data
382             if (errno != ETIMEDOUT) {
383               fprintf(stderr, "%s: Unexpected error %d\n", __FUNCTION__, errno);
384             }
385             break;
386           }
387
388 //          g_saveq.push(string((const char*) msg2, len2));
389           g_saveq.push(std::string((const char*) msg2, len2));
390
391         }
392       }
393       work_str = g_saveq.front();
394       if (eFrameworkunifiedStatusOK
395           != WriteAndSwitchLogFile(work_str.data(), work_str.length())) {
396         fprintf(stderr, "%s: Failed in write Saved data, errno=%d\n",
397                 __FUNCTION__, errno);
398         break;
399       } else {
400         written_once++;
401         g_saveq.pop();
402       }
403     }
404     if (pushed || g_wfd == -1) {
405       continue;
406     }
407     // write data
408     if (eFrameworkunifiedStatusOK != WriteAndSwitchLogFile(msg, len)) {
409       fprintf(stderr, "%s: Failed in write Saved data-2, errno=%d\n",
410               __FUNCTION__, errno);
411     }
412   }
413   return eFrameworkunifiedStatusOK;
414 }
415
416 EFrameworkunifiedStatus OnSyncTimeout(HANDLE hApp) {
417   if (g_need_sync) {
418     if (g_wfd != -1 && g_wfd != -2) {
419       char logpath[MAXPATHLEN];
420       fsync(g_wfd);
421       close(g_wfd);
422       g_wfd = -1;
423       EncryptAndCopyFile();
424
425 //      snprintf(logpath, "%s/%s", g_log_tmp_path, USB_RT_LOGNAME_TMP);
426       snprintf(logpath, MAXPATHLEN, "%s/%s", g_log_tmp_path, USB_RT_LOGNAME_TMP);
427
428       if ((g_wfd = open(logpath, O_RDWR | O_CREAT | O_APPEND | O_CLOEXEC, 0644))
429           == -1) {
430         fprintf(stderr, "%s: Failed to open file %s, errno=%d (%s)\n",
431                 __FUNCTION__, logpath, errno, strerror(errno));
432         // because in order to continue to obtain logs.
433         return eFrameworkunifiedStatusOK;
434       }
435       g_need_sync = false;
436     }
437   }
438   return eFrameworkunifiedStatusOK;
439 }
440
441 EFrameworkunifiedStatus rtUsbLogThread(HANDLE hApp) {
442   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
443   struct mq_attr qattr;
444   const struct timespec idle_time = { 1, 0 };  // 1sec
445   HANDLE timer_handle = NULL;
446
447   // Subscribe Boot Mode Notifcation to SysMgr
448   l_eStatus = FrameworkunifiedSubscribeNotificationWithCallback(hApp,
449   NTFY_SSSystemMgrPowerOnOff,
450                                                    OnPowerOnOffNotification);
451   if (eFrameworkunifiedStatusOK != l_eStatus) {
452     fprintf(stderr, "%s: Subscribe PowerOnOff failed, status=%d\n",
453             __FUNCTION__, l_eStatus);
454   }
455   // Subscribe Device Detection Availability
456   while (1) {
457     if (g_devDetect.Initialize(hApp)) {
458       if (eFrameworkunifiedStatusOK
459           != (l_eStatus = g_devDetect.NotifyOnDeviceDetectionAvailability(
460               OnDeviceDetectionAvailability))) {
461         fprintf(stderr,
462                 "%s: DevDetec AvailabilityCallback registration failed\n",
463                 __FUNCTION__);
464       }
465       if (eFrameworkunifiedStatusOK
466           != (l_eStatus = g_devDetect.NotifyOnOpenSessionAck(
467               OnDeviceDetectionOpenSessionACK))) {
468         fprintf(stderr, "%s: DevDetec OpenSession ACK registration failed\n",
469                 __FUNCTION__);
470       }
471       if (eFrameworkunifiedStatusOK
472           != (l_eStatus = g_devDetect.NotifyOnCloseSessionAck(
473               onDeviceDetectionCloseSessionACK))) {
474         fprintf(stderr, "%s: DevDetec CloseSession ACK registration failed\n",
475                 __FUNCTION__);
476       }
477       break;
478     } else {
479       fprintf(stderr, "%s: Device Detection Object Initialization failed\n",
480               __FUNCTION__);
481       nanosleep(&idle_time, NULL);
482     }
483   }
484
485   // open message queue
486   while (1) {
487     qattr.mq_flags = 0;
488     qattr.mq_maxmsg = USB_REALTIME_MSGMAX;
489     qattr.mq_msgsize = USB_REALTIME_SIZMAX;
490     qattr.mq_curmsgs = 0;
491     if ((g_qid = mq_open(USB_REALTIME_QNAME, O_RDWR | O_CREAT, 0666, &qattr))
492         >= (mqd_t) 0) {
493       break;
494     }
495     fprintf(stderr, "%s: Failed in mq_open, errno=%d\n", __FUNCTION__, errno);
496     nanosleep(&idle_time, NULL);
497   }
498
499   // Attach callback func to message queue fd
500   l_eStatus = FrameworkunifiedAttachCallbackToDispatcherWithFd(hApp, static_cast<int>(g_qid),
501                                                   OnMessageQueueReceived);
502   if (eFrameworkunifiedStatusOK != l_eStatus) {
503     fprintf(
504         stderr,
505         "%s: Error in FrameworkunifiedAttachCallbackToDispatcherWithFd with mq_fd, status=%d\n",
506         __FUNCTION__, l_eStatus);
507     return l_eStatus;
508   }
509   // Start Cyclic Timer
510   timer_handle = FrameworkunifiedAttachTimerCallback(hApp, USB_RT_TIMER_CYCLE,
511   USB_RT_TIMER_CYCLE,
512                                         OnSyncTimeout);
513   if (timer_handle == NULL) {
514     fprintf(stderr, "%s: Error in FrameworkunifiedAttachTimerCallback\n", __FUNCTION__);
515     return eFrameworkunifiedStatusFail;
516   }
517
518   // Enter dispatcher ==> Just return
519   return eFrameworkunifiedStatusOK;
520 }
521
522 EFrameworkunifiedStatus rtUsbLogTShutdown(HANDLE hApp) {
523   return eFrameworkunifiedStatusOK;
524 }
525
526 EFrameworkunifiedStatus OnDeviceDetectionAvailability(HANDLE hApp) {
527   EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusOK;
528
529   if (FrameworkunifiedIsServiceAvailable(hApp)) {
530     if (eFrameworkunifiedStatusOK != (eStatus = g_devDetect.OpenSessionRequest())) {
531       fprintf(stderr, "%s: Open session request failed\n", __FUNCTION__);
532     }
533   } else {
534     if (eFrameworkunifiedStatusOK != (eStatus = g_devDetect.CloseSessionRequest())) {
535       fprintf(stderr, "%s: Close session request failed\n", __FUNCTION__);
536     }
537   }
538   return eStatus;
539 }
540
541 EFrameworkunifiedStatus OnDeviceDetectionOpenSessionACK(HANDLE hApp) {
542   EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusOK;
543
544   if (eFrameworkunifiedStatusOK == (eStatus = g_devDetect.DecodeOpenSessionResponse())) {
545     if (eFrameworkunifiedStatusOK
546         != (eStatus = g_devDetect.RegisterForDeviceDetectionEvent(
547             SS_DEV_DETECT_ANY_USB_EV, onUsbDetectCallback))) {
548       fprintf(stderr, "%s: Registration for SS_DEV_DETECT_ANY_USB_EV failed\n",
549               __FUNCTION__);
550     }
551   } else {
552     fprintf(stderr, "%s: Decode open session response failed\n", __FUNCTION__);
553   }
554   return eStatus;
555 }
556
557 EFrameworkunifiedStatus onDeviceDetectionCloseSessionACK(HANDLE hApp) {
558   EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusOK;
559   CloseSessionAck tCloseSessionAck;
560
561   if (hApp) {
562     if (eFrameworkunifiedStatusOK
563         == (eStatus = FrameworkunifiedGetMsgDataOfSize(hApp, &tCloseSessionAck,
564                                           sizeof(tCloseSessionAck)))) {
565       if (eFrameworkunifiedStatusOK != tCloseSessionAck.eStatus) {
566         eStatus = eFrameworkunifiedStatusFail;
567       }
568     }
569   }
570   return eStatus;
571 }
572
573 EFrameworkunifiedStatus onUsbDetectCallback(HANDLE hApp) {
574   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
575   SS_MediaDetectInfo l_tMediaDetectInfo;
576
577   if (eFrameworkunifiedStatusOK
578       != (l_eStatus = FrameworkunifiedGetMsgDataOfSize(hApp, &l_tMediaDetectInfo,
579                                           sizeof(l_tMediaDetectInfo)))) {
580     fprintf(stderr, "%s: FrameworkunifiedGetMsgDataOfSize Failed Status:0x%x\n",
581             __FUNCTION__, l_eStatus);
582   } else {
583     if (l_tMediaDetectInfo.dev_type != eUSB) {  // NOT mass storage device
584       return l_eStatus;
585     }
586     if (l_tMediaDetectInfo.bIsDeviceAvailable) {
587       if (g_usb_available) {  // Already mounted
588         return l_eStatus;
589       }
590       // set USB device available
591       g_usb_available = true;
592       // Organize paths to access
593       strncpy(g_mnt_path, l_tMediaDetectInfo.deviceMountpath,
594               sizeof(g_mnt_path));
595
596       snprintf(g_fld_path, MAXPATHLEN, "%s%s", g_mnt_path, USB_RT_FOLDERPATH_);
597       snprintf(g_log_path, MAXPATHLEN, "%s/%s", g_fld_path, USB_RT_LOGNAME_);
598       g_log_name = const_cast<char*>(USB_RT_LOGNAME_);
599
600
601
602 //      snprintf(g_log_tmp_path, "%s", USB_RT_TMP_PATH);
603       snprintf(g_log_tmp_path, MAXPATHLEN, "%s", USB_RT_TMP_PATH);
604
605
606     } else {
607       // unset USB device available
608       if (strcmp(l_tMediaDetectInfo.deviceMountpath, g_mnt_path) == 0) {
609         g_usb_available = false;
610         g_mnt_path[0] = 0;
611         if (g_wfd != -1 && g_wfd != -2) {
612           close(g_wfd);
613           g_wfd = -1;
614           EncryptAndCopyFile();
615         }
616       }
617     }
618   }
619
620   return (l_eStatus);
621 }
622
623 EFrameworkunifiedStatus EncryptAndCopyFile(void) {
624   char usblogpath[MAXPATHLEN];
625   char logpath[MAXPATHLEN];
626   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
627   int rfd, wfd;
628   int ret;
629   struct stat istat_buf;
630
631
632 //  snprintf(usblogpath, "%s%05d.log", g_log_path, g_num_of_file);
633
634 //  snprintf(logpath, "%s/%s", g_log_tmp_path, USB_RT_LOGNAME_TMP);
635   snprintf(usblogpath, MAXPATHLEN, "%s%05d.log", g_log_path, g_num_of_file);
636
637   snprintf(logpath, MAXPATHLEN, "%s/%s", g_log_tmp_path, USB_RT_LOGNAME_TMP);
638
639
640   rfd = open(logpath, O_RDWR | O_CLOEXEC);
641   if (rfd == -1) {
642     fprintf(stderr, "%s: Error. Failed to open file: %s for reading.\n",
643             __FUNCTION__, logpath);
644     return eFrameworkunifiedStatusFail;
645   }
646
647   ret = fstat(rfd, &istat_buf);
648   if (ret < 0) {
649     fprintf(stderr, "%s: Error. stat(%s). errno: %d, %s \n", __FUNCTION__,
650             logpath, errno, strerror(errno));
651     close(rfd);
652     return eFrameworkunifiedStatusFail;
653   } else {
654     BYTE *pData;
655     int total_len;
656     int read_len;
657     off_t total_size = istat_buf.st_size;
658
659     wfd = open(usblogpath, O_RDWR | O_APPEND | O_TRUNC | O_CREAT | O_CLOEXEC,
660                0644);
661     if (wfd == -1) {
662       fprintf(stderr, "%s: Error. Failed to open file: %s for reading.\n",
663               __FUNCTION__, usblogpath);
664       close(rfd);
665       return eFrameworkunifiedStatusFail;
666     }
667
668     pData = reinterpret_cast<BYTE*>(malloc(ENC_BUF_MAX_SIZE));
669     if (pData == NULL) {
670       fprintf(stderr, "%s: Error. Failed to malloc %d byte for dst \n",
671               __FUNCTION__, ENC_BUF_MAX_SIZE);
672       close(rfd);
673       close(wfd);
674       return eFrameworkunifiedStatusFail;
675     }
676
677     total_len = static_cast<int>(total_size);
678     do {
679       read_len = read(rfd, pData, ENC_BUF_MAX_SIZE);
680       if (read_len == -1) {
681         fprintf(stderr, "%s: Error. File read failed. errno: %d, %s \n",
682                 __FUNCTION__, errno, strerror(errno));
683         l_eStatus = eFrameworkunifiedStatusFail;
684         break;
685       }
686       ret = write(wfd, pData, read_len);
687       if (ret == -1) {
688         fprintf(stderr, "%s: Error. length(%d) no space to write: %d, %s \n",
689                 __FUNCTION__, ret, errno, strerror(errno));
690         l_eStatus = eFrameworkunifiedStatusFail;
691         break;
692       }
693       total_len -= read_len;
694     } while (total_len > 0);
695
696     fsync(wfd);
697     free(pData);
698     close(wfd);
699     close(rfd);
700
701     if (l_eStatus == eFrameworkunifiedStatusFail) {
702       return l_eStatus;
703     }
704     {
705       // Synchronization security
706       struct stat ostat_buf;
707       while (1) {
708         ret = stat(usblogpath, &ostat_buf);
709         if (ret < 0) {
710           fprintf(stderr, "%s: Error. stat(%s). errno: %d, %s", __FUNCTION__,
711                   usblogpath, errno, strerror(errno));
712           break;
713         }
714         if (ostat_buf.st_size >= total_size) {
715           break;
716         }
717         usleep(1000);  // interval
718       }
719     }
720   }
721   return l_eStatus;
722 }