2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #ifndef __STC_MANAGER_UTIL_H__
18 #define __STC_MANAGER_UTIL_H__
24 #include <stdbool.h> /* bool */
25 #include <stdint.h> /* uint32_t, uint63_t */
27 #include <sqlite3.h> /* database handling */
28 #include <time.h> /* time function */
29 #include <vconf/vconf.h>
36 #define LOG_TAG "STC_MANAGER"
38 #define STC_LOGD(format, args...) LOGD(format, ##args)
39 #define STC_LOGI(format, args...) LOGI(format, ##args)
40 #define STC_LOGW(format, args...) LOGW(format, ##args)
41 #define STC_LOGE(format, args...) LOGE(format, ##args)
43 #define __STC_LOG_FUNC_ENTER__ LOGD("Enter")
44 #define __STC_LOG_FUNC_EXIT__ LOGD("Quit")
48 #define STC_LOGD(format, args...)
49 #define STC_LOGI(format, args...)
50 #define STC_LOGW(format, args...)
51 #define STC_LOGE(format, args...)
53 #define __STC_LOG_FUNC_ENTER__
54 #define __STC_LOG_FUNC_EXIT__
58 #define LOG_RED "\033[0;31m"
59 #define LOG_GREEN "\033[0;32m"
60 #define LOG_BROWN "\033[0;33m"
61 #define LOG_BLUE "\033[0;34m"
62 #define LOG_MAGENTA "\033[0;35m"
63 #define LOG_CYAN "\033[0;36m"
64 #define LOG_YELLOW "\033[1;33m"
65 #define LOG_LIGHTRED "\033[1;31m"
66 #define LOG_LIGHTGREEN "\033[1;32m"
67 #define LOG_LIGHTBLUE "\033[1;34m"
68 #define LOG_LIGHTMAGENTA "\033[1;35m"
69 #define LOG_LIGHTCYAN "\033[1;36m"
70 #define LOG_END "\033[0;m"
72 #define APP_ID_LEN_MAX 1024
74 #define GPOINTER_TO_PID(x) (pid_t)GPOINTER_TO_INT((x))
75 #define PID_TO_GPOINTER(x) GINT_TO_POINTER((pid_t)(x))
77 #define MALLOC0(t, n) ((t*) g_try_malloc0((n) * sizeof(t)))
78 #define FREE(p) do { \
85 #define EXEC(error_code, command) do { \
86 if (error_code != command) { \
87 __STC_LOG_FUNC_EXIT__; \
92 #define DEBUG_GDBUS_VARIANT(str, parameters) do { \
93 gchar *params_str = NULL; \
95 params_str = g_variant_print(parameters, \
98 STC_LOGD("%s[%s]", str, \
99 params_str ? params_str : "NULL"); \
100 g_free(params_str); \
103 #define DEBUG_GDBUS_KEY_VALUE(key, value) do { \
105 STC_LOGD("Key : [%s]", key); \
108 DEBUG_GDBUS_VARIANT("Value: ", value); \
112 #define _pure_ __attribute__ ((pure))
113 #define _cleanup_(x) __attribute__((cleanup(x)))
115 static inline void freep(void *p)
120 static inline void closep(int *fd)
126 static inline void fclosep(FILE **f)
132 static inline void pclosep(FILE **f)
138 static inline void closedirp(DIR **d)
144 #define _cleanup_free_ _cleanup_(freep)
145 #define _cleanup_close_ _cleanup_(closep)
146 #define _cleanup_fclose_ _cleanup_(fclosep)
147 #define _cleanup_pclose_ _cleanup_(pclosep)
148 #define _cleanup_closedir_ _cleanup_(closedirp)
150 #define NUM_DIFF(x, y) ((x > y) ? (x - y) : (y -x))
152 #define BYTE_TO_KBYTE(b) ((b) >> 10)
153 #define BYTE_TO_MBYTE(b) ((b) >> 20)
154 #define BYTE_TO_GBYTE(b) ((b) >> 30)
155 #define BYTE_TO_PAGE(b) ((b) >> 12)
157 #define KBYTE_TO_BYTE(k) ((k) << 10)
158 #define KBYTE_TO_MBYTE(k) ((k) >> 10)
159 #define KBYTE_TO_GBYTE(k) ((k) >> 20)
161 #define MBYTE_TO_BYTE(m) ((m) << 20)
162 #define MBYTE_TO_KBYTE(m) ((m) << 10)
163 #define MBYTE_TO_GBYTE(m) ((m) >> 10)
165 #define GBYTE_TO_BYTE(g) ((g) << 30)
166 #define GBYTE_TO_KBYTE(g) ((g) << 20)
167 #define GBYTE_TO_MBYTE(g) ((g) << 10)
169 #define streq(a, b) (strncmp((a), (b), strlen(b)+1) == 0)
170 #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
171 #define strcaseeq(a, b) (strcasecmp((a), (b)) == 0)
172 #define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
174 static inline bool is_empty(const char *p)
179 static inline bool strstart_with(const char *str, const char *with)
181 return strncmp(str, with, strlen(with)) == 0;
184 #define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \
185 for ((state) = NULL, (word) = split((s), &(length), (separator), &(state)); \
187 (word) = split((s), &(length), (separator), &(state)))
189 #define FOREACH_WORD(word, length, s, state) \
190 FOREACH_WORD_SEPARATOR(word, length, s, WHITESPACE, state)
192 #define FOREACH_DIRENT(de, d, result, on_error) \
193 for (errno = readdir_r(d, &de, &result);; errno = readdir_r(d, &de, &result)) \
194 if (errno || !result) { \
198 } else if (streq(de.d_name, ".") || \
199 streq(de.d_name, "..")) \
203 #define FOREACH_STRV(s, l) \
204 for ((s) = (l); (s) && *(s); (s)++)
206 #define execute_once \
207 static int __func__##guardian; \
209 __func__##guardian == 0; \
210 __func__##guardian = 1)
213 #define API __attribute__((visibility("default")))
216 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
218 #define DECLARE_WRAPPER(fn_name, inner_fn) \
219 static void fn_name(void *data, void __attribute__((__unused__)) *not_used) \
221 return inner_fn(data); \
224 #define UNUSED __attribute__((__unused__))
226 #define MAX_SIZE2(a, b) sizeof(a) + sizeof(b) - 1
227 #define MAX_SIZE3(a, b, c) MAX_SIZE2(a, b) + sizeof(c) - 1
230 * One byte digit has 3 position in decimal representation
234 * >8 - compile time error
235 * plus 1 null termination byte
236 * plus 1 for negative prefix
238 #define MAX_DEC_SIZE(type) \
239 (2 + (sizeof(type) <= 1 ? 3 : \
240 sizeof(type) <= 2 ? 5 : \
241 sizeof(type) <= 4 ? 10 : \
242 sizeof(type) <= 8 ? 20 : \
243 sizeof(int[-2*(sizeof(type) > 8)])))
245 #define SET_BIT(a, bit) \
248 #define UNSET_BIT(a, bit) \
251 #define CHECK_BIT(a, bit) \
254 #define ret_msg_if(expr, fmt, arg...) do { \
256 STC_LOGE(fmt, ##arg); \
261 #define ret_value_if(expr, val) do { \
263 STC_LOGE("(%s) -> %s():%d return", #expr, __FUNCTION__, __LINE__); \
268 #define ret_value_msg_if(expr, val, fmt, arg...) do { \
270 STC_LOGE(fmt, ##arg); \
275 #define ret_value_errno_msg_if(expr, val, fmt, arg...) do { \
277 STC_LOGE(fmt, ##arg); \
284 * @brief Copy from source to destination
285 * destination should not be on heap.
286 * Destination will be null terminated
288 #define STRING_SAVE_COPY(destination, source) do { \
289 if (destination && source) { \
290 size_t null_pos = strlen(source); \
291 strncpy(destination, source, sizeof(destination)); \
292 null_pos = sizeof(destination) - 1 < null_pos ? \
293 sizeof(destination) - 1 : null_pos; \
294 destination[null_pos] = '\0'; \
298 /* FIXME: Do we really need pointers? */
299 #define array_foreach(key, type, array) \
300 guint _array_foreach_index; \
302 for (_array_foreach_index = 0; \
303 array && _array_foreach_index < array->len && \
304 (key = &g_array_index(array, type, _array_foreach_index)); \
305 ++_array_foreach_index)
307 #define slist_foreach(key, type, list) \
309 GSList *_slist_foreach_copy_list = list; \
311 _slist_foreach_copy_list && \
312 ((key = _slist_foreach_copy_list->data) || 1); \
313 _slist_foreach_copy_list = _slist_foreach_copy_list->next)
315 #define gslist_for_each_item(item, list) \
316 for (item = list; item != NULL; item = g_slist_next(item))
318 #define gslist_for_each(head, elem, node) \
319 for (elem = head, node = NULL; elem && ((node = elem->data) != NULL); elem = elem->next, node = NULL)
321 #define gslist_for_each_safe(head, elem, elem_next, node) \
322 for (elem = head, elem_next = g_slist_next(elem), node = NULL; \
323 elem && ((node = elem->data) != NULL); \
324 elem = elem_next, elem_next = g_slist_next(elem), node = NULL)
326 #define TASK_FILE_NAME "tasks"
327 #define CGROUP_FILE_NAME "cgroup.procs"
328 #define UNKNOWN_APP "(unknown)"
330 #define INFO_STORAGE_DIR "/var/lib/stc"
331 #define INFO_CONFIG "info.config"
332 #define INFO_DEBUGLOG "debuglog"
334 #define MAX_PATH_LENGTH 512
335 #define MAX_NAME_LENGTH 256
336 #define MAX_IFACE_LENGTH 32
337 #define MAX_APPID_LENGTH 128
338 #define MAX_PKGNAME_LENGTH 128
340 #define PROC_BUF_MAX 64
341 #define PROC_NAME_MAX 1024
342 #define PROC_STATUS_CNT 7
344 #define PROC_STATUS_NAME 0
345 #define PROC_STATUS_STATE 1
346 #define PROC_STATUS_TGID 2
347 #define PROC_STATUS_NGID 3
348 #define PROC_STATUS_PID 4
349 #define PROC_STATUS_PPID 5
350 #define PROC_STATUS_TRACERPID 6
352 #define PROC_STATUS_NAME_STR "Name:"
353 #define PROC_STATUS_STATE_STR "State:"
354 #define PROC_STATUS_TGID_STR "Tgid:"
355 #define PROC_STATUS_NGID_STR "Ngid:"
356 #define PROC_STATUS_PID_STR "Pid:"
357 #define PROC_STATUS_PPID_STR "PPid:"
358 #define PROC_STATUS_TRACERPID_STR "TracerPid:"
360 #define COMMA_DELIMETER ","
362 #define COUNTER_UPDATE_PERIOD 60
363 #define COUNTER_FLUSH_PERIOD 60
365 #define NONE_QUOTA_ID 0
367 #define TIME_TO_SAFE_DATA 1 /* one second */
370 * @desc reserved classid enums
371 * internal structure, we don't provide it externally
373 enum stc_reserved_classid {
375 STC_ALL_APP_CLASSID, /**< kernel expects 1 for handling restriction for all applications */
376 STC_TETHERING_APP_CLASSID, /**< it uses in user space logic for counting tethering traffic */
377 STC_FOREGROUND_APP_CLASSID, /**< it will used for special cgroup, blocked cgroup */
378 STC_BACKGROUND_APP_CLASSID, /**< background data monitoring */
379 STC_TOTAL_DATACALL_CLASSID, /**< Cellular data monitoring */
380 STC_TOTAL_WIFI_CLASSID, /**< Wi-Fi data monitoring */
381 STC_TOTAL_BLUETOOTH_CLASSID,
382 STC_TOTAL_IPV4_CLASSID, /**< IPV4 data monitoring */
383 STC_TOTAL_IPV6_CLASSID, /**< IPV6 data monitoring */
384 STC_NETWORK_RESTRICTION_APP_CLASSID,
385 STC_RESERVED_CLASSID_MAX,
388 enum stc_counter_state {
389 STC_DEFAULT_STATE = 0,
390 STC_FORCIBLY_FLUSH_STATE = 1 << 1,
391 STC_FORCIBLY_QUIT_STATE = 1 << 2,
392 STC_NET_BLOCKED_STATE = 1 << 3,
393 STC_CHECK_QUOTA = 1 << 4,
394 STC_UPDATE_REQUESTED = 1 << 5,
397 gboolean stc_util_get_config_bool(char *key);
398 gchar * stc_util_get_config_str(char *key);
399 int stc_util_get_config_int(char *key);
401 void stc_util_set_debuglog(int debuglog);
402 int stc_util_get_debuglog(void);
404 void stc_util_initialize_config(void);
406 #endif /* __STC_MANAGER_UTIL_H__ */