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