31b849a29e73898ee88d60487abd5b34e4652da3
[platform/core/system/swap-manager.git] / daemon / sys_stat.c
1 /*
2  *  DA manager
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:
7  *
8  * Jaewon Lim <jaewon81.lim@samsung.com>
9  * Woojin Jung <woojin2.jung@samsung.com>
10  * Juyoung Kim <j0.kim@samsung.com>
11  * Cherepanov Vitaliy <v.cherepanov@samsung.com>
12  * Nikita Kalyazin    <n.kalyazin@samsung.com>
13  *
14  * Licensed under the Apache License, Version 2.0 (the "License");
15  * you may not use this file except in compliance with the License.
16  * You may obtain a copy of the License at
17  *
18  * http://www.apache.org/licenses/LICENSE-2.0
19  *
20  * Unless required by applicable law or agreed to in writing, software
21  * distributed under the License is distributed on an "AS IS" BASIS,
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23  * See the License for the specific language governing permissions and
24  * limitations under the License.
25  *
26  * Contributors:
27  * - S-Core Co., Ltd
28  * - Samsung RnD Institute Russia
29  *
30  */
31
32 #include <glob.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <stdbool.h>
37 #include <ctype.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <sys/time.h>
41 #include <sys/vfs.h>
42 #include <fcntl.h>
43 #include <unistd.h>
44 #include <dirent.h>
45 #include <errno.h>
46 #include <assert.h>
47 #include <inttypes.h>
48 #include <stdint.h>
49
50 #include <system_info.h>
51 #include <runtime_info.h>
52 #include <telephony_network.h>
53 #include <call.h>
54
55 #include "da_protocol.h"
56 #include "da_data.h"
57
58 #include "vconf.h"
59
60 #include "sys_stat.h"
61 #include "daemon.h"
62 #include "debug.h"
63
64 // defines for runtime environment
65 #define FOR_EACH_CPU
66
67 #define BUFFER_MAX                      1024
68 #define LARGE_BUFFER            512
69 #define MIDDLE_BUFFER           256
70 #define SMALL_BUFFER            64
71 #define PROCPATH_MAX            32
72 #define STATUS_STRING_MAX       16
73 #define MAX_NUM_OF_FREQ         16
74
75 #define MEM_SLOT_TOTAL          0
76 #define MEM_SLOT_FREE           1
77 #define MEM_SLOT_BUFFER         2
78 #define MEM_SLOT_CACHED         3
79 #define MEM_SLOT_MAX            4
80
81 #define MIN_TICKS_FOR_LOAD      8
82 #define MIN_TOTAL_TICK          10
83 #define SYS_INFO_TICK           100     // TODO : change to (Hertz * profiling period)
84
85 #define CPUMHZ          "cpu MHz"
86 #define DA_PROBE_TIZEN_SONAME           "da_probe_tizen.so"
87 #define DA_PROBE_OSP_SONAME                     "da_probe_osp.so"
88 #define CAMCORDER_FILE          "/usr/etc/mmfw_camcorder.ini"
89 #define CAMERA_COUNT_STR        "DeviceCount"
90
91 enum PROCESS_DATA
92 {
93         PROCDATA_STAT,
94         PROCDATA_SMAPS
95 };
96
97 // declared by greatim
98 static int Hertz = 0;
99 static int num_of_cpu = 0;
100 static int num_of_freq = 0;
101 static uint64_t mem_slot_array[MEM_SLOT_MAX];
102 static CPU_t* cpus = NULL;
103 static unsigned long probe_so_size = 0;
104
105
106 int get_file_status_no_open(int pfd, const char *filename)
107 {
108         int status = 0;
109         char buf[STATUS_STRING_MAX];
110
111         if (unlikely(pfd < 0)) {
112                 // file is not open
113                 return 0;
114         }
115
116         lseek(pfd, 0, SEEK_SET);        // rewind to start of file
117
118         // read from file
119         if (unlikely(read(pfd, buf, STATUS_STRING_MAX) == -1))
120                 status =  -(errno);
121         else
122                 status = atoi(buf);
123
124         return status;
125 }
126 // daemon api : get status from file
127 // pfd must not be null
128 int get_file_status(int *pfd, const char *filename)
129 {
130         int status = 0;
131
132         if (likely(pfd != NULL)) {
133                 //open if is not open
134                 if (unlikely(*pfd < 0)) {
135                         // open file first
136                         *pfd = open(filename, O_RDONLY);
137                         if (unlikely(*pfd == -1)) {
138                                 /* This file may absent in the system */
139                                 return 0;
140                         }
141                 }
142
143                 if (unlikely(*pfd < 0)) {
144                         //file is open. lets read
145                         status = get_file_status_no_open(*pfd, filename);
146                 }
147
148         }
149
150         return status;
151 }
152
153 // =============================================================================
154 // device status information getter functions
155 // =============================================================================
156 static int get_wifi_status()
157 {
158         int wifi_status = 0;
159         int res = 0;
160
161         res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_status);
162         if (unlikely(res < 0)) {
163                 LOG_ONCE_W("get error #%d\n", res);
164                 wifi_status = VCONFKEY_WIFI_OFF;
165         }
166
167         return wifi_status;
168 }
169
170 static int get_bt_status()
171 {
172         int bt_status = false;
173         int res = 0;
174
175         res = vconf_get_int(VCONFKEY_BT_STATUS, &bt_status);
176         if (unlikely(res < 0)) {
177                 LOG_ONCE_W("get error #%d\n", res);
178                 bt_status = VCONFKEY_BT_STATUS_OFF;
179         }
180
181         return bt_status;
182 }
183
184 static int get_gps_status()
185 {
186         int gps_status = 0;
187         int res = 0;
188
189         res = vconf_get_int(VCONFKEY_LOCATION_ENABLED, &gps_status);
190         if(unlikely(res < 0)) {
191                 LOG_ONCE_W("get error #%d\n", res);
192                 gps_status = VCONFKEY_LOCATION_GPS_OFF;
193         } else if(gps_status != 0) {
194                 res = vconf_get_int(VCONFKEY_LOCATION_GPS_STATE, &gps_status);
195                 if (unlikely(res < 0)) {
196                         LOG_ONCE_W("get error #%d\n", res);
197                         gps_status = VCONFKEY_LOCATION_GPS_OFF;
198                 }
199         }
200
201         return gps_status;
202 }
203
204 static void init_brightness_status()
205 {
206 #ifdef DEVICE_ONLY
207         DIR *dir_info;
208         struct dirent *dir_entry;
209         char fullpath[PATH_MAX];
210
211         dir_info = opendir(BRIGHTNESS_PARENT_DIR);
212         if (dir_info != NULL) {
213                 while ((dir_entry = readdir(dir_info)) != NULL) {
214                         if (strcmp(dir_entry->d_name, ".") == 0 ||
215                             strcmp(dir_entry->d_name, "..") == 0)
216                                 continue;
217                         else { /* first directory */
218                                 sprintf(fullpath,
219                                         BRIGHTNESS_PARENT_DIR "/%s/"
220                                         BRIGHTNESS_FILENAME,
221                                         dir_entry->d_name);
222                                 get_file_status(&manager.fd.brightness,
223                                                 fullpath);
224                         }
225                 }
226                 closedir(dir_info);
227         } else {
228                 /* do nothing */
229         }
230 #else
231         get_file_status(&manager.fd.brightness, EMUL_BRIGHTNESSFD);
232 #endif
233 }
234
235 static int get_brightness_status()
236 {
237         return get_file_status_no_open(manager.fd.brightness, EMUL_BRIGHTNESSFD);
238 }
239
240 static int get_max_brightness()
241 {
242         int maxbrightnessfd = -1;
243         static int max_brightness = -1;
244
245         if (__builtin_expect(max_brightness < 0, 0)) {
246 #ifdef DEVICE_ONLY
247                 DIR* dir_info;
248                 struct dirent* dir_entry;
249                 char fullpath[PATH_MAX];
250
251                 dir_info = opendir(BRIGHTNESS_PARENT_DIR);
252                 if (dir_info != NULL) {
253                         while((dir_entry = readdir(dir_info)) != NULL) {
254                                 if (strcmp(dir_entry->d_name, ".") == 0 ||
255                                     strcmp(dir_entry->d_name, "..") == 0)
256                                         continue;
257                                 else { /* first */
258                                         sprintf(fullpath,
259                                                 BRIGHTNESS_PARENT_DIR "/%s/" MAX_BRIGHTNESS_FILENAME,
260                                                 dir_entry->d_name);
261                                         max_brightness = get_file_status(&maxbrightnessfd, fullpath);
262                                 }
263                         }
264                         closedir(dir_info);
265                 } else {
266                         // do nothing
267                 }
268 #else /* DEVICE_ONLY */
269                 max_brightness = get_file_status(&maxbrightnessfd, EMUL_MAX_BRIGHTNESSFD);
270 #endif /* DEVICE_ONLY */
271         }
272
273         if (maxbrightnessfd != -1)
274                 close(maxbrightnessfd);
275
276         return max_brightness;
277 }
278
279 static void init_video_status()
280 {
281         manager.fd.video = fopen(MFCFD, "r");
282 }
283
284 static int get_video_status()
285 {
286         int video_status = 0;
287         int ret;
288         FILE *video_fp = manager.fd.video;
289         char stat[256];
290
291         if (video_fp == NULL) // file is not open
292                 return 0;
293
294         rewind(video_fp);
295         fflush(video_fp);
296
297         ret = fscanf(video_fp, "%s", stat);
298
299         if (ret != EOF)
300                 if(strncmp(stat,"active",6) == 0)
301                         video_status = 1;
302
303         return video_status;
304 }
305
306 static int get_rssi_status()
307 {
308
309         int flightmode_status;
310         int res = 0;
311
312         int rssi_status;
313         res = vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE,
314                                         &flightmode_status);
315         if(unlikely(res < 0)) {
316                 LOG_ONCE_W("get err #%d <%s>\n", res,
317                          VCONFKEY_TELEPHONY_FLIGHT_MODE);
318                 flightmode_status = 0;
319         }
320
321         if(!flightmode_status) {
322                 res = vconf_get_int(VCONFKEY_TELEPHONY_RSSI, &rssi_status);
323                 if(unlikely(res < 0)) {
324                         LOG_ONCE_W("rssi get err #%d\n", res);
325                         rssi_status = VCONFKEY_TELEPHONY_RSSI_0;
326                 }
327         } else {
328                 rssi_status = VCONFKEY_TELEPHONY_RSSI_0;
329         }
330
331         return rssi_status;
332
333         return 0;
334 }
335
336 static int get_call_status()
337 {
338         int call_status = 0;
339         int res = 0;
340
341         res = vconf_get_int(VCONFKEY_CALL_STATE, &call_status);
342         if(unlikely(res < 0)) {
343                 LOG_ONCE_W("get err #%d\n", res);
344                 call_status = VCONFKEY_CALL_OFF;
345         }
346
347         return call_status;
348 }
349
350 /* dnet means 3G? */
351 static int get_dnet_status()
352 {
353         int dnet_status = false;
354         int res = 0;
355
356         res = vconf_get_int(VCONFKEY_DNET_STATE, &dnet_status);
357         if(unlikely(res < 0)) {
358                 LOG_ONCE_W("get err #%d <%s>\n", res, VCONFKEY_DNET_STATE);
359                 dnet_status = VCONFKEY_DNET_OFF;
360         }
361
362         return dnet_status;
363 }
364
365 static int get_camera_status()
366 {
367         int camera_status = 0;
368
369         if (unlikely(vconf_get_int(VCONFKEY_CAMERA_STATE, &camera_status) < 0)) {
370                 camera_status = VCONFKEY_CAMERA_STATE_NULL;
371         }
372
373         return camera_status;
374 }
375
376 // this means silent mode?
377 static int get_sound_status()
378 {
379         int sound_status = 0;
380         int res = 0;
381
382         res = vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL,
383                              &sound_status);
384         if (unlikely(res < 0)) {
385                 LOG_ONCE_W("get err #%d\n", res);
386                 sound_status = 0;
387         }
388
389         return sound_status;
390 }
391
392 static int get_audio_status()
393 {
394         int audio_state = 0;
395         int res = 0;
396
397         res = vconf_get_int(VCONFKEY_SOUND_STATUS,
398                             &audio_state);
399         if (unlikely(res < 0)) {
400                 LOG_ONCE_W("get err #%d\n", res);
401                 audio_state = 0;
402         }
403
404         return audio_state;
405 }
406
407 static int get_vibration_status()
408 {
409         int vibration_status = 0;
410         int res = 0;
411
412         res = vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL,
413                                         &vibration_status);
414         if(unlikely(res < 0)) {
415                 LOG_ONCE_W("get err #%d\n", res);
416                 vibration_status = 0;
417         }
418
419         return vibration_status;
420 }
421
422 static void init_voltage_status()
423 {
424         get_file_status(&manager.fd.voltage, VOLTAGEFD);
425 }
426
427 static int get_voltage_status()
428 {
429         return get_file_status_no_open(manager.fd.voltage, VOLTAGEFD);
430 }
431
432 // =====================================================================
433 // cpu information getter functions
434 // =====================================================================
435 static void get_cpu_frequency(float *freqs)
436 {
437         char filename[MIDDLE_BUFFER];
438         char freq_str[SMALL_BUFFER];
439         FILE *f;
440         int cpu_n = 0;
441
442         //clean data array
443         for (cpu_n = 0; cpu_n < num_of_cpu; cpu_n++)
444                 freqs[cpu_n] = 0.0;
445
446         cpu_n = 0;
447         while (1) {
448                 //is CPU present
449                 snprintf(filename, MIDDLE_BUFFER,
450                          "/sys/devices/system/cpu/cpu%d/online", cpu_n);
451
452                 f = fopen(filename, "r");
453                 if (!f){
454                         LOGI_th_samp("file not found <%s\n>", filename);
455                         break;
456                 }
457                 fclose(f);
458
459                 //get CPU freq
460                 snprintf(filename, MIDDLE_BUFFER,
461                          "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq", cpu_n);
462                 f = fopen(filename, "r");
463                 if (!f)
464                 {
465                         //core is disabled
466                         LOGI_th_samp("core #%d diasabled\n", cpu_n);
467                         freqs[cpu_n] = 0.0;
468                 } else {
469                         //core enabled, get frequency
470                         fscanf(f, "%s", freq_str);
471                         freqs[cpu_n] = atof(freq_str);
472                         LOGI_th_samp("core #%d freq = %.0f\n", cpu_n, freqs[cpu_n]);
473                         fclose(f);
474                 }
475
476                 //next core
477                 cpu_n++;
478
479         }
480 }
481
482 // ========================================================================
483 // get cpu and memory info for each process and whole system
484 // ========================================================================
485 typedef struct _proc_node {
486         proc_t proc_data;
487         unsigned long long saved_utime;
488         unsigned long long saved_stime;
489         int found;
490         struct _proc_node *next;
491 } procNode;
492
493 static procNode *prochead = NULL;
494 static procNode *thread_prochead = NULL;
495
496 static procNode* find_node(procNode *head, pid_t pid)
497 {
498         procNode *t = head;
499
500         while (t != NULL) {
501                 if (t->proc_data.pid == pid)
502                 {
503                         t->found = 1;
504                         break;
505                 }
506                 t = t->next;
507         }
508         return t;
509 }
510
511 static procNode* add_node(procNode **head, pid_t pid)
512 {
513         procNode *n;
514
515         n = (procNode *) malloc(sizeof(procNode));
516         if (n == NULL) {
517                 LOGE("Not enough memory, add cpu info node failied");
518                 return NULL;
519         }
520
521         n->proc_data.pid = pid;
522         n->found = 1;
523         n->next = *head;
524         *head = n;
525
526         return n;
527 }
528
529 static int del_node(procNode **head, pid_t pid)
530 {
531         procNode *t;
532         procNode *prev;
533
534         t = *head;
535         prev = NULL;
536 /*      LOGI("dell t=%d\n",t); */
537         while (t != NULL) {
538                 if (t->proc_data.pid == pid) {
539                         if (prev != NULL)
540                                 prev->next = t->next;
541                         else
542                                 *head = (*head)->next;
543                         free(t);
544                         break;
545                 }
546                 prev = t;
547                 t = t->next;
548         }
549
550 /*      LOGI("ret 0\n"); */
551         return 0;
552 }
553
554 static int del_notfound_node(procNode **head)
555 {
556         procNode *proc, *prev;
557         prev = NULL;
558         for(proc = *head; proc != NULL; )
559         {
560                 if(proc->found == 0)
561                 {
562                         if(prev != NULL)
563                         {
564                                 prev->next = proc->next;
565                                 free(proc);
566                                 proc = prev->next;
567                         }
568                         else
569                         {
570                                 *head = (*head)->next;
571                                 free(proc);
572                                 proc = *head;
573                         }
574                 }
575                 else
576                 {
577                         prev = proc;
578                         proc = proc->next;
579                 }
580         }
581         return 0;
582 }
583
584 static int reset_found_node(procNode *head)
585 {
586         procNode* proc;
587         for(proc = head; proc != NULL; proc = proc->next)
588         {
589                 proc->found = 0;
590         }
591         return 0;
592 }
593
594 // return 0 for normal case
595 // return negative value for error case
596 static int parse_proc_stat_file_bypid(char *path, proc_t* P)
597 {
598         char filename[PROCPATH_MAX];
599         char buf[BUFFER_MAX];
600         int fd, num;
601         char *abuf, *bbuf;
602
603         // read from stat file
604         sprintf(filename, "%s/stat", path);
605         fd = open(filename, O_RDONLY, 0);
606
607         if(unlikely(fd == -1)){
608                 return -1;
609         }
610
611         num = read(fd, buf, BUFFER_MAX);
612         close(fd);
613
614         if(unlikely(num <= 0)){
615                 LOGE("nothing read from '%s'\n", filename);
616                 return -1;
617         } else if(num == BUFFER_MAX)
618                 num -= 1;
619
620
621         buf[num] = '\0';
622
623         // scan from buffer
624         // copy command name
625         abuf = strchr(buf, '(') + 1;
626         bbuf = strrchr(buf, ')');
627         num = bbuf - abuf;
628         if(unlikely(num >= sizeof(P->command)))
629                 num = sizeof(P->command) - 1;
630         memcpy(P->command, abuf, num);
631         P->command[num] = '\0';
632         abuf = bbuf + 2;
633
634         // scan data
635
636         sscanf(abuf,
637                 "%c "
638                 "%d %d %d %d %d "
639                 "%lu %lu %lu %lu %lu "
640                 "%Lu %Lu %Lu %Lu "  // utime stime cutime cstime
641                 "%ld %ld "
642                 "%d "
643                 "%ld "
644                 "%Lu "  // start_time
645                 "%lu "
646                 "%ld",
647                 &P->state,
648                 &P->ppid, &P->pgrp, &P->sid, &P->tty_nr, &P->tty_pgrp,
649                 &P->flags, &P->minor_fault, &P->cminor_fault, &P->major_fault, &P->cmajor_fault,
650                 &P->utime, &P->stime, &P->cutime, &P->cstime,
651                 &P->priority, &P->nice,
652                 &P->numofthread,
653                 &P->dummy,
654                 &P->start_time,
655                 &P->vir_mem,
656                 &P->res_memblock
657                 );
658
659         if(P->numofthread == 0)
660                 P->numofthread = 1;
661
662         return 0;
663 }
664
665 // return 0 for normal case
666 // return negative value for error case
667 static int parse_proc_smaps_file_bypid(char *path, proc_t* P)
668 {
669 #define MIN_SMAP_BLOCKLINE      50
670
671         char filename[PROCPATH_MAX];
672         char buf[MIDDLE_BUFFER];
673         char numbuf[SMALL_BUFFER];
674         FILE* fp;
675
676         // reset pss size of proc_t
677         P->pss = 0;
678         P->sh_mem = 0;
679
680         // read from smaps file
681         sprintf(filename, "%s/smaps", path);
682         fp = fopen(filename, "r");
683
684         if(fp == NULL){
685                 return -1;
686         }
687
688         if(unlikely(probe_so_size == 0))        // probe so size is not abtained
689         {
690                 int is_probe_so = 0;
691                 while(fgets(buf, MIDDLE_BUFFER, fp) != NULL)
692                 {
693                         if(strncmp(buf, "Pss:", 4) == 0)        // line is started with "Pss:"
694                         {
695                                 sscanf(buf, "Pss:%s kB", numbuf);
696                                 P->pss += atoi(numbuf);
697                                 if(is_probe_so == 1)
698                                 {
699                                         probe_so_size += atoi(numbuf);
700                                         is_probe_so = 0;        // reset search flag
701                                 }
702                         }
703                         else if(strncmp(buf, "Shared", 6) == 0) // line is started with "Shared"
704                         {
705                                 char *p = buf;
706                                 p = strstr(buf, ":");
707                                 if (p != 0) {
708                                         sscanf(p, ":%s kB", numbuf);
709                                         P->sh_mem += atoi(numbuf);
710                                 }
711
712                         }
713                         else    // not Pss line
714                         {
715                                 if (is_probe_so == 0 && strlen(buf) > MIN_SMAP_BLOCKLINE)
716                                 {
717                                         // first we find probe so section
718                                         if(strstr(buf, DA_PROBE_TIZEN_SONAME) != NULL ||
719                                                         strstr(buf, DA_PROBE_OSP_SONAME) != NULL)
720                                         {
721                                                 // found probe.so
722                                                 is_probe_so = 1;
723                                         }
724                                         else
725                                         {
726                                                 // do nothing
727                                         }
728                                 }
729                                 else
730                                 {
731                                         // do nothing
732                                 }
733                         }
734                 }
735         }
736         else    // we know about probe.so size already
737         {
738                 while(fgets(buf, MIDDLE_BUFFER, fp) != NULL)
739                 {
740                         if(strncmp(buf, "Pss:", 4) == 0)
741                         {
742                                 sscanf(buf, "Pss:%s kB", numbuf);
743                                 P->pss += atoi(numbuf);
744                         }
745                         else if(strncmp(buf, "Shared", 6) == 0) // line is started with "Shared"
746                         {
747                                 char *p = buf;
748                                 p = strstr(buf, ":");
749                                 if (p != 0) {
750                                         sscanf(p, ":%s kB", numbuf);
751                                         P->sh_mem += atoi(numbuf);
752                                 }
753                         }
754                 }
755         }
756
757         P->pss -= probe_so_size;
758
759         fclose(fp);
760
761         return 0;
762 }
763
764 // return 0 for normal case
765 // return positive value for non critical case
766 // return negative value for critical case
767 static int update_process_data(int* pidarray, int pidcount, enum PROCESS_DATA datatype)
768 {
769         static struct stat sb;
770         int i, ret = 0;
771         char buf[PROCPATH_MAX];
772         procNode* procnode;
773
774         for(i = 0; i < pidcount; i++)
775         {
776 /*              LOGI("#%d\n", i); */
777                 if (pidarray[i] == 0)   // pid is invalid
778                 {
779                         ret = 1;
780                         continue;
781                 }
782
783                 sprintf(buf, "/proc/%d", pidarray[i]);
784 /*              LOGI("#->%s\n", buf); */
785                 if (unlikely(stat(buf, &sb) == -1))     // cannot access anymore
786                 {
787 /*                      LOGI("#del from prochead=%d\n", prochead); */
788                         del_node(&prochead, pidarray[i]);
789                         ret = errno;
790                         continue;
791                 }
792
793 /*              LOGI("find node = %d\n", procnode); */
794                 if ((procnode = find_node(prochead, pidarray[i])) == NULL)      // new process
795                 {
796 /*                      LOGI("proc node1 = %d\n", procnode); */
797                         procnode = add_node(&prochead, pidarray[i]);
798                         if(datatype == PROCDATA_STAT)
799                         {
800                                 if (unlikely((ret = parse_proc_stat_file_bypid(buf, &(procnode->proc_data))) < 0))
801                                 {
802                                         LOGE("Failed to get proc stat file by pid(%d)\n", pidarray[i]);
803                                 }
804                                 else
805                                 {
806                                         procnode->saved_utime = procnode->proc_data.utime;
807                                         procnode->saved_stime = procnode->proc_data.stime;
808                                 }
809                         }
810                         else if(datatype == PROCDATA_SMAPS)
811                         {
812                                 if (unlikely((ret = parse_proc_smaps_file_bypid(buf, &(procnode->proc_data))) < 0))
813                                 {
814                                         LOGE("Failed to get proc smaps file by pid(%d)\n", pidarray[i]);
815                                 }
816                                 else
817                                 {       // do nothing
818                                 }
819                         }
820                         else
821                         {       // impossible
822                         }
823                 }
824                 else
825                 {
826 /*                      LOGI("proc node2 = %d\n", procnode); */
827                         if(datatype == PROCDATA_STAT)
828                         {
829                                 if (unlikely((ret = parse_proc_stat_file_bypid(buf, &(procnode->proc_data))) < 0))
830                                 {
831                                         LOGE("Failed to get proc stat file by pid(%d)\n", pidarray[i]);
832                                 }
833                                 else
834                                 {       // do nothing
835                                 }
836                         }
837                         else if(datatype == PROCDATA_SMAPS)
838                         {
839                                 if (unlikely((ret = parse_proc_smaps_file_bypid(buf, &(procnode->proc_data))) < 0))
840                                 {
841                                         LOGE("Failed to get proc smaps file by pid(%d)\n", pidarray[i]);
842                                 }
843                                 else
844                                 {       // do nothing
845                                 }
846                         }
847                         else
848                         {       // impossible
849                         }
850                 }
851         }
852 /*      LOGI("del_notfound_node\n"); */
853         del_notfound_node(&prochead);
854 /*      LOGI("reset_found_node\n"); */
855         reset_found_node(prochead);
856
857 /*      LOGI("ret %d\n", ret); */
858         return ret;
859 }
860
861 static int update_system_cpu_frequency(int cur_index)
862 {
863         char buf[SMALL_BUFFER];
864         char filename[SMALL_BUFFER];
865         int i, j;
866         FILE* fp;
867
868         // execute this block only once
869         if(unlikely(num_of_freq <= 0))
870         {
871                 FILE* fp;
872                 num_of_freq = 0;
873                 if((fp = fopen(CPUNUM_OF_FREQ, "r")) != NULL)
874                 {
875                         while(fgets(buf, SMALL_BUFFER, fp) != NULL)
876                         {
877                                 num_of_freq++;
878                         }
879                         fclose(fp);
880                 }
881                 else
882                 {
883                         /* This file may absent in the system */
884                 }
885
886                 for(i = 0; i < num_of_cpu; i++)
887                 {
888                         if(cpus[i].pfreq == NULL && num_of_freq)
889                         {
890                                 cpus[i].pfreq = (cpufreq_t*) calloc(num_of_freq, sizeof(cpufreq_t));
891                         }
892                 }
893         }
894
895         sprintf(filename, CPUNUM_OF_FREQ);
896         // update cpu frequency information
897         for(i = 0; i < num_of_cpu; i++)
898         {
899                 filename[27] = (char)('0' + i);
900                 fp = fopen(filename, "r");
901                 if(fp != NULL)
902                 {
903                         for(j = 0; j < num_of_freq; j++)
904                         {
905                                 if(fgets(buf, SMALL_BUFFER, fp) != NULL)
906                                 {
907                                         sscanf(buf, "%lu %Lu", &(cpus[i].pfreq[j].freq),
908                                                         &(cpus[i].pfreq[j].tick));
909                                 }
910                                 else    // cannot read anymore from frequency info file
911                                         break;
912                         }
913
914                         fclose(fp);
915                         cpus[i].cur_freq_index = cur_index;
916                 }
917                 else    // cannot load cpu frequency information
918                 {       // do nothing
919                 }
920         }
921
922         return 0;
923 }
924
925 // return 0 for normal case
926 // return negative value for error
927 static void init_system_cpu_data()
928 {
929         manager.fd.procstat = fopen(PROCSTAT, "r");
930 }
931
932 static int update_system_cpu_data(int cur_index)
933 {
934 /*      LOGI(">\n"); */
935
936         FILE* fp = manager.fd.procstat;
937         int num;
938         char buf[BUFFER_MAX];
939
940         if(fp == NULL)
941                 return -1;
942
943         rewind(fp);
944         fflush(fp);
945
946         if(fgets(buf, sizeof(buf), fp) == NULL)
947         {
948                 LOGE("Failed to read first line of " PROCSTAT "\n");
949                 return -1;
950         }
951
952 /* LOGI("scan; cpus = %d\n", cpus); */
953
954         cpus[num_of_cpu].x = 0;
955         cpus[num_of_cpu].y = 0;
956         cpus[num_of_cpu].z = 0;
957         num = sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",
958                         &cpus[num_of_cpu].u,
959                         &cpus[num_of_cpu].n,
960                         &cpus[num_of_cpu].s,
961                         &cpus[num_of_cpu].i,
962                         &cpus[num_of_cpu].w,
963                         &cpus[num_of_cpu].x,
964                         &cpus[num_of_cpu].y,
965                         &cpus[num_of_cpu].z
966                         );
967         cpus[num_of_cpu].cur_load_index = cur_index;
968         if(num < 4)
969         {
970                 LOGE("Failed to read from " PROCSTAT "\n");
971                 return -1;
972         }
973
974 #ifdef FOR_EACH_CPU
975
976 /*      LOGI("cpu num = %d\n", num_of_cpu); */
977         // and just in case we're 2.2.xx compiled without SMP support...
978         if(num_of_cpu == 1)
979         {
980                 cpus[0].id = cpus[1].id = 0;
981                 memcpy(cpus, &cpus[1], sizeof(tic_t) * 8);
982                 cpus[0].cur_load_index = cur_index;
983         }
984         else if(num_of_cpu > 1)
985         {
986                 int i;
987                 // now value each separate cpu's tics
988                 for(i = 0; i < num_of_cpu; i++)
989                 {
990                         if(fgets(buf, sizeof(buf), fp) != NULL)
991                         {
992                                 cpus[i].x = 0;
993                                 cpus[i].y = 0;
994                                 cpus[i].z = 0;
995                                 num = sscanf(buf, "cpu%u %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",
996                                                 &cpus[i].id,
997                                                 &cpus[i].u, &cpus[i].n, &cpus[i].s, &cpus[i].i,
998                                                 &cpus[i].w, &cpus[i].x, &cpus[i].y, &cpus[i].z);
999                                 if(num > 4)
1000                                 {
1001                                         LOGI_th_samp("Readed %d stats of %dth cpu\n", num, i);
1002                                         cpus[i].cur_load_index = cur_index;
1003                                 }
1004                                 else    // buf is not cpu core tick information
1005                                 {       // do nothing
1006                                 }
1007                         }
1008                         else    // cannot read anymore from /proc/stat file
1009                         {       // do nothing
1010                         }
1011                 }
1012         }
1013         else
1014         {
1015                 // not possible
1016                 return -1;
1017         }
1018 #endif
1019         return 0;
1020 }
1021
1022 // return 0 for normal case
1023 // return negative value for error
1024 static void init_update_system_memory_data()
1025 {
1026         manager.fd.procmeminfo = open(PROCMEMINFO, O_RDONLY);
1027 }
1028
1029 static int update_system_memory_data(uint64_t *memtotal, uint64_t *memused)
1030 {
1031         int meminfo_fd = manager.fd.procmeminfo;
1032         char *head, *tail;
1033         int i, num;
1034         char buf[BUFFER_MAX];
1035         static const mem_t mem_table[] = {
1036                 {"Buffers",             (unsigned long *)&mem_slot_array[MEM_SLOT_BUFFER]},
1037                 {"Cached",              (unsigned long *)&mem_slot_array[MEM_SLOT_CACHED]},
1038                 {"MemFree",             (unsigned long *)&mem_slot_array[MEM_SLOT_FREE]},
1039                 {"MemTotal",    (unsigned long *)&mem_slot_array[MEM_SLOT_TOTAL]},
1040         };
1041         const int mem_table_size = sizeof(mem_table) / sizeof(mem_t);
1042
1043         if (meminfo_fd == -1)
1044                 return -1;
1045
1046         lseek(meminfo_fd, 0L, SEEK_SET);
1047         if((num = read(meminfo_fd, buf, BUFFER_MAX)) < 0)
1048         {
1049                 LOGE("Failed to read from " PROCMEMINFO "\n");
1050                 return -1;
1051         }
1052
1053         if(num == BUFFER_MAX)
1054                 num -= 1;
1055
1056         buf[num] = '\0';
1057 //      LOGI("buffer=<%s>\n", buf);
1058
1059         num = 0;        // number of found element
1060         head = buf;
1061         for( ;num < mem_table_size ; )
1062         {
1063                 tail = strchr(head, ':');
1064                 if(!tail)
1065                         break;
1066                 *tail = '\0';
1067                 for(i = 0; i < mem_table_size; i++)
1068                 {
1069                         if(strcmp(head, mem_table[i].name) == 0)        // found
1070                         {
1071                                 head = tail + 1;
1072                                 *(mem_table[i].slot) = strtoul(head, &tail, 10);
1073                                 num++;
1074                                 break;
1075                         }
1076                 }
1077                 if(i == mem_table_size) // cannot find entry
1078                 {
1079                         head = tail + 1;
1080                 }
1081                 tail = strchr(head, '\n');
1082                 if(tail == NULL)
1083                         break;
1084                 head = tail + 1;
1085         }
1086 /*              LOGI("Buffers = %016LX\n", mem_slot_array[MEM_SLOT_BUFFER]); */
1087 /*              LOGI("Cached  = %016LX\n", mem_slot_array[MEM_SLOT_CACHED]); */
1088 /*              LOGI("MemFree = %016LX\n", mem_slot_array[MEM_SLOT_FREE]); */
1089 /*              LOGI("MemTotal= %016LX\n", mem_slot_array[MEM_SLOT_TOTAL]); */
1090         if(num == mem_table_size)       // find all element
1091         {
1092                 *memtotal = mem_slot_array[MEM_SLOT_TOTAL];
1093                 *memused = mem_slot_array[MEM_SLOT_TOTAL] - mem_slot_array[MEM_SLOT_FREE] -
1094                         mem_slot_array[MEM_SLOT_BUFFER] - mem_slot_array[MEM_SLOT_CACHED];
1095
1096
1097                 *memtotal *= 1024;      // change to Byte
1098                 *memused *= 1024;       // change to Byte
1099                 return 0;
1100         }
1101         else
1102         {
1103                 LOGE("Cannot find all neccessary element in meminfo\n");
1104                 return -1;
1105         }
1106 }
1107
1108
1109 // return 0 for error case
1110 // return system total memory in MB
1111 //static
1112 unsigned long get_system_total_memory()
1113 {
1114         int meminfo_fd = manager.fd.procmeminfo;
1115         char *head, *tail;
1116         int num;
1117         char buf[BUFFER_MAX];
1118         static const char* memtotalstr = "MemTotal";
1119         unsigned long totalmem = 0;
1120
1121         if (meminfo_fd == -1)
1122                 return 0;
1123
1124         lseek(meminfo_fd, 0L, SEEK_SET);
1125
1126         if((num = read(meminfo_fd, buf, BUFFER_MAX)) < 0)
1127         {
1128                 LOGE("Failed to read from " PROCMEMINFO "\n");
1129                 return 0;
1130         }
1131
1132         if(num == BUFFER_MAX)
1133                 num -= 1;
1134         buf[num] = '\0';
1135
1136         head = buf;
1137         for( ; ; )
1138         {
1139                 tail = strchr(head, ':');
1140                 if(!tail)
1141                         break;
1142                 *tail = '\0';
1143                 if(strcmp(head, memtotalstr) == 0)      // found
1144                 {
1145                         head = tail + 1;
1146                         totalmem = strtoul(head, &tail, 10);
1147                         break;
1148                 }
1149
1150                 head = tail + 1;
1151                 tail = strchr(head, '\n');
1152                 if(tail == NULL)
1153                         break;
1154                 head = tail + 1;
1155         }
1156
1157         return (totalmem * 1024);
1158 }
1159
1160 // ===============================================================
1161 // disk information getter functions
1162 // ===============================================================
1163 static int get_fsinfo(const char* path, int type)
1164 {
1165         struct statfs buf;
1166         int total;
1167         int free;
1168
1169         if (statfs(path, &buf) < 0)
1170         {
1171                 return -errno;
1172         }
1173
1174         total = (int)((long long)(buf.f_bsize / 1024LL * buf.f_blocks) / 1024LL);
1175         free = (int)((long long)(buf.f_bsize / 1024LL * buf.f_bavail) / 1024LL);
1176
1177 /*      LOGI("File storage total(%d), free(%d)\n", total, free); */
1178         if (type == FSINFO_TYPE_TOTAL)
1179         {
1180                 return total;
1181         }
1182         else if (type == FSINFO_TYPE_FREE)
1183         {
1184                 return free;
1185         }
1186
1187         return -1;
1188 }
1189
1190 static int stat_get_storageinfo(int type)
1191 {
1192         return get_fsinfo(UMSFD, type);
1193 }
1194
1195 static int stat_get_cardinfo(int type)
1196 {
1197         if (access(MMCBLKFD, F_OK) < 0)
1198         {
1199                 return -1;
1200         }
1201
1202         return get_fsinfo(MMCFD, type);
1203 }
1204
1205
1206 static int get_total_drive()
1207 {
1208         int total = 0;
1209         int storage = stat_get_storageinfo(FSINFO_TYPE_TOTAL);
1210         int card = stat_get_cardinfo(FSINFO_TYPE_TOTAL);
1211
1212         if (storage < 0 && card < 0)
1213         {
1214                 return -1;
1215         }
1216
1217         total = storage + card;
1218
1219         return total;
1220 }
1221
1222 static int get_total_used_drive()
1223 {
1224         int total = 0;
1225         int free = 0;
1226         int storage = stat_get_storageinfo(FSINFO_TYPE_FREE);
1227         int card = stat_get_cardinfo(FSINFO_TYPE_FREE);
1228
1229         if (storage < 0 && card < 0)
1230         {
1231                 LOGI_th_samp("total_used_drive = -1\n");
1232                 return -1;
1233         }
1234
1235         free = storage + card;
1236         total = get_total_drive() - free;
1237
1238         LOGI_th_samp("total_used_drive = %d\n", total);
1239
1240         return total;
1241 }
1242
1243 static int update_thread_data(int pid)
1244 {
1245         static struct stat sb;
1246         int ret = 0;
1247         char path[PROCPATH_MAX];
1248         char buf[PROCPATH_MAX];
1249         procNode* procnode;
1250         DIR *taskdir = NULL;
1251         struct dirent *entry = NULL;
1252         unsigned int tid;
1253
1254         sprintf(path, "/proc/%d/task", pid);
1255
1256         if(!(taskdir = opendir(path)))
1257         {
1258                 LOGE("task not found '%s'\n", path);
1259                 return -1;
1260         }
1261
1262         while((entry = readdir(taskdir)) != NULL)
1263         {
1264                 if(*entry->d_name > '0' &&      *entry->d_name <= '9')
1265                 {
1266                         tid = atoi(entry->d_name);
1267                         sprintf(buf, "/proc/%d/task/%d", pid, tid);
1268
1269                         if(unlikely(stat(buf, &sb) == -1))
1270                         {
1271                                 del_node(&thread_prochead, tid);
1272                                 ret = errno;
1273                                 continue;
1274                         }
1275
1276                         if((procnode = find_node(thread_prochead, tid)) == NULL)
1277                         {
1278                                 procnode = add_node(&thread_prochead, tid);
1279                                 if (unlikely((ret = parse_proc_stat_file_bypid(buf, &(procnode->proc_data))) < 0))
1280                                 {
1281                                         LOGE("Failed to get proc stat file by tid(%d). add node\n", tid);
1282                                 }
1283                                 else
1284                                 {
1285                                         procnode->saved_utime = procnode->proc_data.utime;
1286                                         procnode->saved_stime = procnode->proc_data.stime;
1287 /*                                      LOGI("data updated\n"); */
1288                                 }
1289                         }
1290                         else
1291                         {
1292                                 if (unlikely((ret = parse_proc_stat_file_bypid(buf, &(procnode->proc_data))) < 0))
1293                                 {
1294                                         LOGE("Failed to get proc stat file by tid(%d). node exist\n", tid);
1295                                 }
1296                         }
1297                 }
1298         }
1299
1300         del_notfound_node(&thread_prochead);
1301         reset_found_node(thread_prochead);
1302
1303         closedir(taskdir);
1304         return ret;
1305 }
1306
1307 // ========================================================================
1308 // overall information getter functions
1309 // ========================================================================
1310
1311 // this code is not necessary anymore
1312 /*
1313 static void get_app_info(const char* binary_path, char* width,
1314                 char* height, char* theme, char* version,
1315                 char* scale, char* removable,
1316                 char* comment)
1317 {
1318         int fd = 0;
1319         int res = 0;
1320         int i = 0;
1321         int j = 0;
1322         char pkg_info_path [PATH_MAX];
1323         char buffer [BUFFER_MAX];
1324
1325         sprintf(pkg_info_path, "/opt/share/applications/%s.desktop", pkg_name);
1326
1327     fd = open(pkg_info_path, O_RDONLY);
1328     if (fd < 0)
1329         {
1330                 LOGE("Cannot open %s", pkg_info_path);
1331                 return;
1332         }
1333
1334         fcntl( fd, F_SETFD, FD_CLOEXEC );
1335
1336         LOGI("get_app_info - After open pkg_info_path\n");
1337
1338         for (;;)
1339         {
1340                 res = read(fd, buffer, BUFFER_MAX);
1341                 if (res == 0)
1342                 {
1343                         break;
1344                 }
1345                 if (res < 0)
1346                 {
1347                         if (errno == EINTR)
1348                                 continue;
1349                         else
1350                                 break;
1351                 }
1352
1353                 LOGI("read buffer ===%s===\n", buffer);
1354                 for (i = 0; i < res; i++)
1355                 {
1356                         if (i < res - 22 && strncmp(&buffer[i], "X-SLP-BaseLayoutWidth=", 22) == 0)
1357                         {
1358                                 for (j = 0; j < res; j ++)
1359                                 {
1360                                         if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1361                                         {
1362                                                 LOGI("width :::: ");
1363                                                 strncpy(width, &(buffer[i+22]), j-22);
1364                                                 LOGI("%s\n", width);
1365                                                 break;
1366                                         }
1367                                 }
1368                                 i = i + j;
1369                         }
1370                         else if (i < res - 23 && strncmp(&buffer[i], "X-SLP-BaseLayoutHeight=", 23) == 0)
1371                         {
1372                                 for (j = 0; j < res; j ++)
1373                                 {
1374                                         if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1375                                         {
1376                                                 LOGI("height :::: ");
1377                                                 strncpy(height, &(buffer[i+23]), j-23);
1378                                                 LOGI("%s\n", height);
1379                                                 break;
1380                                         }
1381                                 }
1382                                 i = i + j;
1383                         }
1384                         else if (i < res - 6 && (strncmp(&buffer[i], "theme=", 6) == 0 || strncmp(&buffer[i], "Theme=", 6) == 0))
1385                         {
1386                                 for (j = 0; j < res; j ++)
1387                                 {
1388                                         if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1389                                         {
1390                                                 LOGI("theme :::: ");
1391                                                 strncpy(theme, &(buffer[i+6]), j-6);
1392                                                 LOGI("%s\n", theme);
1393                                                 break;
1394                                         }
1395                                 }
1396                                 i = i + j;
1397                         }
1398                         else if (i < res - 8 && (strncmp(&buffer[i], "Version=", 8) == 0 || strncmp(&buffer[i], "version=", 8) == 0))
1399                         {
1400                                 for (j = 0; j < res; j ++)
1401                                 {
1402                                         if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1403                                         {
1404                                                 LOGI("version :::: ");
1405                                                 strncpy(version, &(buffer[i+8]), j-8);
1406                                                 LOGI("%s\n", version);
1407                                                 break;
1408                                         }
1409                                 }
1410                                 i = i + j;
1411                         }
1412                         else if (i < res - 24 && strncmp(&buffer[i], "X-SLP-IsHorizontalScale=", 24) == 0)
1413                         {
1414                                 for (j = 0; j < res; j ++)
1415                                 {
1416                                         if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1417                                         {
1418                                                 LOGI("scale :::: ");
1419                                                 strncpy(scale, &(buffer[i+24]), j-24);
1420                                                 LOGI("%s\n", scale);
1421                                                 break;
1422                                         }
1423                                 }
1424                                 i = i + j;
1425                         }
1426                         else if (i < res - 16 && strncmp(&buffer[i], "X-SLP-Removable=", 16) == 0)
1427                         {
1428                                 for (j = 0; j < res; j ++)
1429                                 {
1430                                         if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1431                                         {
1432                                                 LOGI("removable :::: ");
1433                                                 strncpy(removable, &(buffer[i+16]), j-16);
1434                                                 LOGI("%s\n", removable);
1435                                                 break;
1436                                         }
1437                                 }
1438                                 i = i + j;
1439                         }
1440                         else if (i < res - 8 && (strncmp(&buffer[i], "Comment=", 8) == 0 || strncmp(&buffer[i], "comment=", 8) == 0))
1441                         {
1442                                 for (j = 0; j < res; j ++)
1443                                 {
1444                                         if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1445                                         {
1446                                                 LOGI("comments :::: ");
1447                                                 strncpy(comment, &(buffer[i+8]), j-8);
1448                                                 LOGI("%s\n", comment);
1449                                                 break;
1450                                         }
1451                                 }
1452                                 i = i + j;
1453                         }
1454                 }
1455         }
1456
1457         close(fd);
1458 }
1459 */
1460 int get_camera_count()
1461 {
1462         FILE* fp;
1463         int count = 0;
1464         int size;
1465         char buf[BUFFER_MAX];
1466
1467         fp = fopen(CAMCORDER_FILE, "r");
1468         if(fp != NULL)
1469         {
1470                 size = strlen(CAMERA_COUNT_STR);
1471
1472                 while(fgets(buf, BUFFER_MAX, fp) != NULL)
1473                 {
1474                         if(strncmp(buf, CAMERA_COUNT_STR, size) == 0) {
1475                                 sscanf(buf, CAMERA_COUNT_STR " = %d", &count);
1476                                 break;
1477                         }
1478                 }
1479
1480                 fclose(fp);
1481         } else {
1482                 //can not open file
1483         }
1484
1485         return count;
1486 }
1487
1488 static int get_device_network_type(char* buf, int buflen)
1489 {
1490         int len = 0;
1491         bool bool_var;
1492
1493         system_info_get_platform_bool("tizen.org/feature/network.telephony.service.cdma", &bool_var);
1494         if(bool_var) len += sprintf(buf + len, "CDMA,");
1495         system_info_get_platform_bool("tizen.org/feature/network.telephony.service.edge", &bool_var);
1496         if(bool_var) len += sprintf(buf + len, "EDGE,");
1497         system_info_get_platform_bool("tizen.org/feature/network.telephony.service.gprs", &bool_var);
1498         if(bool_var) len += sprintf(buf + len, "GPRS,");
1499         system_info_get_platform_bool("tizen.org/feature/network.telephony.service.gsm", &bool_var);
1500         if(bool_var) len += sprintf(buf + len, "GSM,");
1501         system_info_get_platform_bool("tizen.org/feature/network.telephony.service.hsdpa", &bool_var);
1502         if(bool_var) len += sprintf(buf + len, "HSDPA,");
1503         system_info_get_platform_bool("tizen.org/feature/network.telephony.service.hspa", &bool_var);
1504         if(bool_var) len += sprintf(buf + len, "HSPA,");
1505         system_info_get_platform_bool("tizen.org/feature/network.telephony.service.hsupa", &bool_var);
1506         if(bool_var) len += sprintf(buf + len, "HSUPA,");
1507         system_info_get_platform_bool("tizen.org/feature/network.telephony.service.umts", &bool_var);
1508         if(bool_var) len += sprintf(buf + len, "UMTS,");
1509         system_info_get_platform_bool("tizen.org/feature/network.telephony.service.lte", &bool_var);
1510         if(bool_var) len += sprintf(buf + len, "LTE,");
1511
1512         if (len != 0) {
1513                 buf[--len] = 0;
1514         }
1515         return len;
1516 }
1517
1518
1519 static int get_device_availability_info(char* buf, int buflen)
1520 {
1521         int camera_count = 0;
1522         bool blue_support = false;
1523         bool gps_support = false;
1524         bool wifi_support = false;
1525         char* networktype = NULL;
1526         int loglen = 0;
1527         char network_type[128];
1528         int network_len;
1529
1530         system_info_get_platform_bool("tizen.org/feature/network.bluetooth", &blue_support);
1531         camera_count = get_camera_count();
1532         system_info_get_platform_bool("tizen.org/feature/location.gps", &gps_support);
1533         network_len = get_device_network_type(networktype, 128);
1534         system_info_get_platform_bool("tizen.org/feature/network.wifi", &wifi_support);
1535
1536         loglen += sprintf(buf, "%d`,%d`,%d`,%d`,",
1537                         (int)blue_support,
1538                         (int)gps_support,
1539                         (int)wifi_support,
1540                         camera_count);
1541
1542         if(network_type != NULL && network_len > 0) {
1543                 loglen += sprintf(buf + loglen, "%s", networktype);
1544                 free(networktype);
1545         }
1546
1547         return loglen;
1548 }
1549
1550 int get_device_info(char* buffer, int buffer_len)
1551 {
1552         int res = 0;
1553 /*
1554         char width[BUFFER_MAX];
1555         char height[BUFFER_MAX];
1556         char theme[BUFFER_MAX];
1557         char version[BUFFER_MAX];
1558         char scale[BUFFER_MAX];
1559         char removable[BUFFER_MAX];
1560         char comment[BUFFER_MAX * 2];
1561
1562         memset(width, 0, sizeof(width));
1563         memset(height, 0, sizeof(height));
1564         memset(theme, 0, sizeof(theme));
1565         memset(version, 0, sizeof(version));
1566         memset(scale, 0, sizeof(scale));
1567         memset(removable, 0, sizeof(removable));
1568         memset(comment, 0, sizeof(comment));
1569 */
1570         res += sprintf(buffer, "%lu`,%d`,", get_system_total_memory(), get_total_drive());
1571         res += get_device_availability_info(buffer + res, buffer_len - res);
1572         res += sprintf(buffer + res, "`,%d", get_max_brightness());
1573
1574         res += sprintf(buffer + res, "`,`,`,`,`,`,`,");
1575 //      res += sprintf(buffer + res, "`,%s`,%s`,%s`,%s`,%s`,%s`,%s", width, height, theme, version, scale, removable, comment);
1576
1577         return res;
1578 }
1579
1580 int update_cpus_info(int event_num, float elapsed)
1581 {
1582         int i = 0;
1583         CPU_t* cpuptr;
1584         // calculate for system cpu load
1585 #ifdef FOR_EACH_CPU
1586         for(i = 0; i < num_of_cpu; i++)
1587 #else
1588         for(i = num_of_cpu; i <= num_of_cpu; i++)
1589 #endif
1590         {
1591         LOGI_th_samp("CPU #%d\n", i);
1592                 cpuptr = &(cpus[i]);
1593
1594                 if(cpuptr->cur_load_index == event_num)
1595                 {
1596                         if(cpuptr->sav_load_index == event_num - 1)             // previous sampling is just before 1 period
1597                         {
1598                                 cpuptr->idle_ticks = cpuptr->i - cpuptr->i_sav;
1599                                 if(unlikely(cpuptr->idle_ticks < 0))
1600                                 {
1601                                         cpuptr->idle_ticks = 0;
1602                                 }
1603                                 cpuptr->total_ticks = (cpuptr->u - cpuptr->u_sav) +
1604                                         (cpuptr->s - cpuptr->s_sav) +
1605                                         (cpuptr->n - cpuptr->n_sav) +
1606                                         cpuptr->idle_ticks +
1607                                         (cpuptr->w - cpuptr->w_sav) +
1608                                         (cpuptr->x - cpuptr->x_sav) +
1609                                         (cpuptr->y - cpuptr->y_sav) +
1610                                         (cpuptr->z - cpuptr->z_sav);
1611                                 if(cpuptr->total_ticks < MIN_TOTAL_TICK)
1612                                 {
1613                                         cpuptr->cpu_usage = 0.0f;
1614                                 }
1615                                 else
1616                                 {
1617                                         cpuptr->cpu_usage = (1.0f - ((float)cpuptr->idle_ticks /
1618                                                                 (float)cpuptr->total_ticks)) * 100.0f;
1619                                 }
1620 //                              if(i != num_of_cpu)
1621 //                              {
1622 //                                      idle_tick_sum += cpuptr->idle_ticks;
1623 //                                      total_tick_sum += cpuptr->total_ticks;
1624 //                              }
1625                                 LOGI_th_samp("System cpu usage log : %d, %Ld, %Ld\n",
1626                                                 i, cpuptr->idle_ticks, cpuptr->total_ticks);
1627                                 if(unlikely(cpuptr->cpu_usage < 0))
1628                                 {
1629                                         cpuptr->cpu_usage = 0.0f;
1630                                 }
1631                         }
1632                         else    // previous sampling is not just before 1 period
1633                         {
1634                                 // assume non idle ticks happen in 1 profiling period
1635                                 // because sampling is not available just before 1 profiling period
1636                                 cpuptr->idle_ticks = (cpuptr->u - cpuptr->u_sav) +
1637                                         (cpuptr->s - cpuptr->s_sav) +
1638                                         (cpuptr->n - cpuptr->n_sav) +
1639                                         (cpuptr->w - cpuptr->w_sav) +
1640                                         (cpuptr->x - cpuptr->x_sav) +
1641                                         (cpuptr->y - cpuptr->y_sav) +
1642                                         (cpuptr->z - cpuptr->z_sav);
1643                                 cpuptr->total_ticks = (long long)(Hertz * elapsed);
1644                                 if(unlikely(cpuptr->total_ticks < 1))
1645                                         cpuptr->total_ticks = 1;
1646                                 cpuptr->cpu_usage = ((float)cpuptr->idle_ticks /
1647                                                 (float)cpuptr->total_ticks) * 100.0f;
1648                                 if(unlikely(cpuptr->cpu_usage > 100.0f))
1649                                 {
1650                                         cpuptr->cpu_usage = 100.0f;
1651                                 }
1652                         }
1653
1654                         // save new value
1655                         cpuptr->u_sav = cpuptr->u;
1656                         cpuptr->s_sav = cpuptr->s;
1657                         cpuptr->n_sav = cpuptr->n;
1658                         cpuptr->i_sav = cpuptr->i;
1659                         cpuptr->w_sav = cpuptr->w;
1660                         cpuptr->x_sav = cpuptr->x;
1661                         cpuptr->y_sav = cpuptr->y;
1662                         cpuptr->z_sav = cpuptr->z;
1663                         cpuptr->sav_load_index = cpuptr->cur_load_index;
1664                 }
1665                 else
1666                 {
1667                         cpuptr->cpu_usage = 0.0f;
1668                 }
1669         }
1670
1671         // calculate for cpu core load that failed to get tick information
1672 /*
1673         if(failed_cpu != 0)
1674         {
1675                 LOGI("ticks1 : %Ld, %Ld\n", idle_tick_sum, total_tick_sum);
1676                 idle_tick_sum = cpus[num_of_cpu].idle_ticks - idle_tick_sum;
1677                 total_tick_sum = cpus[num_of_cpu].total_ticks - total_tick_sum;
1678                 LOGI("ticks2 : %Ld, %Ld\n", idle_tick_sum, total_tick_sum);
1679                 if(total_tick_sum >= MIN_TICKS_FOR_LOAD)
1680                         sys_usage = (1.0f - ((float)idle_tick_sum / (float)total_tick_sum)) * 100.0f;
1681                 else
1682                         sys_usage = 0.0f;
1683                 if(sys_usage < 0.0f) sys_usage = 0.0f;
1684                 else if(sys_usage > 100.0f) sys_usage = 100.0f;
1685
1686                 for(i = 0; i < num_of_cpu; i++)
1687                 {
1688                         if(failed_cpu & (1 << i))
1689                         {
1690                                 cpus[i].cpu_usage = sys_usage;
1691                         }
1692                 }
1693         }
1694 */
1695         return 0;
1696 }
1697
1698 int fill_system_processes_info(float factor, struct system_info_t * sys_info)
1699 {
1700         procNode* proc;
1701         int i = 0;
1702         float thread_load;
1703         // data variable
1704         unsigned long virtual = 0;
1705         unsigned long resident = 0;
1706         unsigned long shared = 0;
1707         unsigned long pssmem = 0;
1708         uint64_t ticks = 0;
1709         float app_cpu_usage = 0.0;
1710
1711         LOGI_th_samp("prochead = %X\n", (unsigned int)prochead);
1712         for(proc = prochead; proc != NULL; proc = proc->next)
1713         {
1714                 //increment process count
1715                 sys_info->count_of_processes++; //maybe wrong
1716         }
1717         sys_info->process_load = malloc (
1718                                                                                 sys_info->count_of_processes *
1719                                                                                 sizeof(*sys_info->process_load)
1720                                                                         );
1721         i = 0;
1722         for(proc = prochead; proc != NULL; proc = proc->next)
1723         {
1724                 LOGI_th_samp("proc#%d (%d %d),(%d %d) (%d) %f\n",
1725                                 i,
1726                                 (unsigned int)proc->proc_data.utime, (unsigned int)proc->proc_data.stime ,
1727                                 (unsigned int)proc->saved_utime, (unsigned int)proc->saved_stime,
1728                                 (int)(proc->proc_data.utime + proc->proc_data.stime - proc->saved_utime - proc->saved_stime),
1729                                 (float)(
1730                                         proc->saved_utime + proc->saved_stime -
1731                                         proc->proc_data.utime - proc->proc_data.stime
1732                                         ) * factor);
1733                 thread_load = (float)(proc->proc_data.utime + proc->proc_data.stime -
1734                                                                 proc->saved_utime - proc->saved_stime) * factor;
1735
1736                 if(thread_load > 100.0f)
1737                         thread_load = 100.0f;
1738
1739                 //num_thread += proc->proc_data.numofthread;
1740                 virtual += proc->proc_data.vir_mem;                                     // Byte
1741                 resident += (proc->proc_data.res_memblock * 4);         // KByte
1742                 pssmem += (proc->proc_data.pss);                                        // KByte
1743                 shared += (proc->proc_data.sh_mem);                                     // KByte
1744                 ticks += (proc->proc_data.utime + proc->proc_data.stime -
1745                                         proc->saved_utime - proc->saved_stime);
1746
1747                 proc->saved_utime = proc->proc_data.utime;
1748                 proc->saved_stime = proc->proc_data.stime;
1749
1750
1751                 sys_info->process_load[i].id = proc->proc_data.pid;
1752                 sys_info->process_load[i].load = thread_load;
1753                 i++;
1754
1755         }
1756
1757         app_cpu_usage = (float)ticks * factor;
1758         if(app_cpu_usage > 100.0f)
1759                 app_cpu_usage = 100.0f;
1760         resident = resident * 1024;             // change to Byte
1761         pssmem = pssmem * 1024;                 // change to Byte
1762         shared = shared * 1024;                 // change to Byte
1763
1764         sys_info->virtual_memory = virtual;
1765         sys_info->resident_memory = resident;
1766         sys_info->shared_memory = shared;
1767         sys_info->pss_memory = pssmem;
1768
1769         sys_info->app_cpu_usage = app_cpu_usage;
1770
1771         return 0;
1772
1773 }
1774
1775 // fill threads information
1776 int fill_system_threads_info(float factor, struct system_info_t * sys_info)
1777 {
1778         procNode* proc;
1779         float thread_load;
1780
1781         for(proc = thread_prochead; proc != NULL; proc = proc->next)
1782                 //increment thread count
1783                 sys_info->count_of_threads++; //maybe wrong
1784
1785 /*      LOGI_th_samp("thread load\n"); */
1786         struct thread_info_t *pthread;
1787         if (sys_info->count_of_threads != 0)
1788         {
1789                 sys_info->thread_load = malloc( sys_info->count_of_threads * sizeof(*sys_info->thread_load) );
1790                 pthread = sys_info->thread_load;
1791         }
1792
1793         for(proc = thread_prochead; proc != NULL; proc = proc->next)
1794         {
1795                 thread_load = (float)(proc->proc_data.utime + proc->proc_data.stime -
1796                                                                 proc->saved_utime - proc->saved_stime)
1797                         * factor;
1798                 if(thread_load > 100.0f)
1799                         thread_load = 100.0f;
1800
1801                 pthread->pid = proc->proc_data.pid;
1802                 pthread->load = thread_load;
1803                 pthread++;
1804
1805 //              sprintf(thread_loadtmpbuf, "%d,%.1f,", proc->proc_data.pid, thread_load);
1806 //              strcat(thread_loadbuf, thread_loadtmpbuf);
1807
1808                 proc->saved_utime = proc->proc_data.utime;
1809                 proc->saved_stime = proc->proc_data.stime;
1810         }
1811
1812         return 0;
1813 }
1814
1815 //fill system cpu information
1816 int fill_system_cpu_info(struct system_info_t *sys_info)
1817 {
1818         float sys_usage = 0.0f;
1819         int i = 0;
1820
1821         // calculate for whole cpu load by average all core load
1822         LOGI_th_samp("calculate for whole cpu load num_of_cpu=%d\n", num_of_cpu);
1823         for(i = 0 ; i < num_of_cpu; i++)
1824                 sys_usage += cpus[i].cpu_usage;
1825
1826         // fill cpu load
1827         float *pcpu_usage;
1828         if (num_of_cpu != 0)
1829         {
1830                 sys_info->cpu_load = malloc( num_of_cpu * sizeof(*sys_info->cpu_load) );
1831                 pcpu_usage = sys_info->cpu_load;
1832                 for(i = 0; i < num_of_cpu; i++)
1833                 {
1834                         LOGI_th_samp("cpu#%d : %.1f\n" , i,  cpus[i].cpu_usage);
1835                         *pcpu_usage = cpus[i].cpu_usage;
1836                         pcpu_usage++;
1837                 }
1838         }
1839
1840         //fill CPU frequency
1841         sys_info->cpu_frequency = malloc(num_of_cpu * sizeof(float));
1842         if (!sys_info->cpu_frequency) {
1843                 LOGE("Cannot alloc cpu freq\n");
1844                 return 1;
1845         }
1846         get_cpu_frequency(sys_info->cpu_frequency);
1847
1848         return 0;
1849 }
1850
1851
1852 //fill cpu frequency based on cpu tick count in different cpu frequence states
1853 int fill_cpu_frequecy(int event_num)
1854 {
1855         // calculate for system cpu frequency
1856         float sys_usage = 0.0f;
1857         uint64_t ticks = 0, freqsum = 0;
1858         int i, j;
1859         CPU_t* cpuptr;
1860
1861         for(i = 0; i < num_of_cpu; i++)
1862         {
1863                 cpuptr = &(cpus[i]);
1864
1865                 if(cpuptr->cur_freq_index == event_num)
1866                 {
1867                         if(cpuptr->sav_freq_index == event_num - 1)
1868                         {
1869                                 for(j = 0; j < num_of_freq; j++)
1870                                 {
1871                                         freqsum += (cpuptr->pfreq[j].freq *
1872                                                         (cpuptr->pfreq[j].tick - cpuptr->pfreq[j].tick_sav));
1873                                         ticks += (cpuptr->pfreq[j].tick - cpuptr->pfreq[j].tick_sav);
1874                                 }
1875                         }
1876                         else
1877                         {       // do nothing
1878                         }
1879
1880                         for(j = 0; j < num_of_freq; j++)
1881                         {
1882                                 cpuptr->pfreq[j].tick_sav = cpuptr->pfreq[j].tick;              // restore last tick value
1883                         }
1884                         cpuptr->sav_freq_index = cpuptr->cur_freq_index;
1885                 }
1886
1887 #ifdef FOR_EACH_CPU
1888                 if(ticks != 0)
1889                 {
1890                         if(sys_usage == 0.0f)
1891                                 sys_usage = (float)freqsum / (float)ticks;
1892                         // TODO use sys_usage as cpu #i core freq
1893                 }
1894                 else
1895                 {
1896                         //freqbufpos += sprintf(freqbuf + freqbufpos, "%.0f,", sys_usage);
1897                         // TODO ?
1898                 }
1899                 ticks = 0;
1900                 freqsum = 0;
1901 #endif
1902         }
1903         return -0;
1904 }
1905
1906 static void skip_lines(FILE * fp, unsigned int count)
1907 {
1908         char *buffer = NULL;
1909         size_t buflen;
1910         unsigned int index;
1911         for (index = 0; index != count; ++index)
1912                 getline(&buffer, &buflen, fp);
1913         free(buffer);
1914 }
1915
1916 static void skip_tokens(FILE * fp, unsigned int count)
1917 {
1918         unsigned int index;
1919
1920         for (index = 0; index != count; ++index)
1921                 fscanf(fp, "%*s");
1922 }
1923
1924 static void init_network_stat()
1925 {
1926         manager.fd.networkstat = fopen("/proc/net/dev", "r");
1927 }
1928
1929 static void get_network_stat(uint32_t *recv, uint32_t *send)
1930 {
1931         FILE *fp = manager.fd.networkstat;
1932         uintmax_t irecv, isend;
1933         char ifname[64];
1934         if (fp == NULL)
1935                 return;
1936
1937         rewind(fp);
1938         fflush(fp);
1939
1940         *recv = *send = 0;
1941         skip_lines(fp, 2);      /* strip header */
1942
1943         while (fscanf(fp, "%s", ifname) != EOF)
1944                 if (strcmp("lo:", ifname)) {
1945                         fscanf(fp, "%" SCNuMAX, &irecv);
1946                         skip_tokens(fp, 7);
1947
1948                         fscanf(fp, "%" SCNuMAX, &isend);
1949                         skip_tokens(fp, 7);
1950
1951                         *recv += irecv;
1952                         *send += isend;
1953                 } else
1954                         skip_tokens(fp, 16);
1955 }
1956
1957 static void peek_network_stat_diff(uint32_t *recv, uint32_t *send)
1958 {
1959         static uint32_t irecv_old, isend_old;
1960         uint32_t tmp;
1961
1962         get_network_stat(recv, send);
1963
1964         tmp = *recv;
1965         *recv = tmp - irecv_old;
1966         irecv_old = tmp;
1967
1968         tmp = *send;
1969         *send = tmp - isend_old;
1970         isend_old = tmp;
1971
1972 }
1973
1974 static void init_disk_stat(void)
1975 {
1976         manager.fd.diskstats = fopen("/proc/diskstats", "r");
1977 }
1978
1979 //function return partition sector size
1980 // returns
1981 //  0 if error
1982 //  <size> if no errors
1983 static int get_partition_sector_size(const char * partition_name)
1984 {
1985         int sec_size = 0;
1986         FILE *sfp = 0;
1987         char sec_size_buff[LARGE_BUFFER];
1988
1989         sprintf(sec_size_buff, "/sys/block/%s/queue/hw_sector_size", partition_name);
1990         sfp = fopen(sec_size_buff, "r");
1991         if (sfp == 0) {
1992                 LOGE("cannot detect sector size for <%s> (%s)\n",
1993                                 partition_name, sec_size_buff);
1994                 return 0;
1995         }
1996         fscanf(sfp, "%d", &sec_size);
1997         fclose(sfp);
1998         if (sec_size <= 0){
1999                 LOGE("cannot detect sector size for <%s> (%s)\n",
2000                                 partition_name, sec_size_buff);
2001                 return 0;
2002         }
2003
2004         return sec_size;
2005 }
2006
2007 static void get_disk_stat(uint32_t *reads, uint32_t *sec_reads,
2008                           uint32_t *writes, uint32_t *sec_writes)
2009 {
2010         enum { partition_name_maxlength = 128 };
2011         FILE *fp = manager.fd.diskstats;
2012         char master_partition[partition_name_maxlength] = { 0 };
2013
2014         *reads = *writes = 0;
2015         *sec_reads = *sec_writes = 0;
2016
2017         if (fp == NULL)
2018                 return;
2019
2020
2021         rewind(fp);
2022         fflush(fp);
2023
2024         while (!feof(fp)) {
2025                 char partition[partition_name_maxlength];
2026                 uintmax_t preads, pwrites;
2027                 uintmax_t psec_read, psec_write;
2028                 skip_tokens(fp, 2);
2029                 fscanf(fp, "%s", partition);
2030                 if (*master_partition
2031                     && !strncmp(master_partition, partition,
2032                                strlen(master_partition))) {
2033                         /* subpartition */
2034                         skip_tokens(fp, 11);
2035                 } else {
2036                         // FIXME it is not good way call this func
2037                         // each time to get partition sector size
2038                         /*sec_size = get_partition_sector_size(partition);
2039                         if (sec_size <= 0){
2040                                 *read = 0;
2041                                 *write = 0;
2042                                 LOGE("get RW error\n");
2043                                 fclose(fp);
2044                                 return;
2045                         }*/
2046
2047                         //1
2048                         fscanf(fp, "%" SCNuMAX, &preads);
2049                         skip_tokens(fp, 1);
2050                         //3
2051                         fscanf(fp, "%" SCNuMAX, &psec_read);
2052                         skip_tokens(fp, 1);
2053                         //5
2054                         fscanf(fp, "%" SCNuMAX, &pwrites);
2055                         skip_tokens(fp, 1);
2056                         //7
2057                         fscanf(fp, "%" SCNuMAX, &psec_write);
2058                         skip_tokens(fp, 4);
2059
2060                         memcpy(master_partition, partition,
2061                                partition_name_maxlength);
2062                         // FIXME rw size is in sectors
2063                         // actualy different disks - different partition sector size (?)
2064                         // maybe need convert to bytes like this:
2065                         //*read += pread * sec_size;
2066                         //*write += pwrite * sec_size;
2067
2068                         *reads += (uint32_t)preads;
2069                         *writes += (uint32_t)pwrites;
2070
2071                         *sec_reads += (uint32_t)psec_read;
2072                         *sec_writes += (uint32_t)psec_write;
2073                 }
2074         }
2075
2076 }
2077
2078 static void peek_disk_stat_diff(uint32_t *reads, uint32_t *sec_reads,
2079                                 uint32_t *writes, uint32_t *sec_writes)
2080 {
2081         static uint32_t reads_old;
2082         static uint32_t sec_reads_old;
2083         static uint32_t writes_old;
2084         static uint32_t sec_writes_old;
2085
2086         uint32_t tmp;
2087
2088         //get cur values
2089         get_disk_stat(reads, sec_reads, writes, sec_writes);
2090
2091         tmp = *reads;
2092         *reads = tmp - reads_old;
2093         reads_old = tmp;
2094
2095         tmp = *writes;
2096         *writes = tmp - writes_old;
2097         writes_old = tmp;
2098
2099         tmp = *sec_reads;
2100         *sec_reads = tmp - sec_reads_old;
2101         sec_reads_old = tmp;
2102
2103         tmp = *sec_writes;
2104         *sec_writes = tmp - sec_writes_old;
2105         sec_writes_old = tmp;
2106
2107 }
2108
2109 static float get_elapsed(void)
2110 {
2111         static struct timeval old_time = {0, 0};
2112         struct timeval current_time;
2113         float elapsed;
2114
2115         gettimeofday(&current_time, NULL);
2116         elapsed = (current_time.tv_sec - old_time.tv_sec) +
2117                 ((float)(current_time.tv_usec - old_time.tv_usec) / 1000000.0f);
2118         old_time.tv_sec = current_time.tv_sec;
2119         old_time.tv_usec = current_time.tv_usec;
2120
2121         return elapsed;
2122 }
2123
2124 static float get_factor(float elapsed)
2125 {
2126         return 100.0f / ((float)Hertz * elapsed * num_of_cpu);
2127 }
2128
2129 static uint64_t read_int64_from_file(const char *fname)
2130 {
2131         FILE *fp = fopen(fname, "r");
2132         uint64_t value;
2133         if (!fp)
2134                 return 0;
2135         if (fscanf(fp, "%lld", &value) != 1)
2136                 value = 0;
2137         fclose(fp);
2138         return value;
2139 }
2140
2141 #define swap_sysfs_relpath(x) ("/sys/kernel/debug/swap/energy/" #x)
2142 #define swap_read_int64(x) (read_int64_from_file(swap_sysfs_relpath(x)))
2143 static uint64_t get_system_lcd_energy()
2144 {
2145         static const char *PROC_LCD_ENERGY_FILES_GLOBPATTERN =
2146                 "/sys/kernel/debug/swap/energy/lcd/*/system";
2147         uint64_t sum_energy = 0;
2148         glob_t glob_buf;
2149         size_t i;
2150         const int err = glob(PROC_LCD_ENERGY_FILES_GLOBPATTERN, 0,
2151                              NULL, &glob_buf);
2152
2153         if (err) {
2154                 LOG_ONCE_E("Globbing for LCD failed with error %d\n", err);
2155                 return 0;
2156         }
2157
2158         for (i = 0; i < glob_buf.gl_pathc; ++i)
2159                 sum_energy += read_int64_from_file(glob_buf.gl_pathv[i]);
2160
2161         globfree(&glob_buf);
2162         return sum_energy;
2163 }
2164 /*
2165  * Calculates difference between current and previous sample (system).
2166  * Stores mutable state in static variables.
2167  */
2168 static uint32_t pop_sys_energy_per_device(enum supported_device dev)
2169 {
2170         static uint64_t cpu_old, flash_old, lcd_old;
2171         uint64_t cpu_new, flash_new, lcd_new;
2172         uint64_t cpu_diff, flash_diff, lcd_diff;
2173
2174         switch (dev) {
2175         case DEVICE_CPU:
2176                 cpu_new = swap_read_int64(cpu_idle/system) +
2177                         swap_read_int64(cpu_running/system);
2178                 cpu_diff = cpu_new - cpu_old;
2179                 cpu_old = cpu_new;
2180                 return (uint32_t)cpu_diff;
2181
2182         case DEVICE_FLASH:
2183                 flash_new = swap_read_int64(flash_read/system) +
2184                         swap_read_int64(flash_write/system);
2185                 flash_diff = flash_new - flash_old;
2186                 flash_old = flash_new;
2187                 return (uint32_t)flash_diff;
2188         case DEVICE_LCD:
2189                 lcd_new = get_system_lcd_energy();
2190                 lcd_diff = lcd_new - lcd_old;
2191                 lcd_old = lcd_new;
2192                 return (uint32_t)lcd_diff;
2193         default:
2194                 assert(0 && "Unknown device. This should not happen");
2195                 return -41;
2196         }
2197 }
2198
2199 // Calculates difference between current and previous sample (app).
2200 // Stores mutable state in static variables.
2201 static uint32_t pop_app_energy_per_device(enum supported_device dev)
2202 {
2203         static uint64_t cpu_old, flash_old;
2204         uint64_t cpu_new, flash_new;
2205         uint64_t cpu_diff, flash_diff;
2206
2207         switch (dev) {
2208         case DEVICE_CPU:
2209                 cpu_new = swap_read_int64(cpu_running/apps);
2210                 cpu_diff = cpu_new - cpu_old;
2211                 cpu_old = cpu_new;
2212                 return (uint32_t)cpu_diff;
2213         case DEVICE_FLASH:
2214                 flash_new = swap_read_int64(flash_read/apps) +
2215                         swap_read_int64(flash_write/apps);
2216                 flash_diff = flash_new - flash_old;
2217                 flash_old = flash_new;
2218                 return (uint32_t)flash_diff;
2219         case DEVICE_LCD:
2220                 /**
2221                  * Per-application energy accounting
2222                  * is not supported for LCD.
2223                  */
2224                 return 0;
2225         default:
2226                 assert(0 && "Unknown device. This should not happen");
2227                 return -41;
2228         }
2229 }
2230
2231 // return log length (>0) for normal case
2232 // return negative value for error
2233 int get_system_info(struct system_info_t *sys_info, int* pidarray, int pidcount)
2234 {
2235         static int event_num = 0;
2236         uint64_t sysmemtotal = 0;
2237         uint64_t sysmemused = 0;
2238         int res = 0;
2239         float elapsed;
2240         float factor;
2241
2242         LOGI_th_samp("start\n");
2243         LOGI_th_samp("PID count : %d\n", pidcount);
2244
2245         memset(sys_info, 0, sizeof(*sys_info));
2246
2247         // common (cpu, processes, memory)
2248         if (IS_OPT_SET(FL_CPU) ||
2249             IS_OPT_SET(FL_PROCESSES) ||
2250             IS_OPT_SET(FL_MEMORY)) {
2251                 if (update_process_data(pidarray, pidcount, PROCDATA_STAT) < 0) {
2252                         LOGE("Failed to update process stat data\n");
2253                         goto fail_exit;
2254                 }
2255                 /**
2256                  * This position is optimized position of timestamp. Just
2257                  * before get system cpu data and just after get process cpu
2258                  * data because cpu data is changed so fast and variance is so
2259                  * remarkable
2260                  */
2261                 elapsed = get_elapsed(); /* DO NOT MOVE THIS SENTENCE! */
2262                 factor = get_factor(elapsed);
2263
2264                 if (update_system_cpu_data(event_num) < 0) {
2265                         LOGE("Failed to update system cpu data\n");
2266                         goto fail_exit;
2267                 }
2268
2269                 if (update_system_cpu_frequency(event_num) < 0) {
2270                         LOGE("Failed to update system cpu freq data\n");
2271                         goto fail_exit;
2272                 }
2273
2274                 /**
2275                  * Memory data is changed slowly and variance is not
2276                  * remarkable, so memory data is less related with timestamp
2277                  * then cpu data
2278                  */
2279                 if (update_process_data(pidarray, pidcount, PROCDATA_SMAPS) < 0) {
2280                         LOGE("Failed to update process smaps data\n");
2281                         goto fail_exit;
2282                 }
2283
2284                 if (pidcount > 0)
2285                         if (update_thread_data(pidarray[0]) < 0) {
2286                                 LOGE("Failed to update thread stat data\n");
2287                                 goto fail_exit;
2288                         }
2289
2290                 if (update_system_memory_data(&sysmemtotal, &sysmemused) < 0) {
2291                         LOGE("Failed to update system memory data\n");
2292                         goto fail_exit;
2293                 }
2294
2295                 if (update_cpus_info(event_num, elapsed) < 0) {
2296                         LOGE("Failed to update cpus info\n");
2297                         goto fail_exit;
2298                 }
2299
2300                 /* calculate process load, memory, app_cpu_usage */
2301                 if (fill_system_processes_info(factor, sys_info) < 0) {
2302                         LOGE("Failed to fill processes info\n");
2303                         goto fail_exit;
2304                 }
2305
2306                 /* calculate thread load */
2307                 if (fill_system_threads_info(factor, sys_info) < 0) {
2308                         LOGE("Failed to fill threads info\n");
2309                         goto fail_exit;
2310                 }
2311
2312                 if (fill_system_cpu_info(sys_info) < 0) {
2313                         LOGE("Failed to fill threads info\n");
2314                         goto fail_exit;
2315                 }
2316         }
2317
2318         if (IS_OPT_SET(FL_MEMORY)) {
2319                 sys_info->total_alloc_size = get_total_alloc_size();
2320                 sys_info->system_memory_total = sysmemtotal;
2321                 sys_info->system_memory_used = sysmemused;
2322         }
2323
2324         LOGI_th_samp("Fill result structure\n");
2325
2326         if (IS_OPT_SET(FL_DISK)) {
2327                 sys_info->total_used_drive = get_total_used_drive();
2328                 peek_disk_stat_diff(&sys_info->disk_reads,
2329                                     &sys_info->disk_sectors_read,
2330                                     &sys_info->disk_writes,
2331                                     &sys_info->disk_sectors_write);
2332         }
2333
2334         if (IS_OPT_SET(FL_NETWORK))
2335                 peek_network_stat_diff(&sys_info->network_send_size,
2336                                        &sys_info->network_receive_size);
2337
2338         if (IS_OPT_SET(FL_DEVICE)) {
2339                 sys_info->wifi_status = get_wifi_status();
2340                 sys_info->bt_status = get_bt_status();
2341                 sys_info->gps_status = get_gps_status();
2342                 sys_info->brightness_status = get_brightness_status();
2343                 sys_info->camera_status = get_camera_status();
2344                 sys_info->sound_status = get_sound_status();
2345                 sys_info->audio_status = get_audio_status();
2346                 sys_info->vibration_status = get_vibration_status();
2347                 sys_info->voltage_status = get_voltage_status();
2348                 sys_info->rssi_status = get_rssi_status();
2349                 sys_info->video_status = get_video_status();
2350                 sys_info->call_status = get_call_status();
2351                 sys_info->dnet_status = get_dnet_status();
2352         }
2353
2354         if (IS_OPT_SET(FL_ENERGY)) {
2355                 int i;
2356                 sys_info->energy = 0; /* not implemented */
2357                 for (i = 0; i != supported_devices_count; ++i) {
2358                         sys_info->energy_per_device[i] =
2359                                 pop_sys_energy_per_device(i);
2360                         sys_info->app_energy_per_device[i] =
2361                                 pop_app_energy_per_device(i);
2362                 }
2363         }
2364
2365 #ifdef THREAD_SAMPLING_DEBUG
2366         print_sys_info(sys_info);
2367 #endif
2368
2369         event_num++;
2370         LOGI_th_samp("exit\n");
2371         return res;
2372
2373 fail_exit:
2374         /* Some data corrupted. Free allocated data. */
2375         reset_system_info(sys_info);
2376         LOGI_th_samp("fail exit\n");
2377         return -1;
2378 }
2379
2380 int initialize_system_info()
2381 {
2382         int i;
2383
2384         num_of_cpu = sysconf(_SC_NPROCESSORS_CONF);
2385         if(num_of_cpu < 1)
2386                 num_of_cpu = 1;
2387         Hertz = sysconf(_SC_CLK_TCK);
2388         LOGI("Hertz : %d\n", Hertz);
2389
2390         // alloc for cpus
2391         if(cpus == NULL)
2392                 cpus = (CPU_t*) calloc((num_of_cpu + 1), sizeof(CPU_t));
2393         if(cpus != NULL)
2394         {
2395                 for(i = 0; i <= num_of_cpu; i++)
2396                 {
2397                         cpus[i].cur_load_index = cpus[i].sav_load_index = -1;
2398                         cpus[i].cur_freq_index = cpus[i].sav_freq_index = -1;
2399                 }
2400         }
2401         else
2402         {
2403                 LOGE("Failed to alloc memory for cpu information\n");
2404                 return -1;
2405         }
2406
2407         return 0;
2408 }
2409
2410 int finalize_system_info()
2411 {
2412         int i;
2413
2414         if(cpus != NULL)
2415         {
2416                 for(i = 0; i < num_of_cpu; i++)
2417                 {
2418                         if(cpus[i].pfreq != NULL)
2419                                 free(cpus[i].pfreq);
2420                 }
2421
2422                 free(cpus);
2423         }
2424
2425         return 0;
2426
2427 }
2428
2429 static void test_and_close(int *fd)
2430 {
2431         if (*fd > 0)
2432                 close(*fd);
2433         *fd = -1;
2434 }
2435
2436 static void ftest_and_close(FILE **fd)
2437 {
2438         if (*fd != NULL)
2439                 fclose(*fd);
2440         *fd = NULL;
2441 }
2442
2443 #define strr(x) #x
2444 #define str(x) strr(x)
2445 #define dtest_and_close(fd) do {LOGI("CLOSE " str(fd) "\n");test_and_close(fd);} while(0)
2446 #define dftest_and_close(fd) do {LOGI("CLOSE " str(fd) "\n");ftest_and_close(fd);} while(0)
2447 void close_system_file_descriptors()
2448 {
2449         dtest_and_close(&manager.fd.brightness);
2450         dtest_and_close(&manager.fd.voltage);
2451         dtest_and_close(&manager.fd.procmeminfo);
2452
2453         dftest_and_close(&manager.fd.video);
2454         dftest_and_close(&manager.fd.procstat);
2455         dftest_and_close(&manager.fd.networkstat);
2456         dftest_and_close(&manager.fd.diskstats);
2457 }
2458
2459 int init_system_file_descriptors()
2460 {
2461         //inits
2462         init_brightness_status();
2463         init_voltage_status();
2464         init_update_system_memory_data();
2465
2466         init_video_status();
2467         init_system_cpu_data();
2468         init_network_stat();
2469         init_disk_stat();
2470
2471         if (manager.fd.brightness < 0)
2472                 LOGW("brightness file not found\n");
2473         if (manager.fd.voltage < 0)
2474                 LOGW("voltage file not found\n");
2475         if (manager.fd.procmeminfo < 0)
2476                 LOGW("procmeminfo file not found\n");
2477
2478         if (manager.fd.video == NULL)
2479                 LOGW("video file not found\n");
2480         if (manager.fd.procstat == NULL)
2481                 LOGW("procstat file not found\n");
2482         if (manager.fd.networkstat == NULL)
2483                 LOGW("networkstat file not found\n");
2484         if (manager.fd.diskstats == NULL)
2485                 LOGW("diskstat file not found\n");
2486         return 0;
2487 }
2488
2489 //CMD SOCKET FUNCTIONS
2490 int fill_target_info(struct target_info_t *target_info)
2491 {
2492         /* system_info_get_value_bool() changes only 1 byte
2493            so we need to be sure that the integer as a whole is correct */
2494         target_info->bluetooth_supp = 0;
2495         target_info->gps_supp = 0;
2496         target_info->wifi_supp = 0;
2497         target_info->camera_count = 0;
2498         target_info->network_type[0] = 0;
2499
2500         target_info->sys_mem_size = get_system_total_memory();
2501         target_info->storage_size = stat_get_storageinfo(FSINFO_TYPE_TOTAL) *
2502                 1024 * 1024;
2503
2504         system_info_get_platform_bool("tizen.org/feature/network.bluetooth",
2505                                                                         (_Bool *)&target_info->bluetooth_supp);
2506
2507
2508         system_info_get_platform_bool("tizen.org/feature/location.gps",
2509                                    (_Bool *)&target_info->gps_supp);
2510
2511         system_info_get_platform_bool("tizen.org/feature/network.wifi",
2512                                    (_Bool *)&target_info->wifi_supp);
2513
2514         target_info->camera_count = get_camera_count();
2515
2516         get_device_network_type(target_info->network_type, NWTYPE_SIZE);
2517
2518
2519         target_info->max_brightness = get_max_brightness();
2520         target_info->cpu_core_count = sysconf(_SC_NPROCESSORS_CONF);
2521         return 0;
2522 }
2523
2524 int sys_stat_prepare(void)
2525 {
2526         uint32_t reads, writes, sec_reads, sec_writes;
2527         uint32_t recv, send;
2528
2529         peek_disk_stat_diff(&reads, &writes, &sec_reads, &sec_writes);
2530         peek_network_stat_diff(&recv, &send);
2531
2532         return 0;
2533 }
2534
2535 static uint32_t msg_data_payload_length(const struct system_info_t *sys_info)
2536 {
2537         uint32_t len = sizeof(*sys_info);
2538
2539         /* num_of_cpu is unknown at compile time */
2540         len += 2 * num_of_cpu * sizeof(float);
2541
2542         /* subtract pointers */
2543         len -= sizeof(sys_info->cpu_frequency) + sizeof(sys_info->cpu_load);
2544         len -= sizeof(sys_info->thread_load) + sizeof(sys_info->process_load);
2545
2546         if (IS_OPT_SET(FL_CPU))
2547                 len += sys_info->count_of_threads *
2548                         sizeof(*sys_info->thread_load);
2549
2550         if (IS_OPT_SET(FL_PROCESSES))
2551                 len += sys_info->count_of_processes *
2552                         sizeof(*sys_info->process_load);
2553
2554         return len;
2555 }
2556
2557 struct msg_data_t *pack_system_info(struct system_info_t *sys_info)
2558 {
2559         const int len = msg_data_payload_length(sys_info);
2560         struct msg_data_t *msg = NULL;
2561         char *p = NULL;
2562         int i = 0;
2563
2564         msg = malloc(MSG_DATA_HDR_LEN + len);
2565         if (!msg) {
2566                 LOGE("Cannot alloc message: %d bytes\n", len);
2567                 return NULL;
2568         }
2569
2570         fill_data_msg_head(msg, NMSG_SYSTEM, 0, len);
2571         p = msg->payload;
2572
2573         // CPU
2574         if (IS_OPT_SET(FL_CPU)) {
2575                 pack_float(p, sys_info->app_cpu_usage);
2576
2577                 for (i = 0; i < num_of_cpu; i++) {
2578                         if (sys_info->cpu_frequency)
2579                                 pack_float(p, sys_info->cpu_frequency[i]);
2580                         else
2581                                 pack_float(p, 0.0);
2582                 }
2583
2584                 for (i = 0; i < num_of_cpu; i++) {
2585                         if (sys_info->cpu_load)
2586                                 pack_float(p, sys_info->cpu_load[i]);
2587                         else
2588                                 pack_float(p, 0.0);
2589                 }
2590                 // thread
2591                 pack_int32(p, sys_info->count_of_threads);
2592                 for (i = 0; i < sys_info->count_of_threads; i++) {
2593                         if (sys_info->thread_load) {
2594                                 pack_int32(p, sys_info->thread_load[i].pid);
2595                                 pack_float(p, sys_info->thread_load[i].load);
2596                         } else {
2597                                 pack_int32(p, 0);
2598                                 pack_float(p, 0.0);
2599                         }
2600                 }
2601         } else {
2602                 pack_float(p, 0.0); /* pack app_cpu_usage */
2603
2604                 for (i = 0; i < num_of_cpu; i++) {
2605                         pack_float(p, 0.0); /* pack cpu_frequency */
2606                         pack_float(p, 0.0); /* pack cpu_load */
2607                 }
2608                 /* thread */
2609                 pack_int32(p, 0); /* pack count_of_threads */
2610         }
2611
2612         /* process */
2613         if (IS_OPT_SET(FL_PROCESSES)) {
2614                 pack_int32(p, sys_info->count_of_processes);
2615                 for (i = 0; i < sys_info->count_of_processes; i++) {
2616                         if (sys_info->process_load) {
2617                                 pack_int32(p, sys_info->process_load[i].id);
2618                                 pack_float(p, sys_info->process_load[i].load);
2619                         } else {
2620                                 pack_int32(p, 0);
2621                                 pack_float(p, 0.0);
2622                         }
2623                 }
2624         } else {
2625                 pack_int32(p, 0); /* pack count_of_processes */
2626         }
2627
2628         /* memory */
2629         if (IS_OPT_SET(FL_MEMORY)) {
2630                 pack_int32(p, sys_info->virtual_memory);
2631                 pack_int32(p, sys_info->resident_memory);
2632                 pack_int32(p, sys_info->shared_memory);
2633                 pack_int32(p, sys_info->pss_memory);
2634                 pack_int32(p, sys_info->total_alloc_size);
2635                 pack_int64(p, sys_info->system_memory_total);
2636                 pack_int64(p, sys_info->system_memory_used);
2637         } else {
2638                 pack_int32(p, 0); /* pack virtual_memory */
2639                 pack_int32(p, 0); /* pack resident_memory */
2640                 pack_int32(p, 0); /* pack shared_memory */
2641                 pack_int32(p, 0); /* pack pss_memory */
2642                 pack_int32(p, 0); /* pack total_alloc_size */
2643                 pack_int64(p, (uint64_t) 0); /* pack system_memory_total */
2644                 pack_int64(p, (uint64_t) 0); /* pack system_memory_used */
2645         }
2646
2647         pack_int32(p, sys_info->total_used_drive);
2648         pack_int32(p, sys_info->disk_reads);
2649         pack_int32(p, sys_info->disk_sectors_read);
2650         pack_int32(p, sys_info->disk_writes);
2651         pack_int32(p, sys_info->disk_sectors_write);
2652
2653         pack_int32(p, sys_info->network_send_size);
2654         pack_int32(p, sys_info->network_receive_size);
2655
2656         pack_int32(p, sys_info->wifi_status);
2657         pack_int32(p, sys_info->bt_status);
2658         pack_int32(p, sys_info->gps_status);
2659         pack_int32(p, sys_info->brightness_status);
2660         pack_int32(p, sys_info->camera_status);
2661         pack_int32(p, sys_info->sound_status);
2662         pack_int32(p, sys_info->audio_status);
2663         pack_int32(p, sys_info->vibration_status);
2664         pack_int32(p, sys_info->voltage_status);
2665         pack_int32(p, sys_info->rssi_status);
2666         pack_int32(p, sys_info->video_status);
2667         pack_int32(p, sys_info->call_status);
2668         pack_int32(p, sys_info->dnet_status);
2669
2670         pack_int32(p, sys_info->energy);
2671         for (i = 0; i != supported_devices_count; ++i)
2672                 pack_int32(p, sys_info->energy_per_device[i]);
2673         for (i = 0; i != supported_devices_count; ++i)
2674                 pack_int32(p, sys_info->app_energy_per_device[i]);
2675
2676         return msg;
2677 }