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