2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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.
28 #include <system_info.h>
29 #include <system_info_private.h>
30 #include <sys/utsname.h>
32 #define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))
33 #define KEY_PREFIX "http://"
35 #define SYSTEM_INFO_MAX -1
39 #define GDBM_CACHE_SIZE 10 /* GDBM default == 100 */
41 extern const struct runtime runtime[LANG_MAX];
43 GHashTable *hashtable = NULL;
44 static pthread_mutex_t fmutex = PTHREAD_MUTEX_INITIALIZER;
46 static char *system_info_db_path;
53 //LCOV_EXCL_START : not supported feature
54 API int system_info_get_value_int(system_info_key_e key, int *value)
56 return SYSTEM_INFO_ERROR_NOT_SUPPORTED;
59 API int system_info_get_value_bool(system_info_key_e key, bool *value)
61 return SYSTEM_INFO_ERROR_NOT_SUPPORTED;
64 API int system_info_get_value_double(system_info_key_e key, double *value)
66 return SYSTEM_INFO_ERROR_NOT_SUPPORTED;
69 API int system_info_get_value_string(system_info_key_e key, char **value)
71 return SYSTEM_INFO_ERROR_NOT_SUPPORTED;
75 static void destroy_key_value(gpointer data)
80 static int db_get_value(enum tag_type tag, const char *key,
81 const char *type, char *value, size_t len)
84 char key_internal[KEY_MAX];
90 int cache_size = GDBM_CACHE_SIZE;
93 if (!key || !type || !value)
94 return SYSTEM_INFO_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
97 case TAG_TYPE_PLATFORM:
98 tag_s = TAG_TYPE_PLATFORM_STR;
100 case TAG_TYPE_CUSTOM:
101 tag_s = TAG_TYPE_CUSTOM_STR;
107 if (strstr(key, KEY_PREFIX) == key)
108 snprintf(key_internal, sizeof(key_internal), "%s:%s:%s", key, type, tag_s);
110 snprintf(key_internal, sizeof(key_internal), "%s%s:%s:%s", KEY_PREFIX, key, type, tag_s);
112 pthread_mutex_lock(&fmutex);
114 hashtable = g_hash_table_new_full(g_str_hash, g_str_equal, destroy_key_value, destroy_key_value);
116 temp = (char *)g_hash_table_lookup(hashtable, key_internal);
118 snprintf(value, len, "%s", temp);
119 pthread_mutex_unlock(&fmutex);
120 return SYSTEM_INFO_ERROR_NONE;
124 if (access(SYSTEM_INFO_DB_RW_PATH, R_OK) == 0)
125 db_path = SYSTEM_INFO_DB_RW_PATH;
127 db_path = SYSTEM_INFO_DB_RO_PATH;
129 db = gdbm_open(db_path, 0, GDBM_READER, S_IRUSR | S_IRGRP | S_IROTH, NULL);
131 _E("Failed to open db (%d, %s)", gdbm_errno, gdbm_strerror(gdbm_errno)); //LCOV_EXCL_LINE
132 pthread_mutex_unlock(&fmutex);
133 return SYSTEM_INFO_ERROR_IO_ERROR; //LCOV_EXCL_LINE
136 ret = gdbm_setopt(db, GDBM_CACHESIZE, &cache_size, sizeof(cache_size));
138 _E("Failed to set cache size to (%d) (ret:%d)", cache_size, gdbm_errno); //LCOV_EXCL_LINE
140 d_key.dptr = key_internal;
141 d_key.dsize = strlen(key_internal) + 1;
143 d_data = gdbm_fetch(db, d_key);
145 _E("Failed to find key (%s, %s)", key, type);
146 ret = SYSTEM_INFO_ERROR_INVALID_PARAMETER;
150 if (len <= d_data.dsize) {
151 _E("Buffer size is smaller than DB value size. It can be cut");
152 d_data.dsize = len - 1;
155 memcpy(value, d_data.dptr, d_data.dsize);
156 value[d_data.dsize] = '\0';
158 ret = SYSTEM_INFO_ERROR_NONE;
160 g_hash_table_insert(hashtable, strdup(key_internal), strdup(value));
164 pthread_mutex_unlock(&fmutex);
168 struct sysinfo_type {
169 system_info_type_e type_e;
170 const char *type_str;
172 { SYSTEM_INFO_BOOL, BOOL_TYPE },
173 { SYSTEM_INFO_INT, INT_TYPE },
174 { SYSTEM_INFO_DOUBLE, DBL_TYPE },
175 { SYSTEM_INFO_STRING, STR_TYPE },
178 static int system_info_get_type(enum tag_type tag, const char *key,
179 system_info_type_e *type)
181 char key_internal[KEY_MAX];
187 int cache_size = GDBM_CACHE_SIZE;
191 return SYSTEM_INFO_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
194 case TAG_TYPE_PLATFORM:
195 tag_s = TAG_TYPE_PLATFORM_STR;
197 case TAG_TYPE_CUSTOM:
198 tag_s = TAG_TYPE_CUSTOM_STR;
204 pthread_mutex_lock(&fmutex);
206 hashtable = g_hash_table_new_full(g_str_hash, g_str_equal, destroy_key_value, destroy_key_value);
208 for (i = 0 ; i < ARRAY_SIZE(info_type); i++) {
209 if (strstr(key, KEY_PREFIX) == key)
210 snprintf(key_internal, sizeof(key_internal),
211 "%s:%s:%s", key, info_type[i].type_str, tag_s);
213 snprintf(key_internal, sizeof(key_internal),
214 "%s%s:%s:%s", KEY_PREFIX, key, info_type[i].type_str, tag_s);
215 temp = g_hash_table_lookup(hashtable, key_internal);
219 *type = info_type[i].type_e;
220 pthread_mutex_unlock(&fmutex);
221 return SYSTEM_INFO_ERROR_NONE;
225 if (!system_info_db_path) {
226 if (access(SYSTEM_INFO_DB_RW_PATH, R_OK) == 0)
227 system_info_db_path = SYSTEM_INFO_DB_RW_PATH;
229 system_info_db_path = SYSTEM_INFO_DB_RO_PATH;
232 db = gdbm_open(system_info_db_path, 0, GDBM_READER, S_IRUSR | S_IRGRP | S_IROTH, NULL);
234 _E("Failed to open db (%d, %s)", gdbm_errno, gdbm_strerror(gdbm_errno)); //LCOV_EXCL_LINE
235 pthread_mutex_unlock(&fmutex);
236 return SYSTEM_INFO_ERROR_IO_ERROR; //LCOV_EXCL_LINE
239 ret = gdbm_setopt(db, GDBM_CACHESIZE, &cache_size, sizeof(cache_size));
241 _E("Failed to set cache size to (%d) (ret:%d)", cache_size, gdbm_errno); //LCOV_EXCL_LINE
243 for (i = 0 ; i < ARRAY_SIZE(info_type); i++) {
244 if (strstr(key, KEY_PREFIX) == key)
245 snprintf(key_internal, sizeof(key_internal),
246 "%s:%s:%s", key, info_type[i].type_str, tag_s);
248 snprintf(key_internal, sizeof(key_internal),
249 "%s%s:%s:%s", KEY_PREFIX, key, info_type[i].type_str, tag_s);
251 d_key.dptr = key_internal;
252 d_key.dsize = strlen(key_internal) + 1;
254 d_data = gdbm_fetch(db, d_key);
256 *type = info_type[i].type_e;
257 ret = SYSTEM_INFO_ERROR_NONE;
259 g_hash_table_insert(hashtable, strndup(key_internal, d_key.dsize),
260 strndup(d_data.dptr, d_data.dsize));
266 if (tag == TAG_TYPE_PLATFORM)
267 ret = system_info_get_type_file(key, type);
269 ret = SYSTEM_INFO_ERROR_INVALID_PARAMETER;
274 pthread_mutex_unlock(&fmutex);
278 static int system_info_get_bool(enum tag_type tag, const char *key, bool *value)
284 const char *runtime_type;
288 return SYSTEM_INFO_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
290 ret = db_get_value(tag, key, BOOL_TYPE, val, sizeof(val));
291 if (ret == SYSTEM_INFO_ERROR_NONE) {
292 runtime_type = getenv("RUNTIME_TYPE");
294 for (rt = 0; rt < LANG_MAX; rt++) {
295 if (!runtime[rt].runtime_type)
297 if (!strncmp(runtime_type, runtime[rt].runtime_type, RT_PREFIX)) {
298 *value = val[runtime[rt].lang] == 'T' ? true : false;
299 return SYSTEM_INFO_ERROR_NONE;
302 _D("Unknown RUNTIME_TYPE, return default value");
305 *value = val[runtime[DEFAULT].lang] == 'T' ? true : false;
306 return SYSTEM_INFO_ERROR_NONE;
309 if (tag == TAG_TYPE_CUSTOM) {
310 ret = external_get_value(TAG_TYPE_CUSTOM_STR, key, BOOL_TYPE, &valp);
311 if (ret == SYSTEM_INFO_ERROR_NONE) {
312 snprintf(val, sizeof(val), "%s", valp); //LCOV_EXCL_LINE
313 free(valp); //LCOV_EXCL_LINE
315 len = strlen(val) + 0;
316 if (!strncmp(val, "true", len) || !strncmp(val, "TRUE", len))
321 return SYSTEM_INFO_ERROR_NONE;
325 _E("Invalid key (%s), type:bool", key);
327 return SYSTEM_INFO_ERROR_INVALID_PARAMETER;
330 static int system_info_get_int(enum tag_type tag, const char *key, int *value)
337 return SYSTEM_INFO_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
339 ret = db_get_value(tag, key, INT_TYPE, val, sizeof(val));
340 if (ret == SYSTEM_INFO_ERROR_NONE)
343 if (tag == TAG_TYPE_CUSTOM) {
344 ret = external_get_value(TAG_TYPE_CUSTOM_STR, key, INT_TYPE, &valp);
345 if (ret == SYSTEM_INFO_ERROR_NONE) {
346 snprintf(val, sizeof(val), "%s", valp); //LCOV_EXCL_LINE
347 free(valp); //LCOV_EXCL_LINE
348 goto out; //LCOV_EXCL_LINE
352 _E("Invalid key (%s), type:integer", key);
354 return SYSTEM_INFO_ERROR_INVALID_PARAMETER;
359 return SYSTEM_INFO_ERROR_NONE;
362 static int system_info_get_double(enum tag_type tag, const char *key, double *value)
369 return SYSTEM_INFO_ERROR_INVALID_PARAMETER;
371 ret = db_get_value(tag, key, DBL_TYPE, val, sizeof(val));
372 if (ret == SYSTEM_INFO_ERROR_NONE)
375 if (tag == TAG_TYPE_CUSTOM) {
376 ret = external_get_value(TAG_TYPE_CUSTOM_STR, key, DBL_TYPE, &valp);
377 if (ret == SYSTEM_INFO_ERROR_NONE) {
378 snprintf(val, sizeof(val), "%s", valp); //LCOV_EXCL_LINE
379 free(valp); //LCOV_EXCL_LINE
380 goto out; //LCOV_EXCL_LINE
384 _E("Invalid key (%s), type:double", key);
386 return SYSTEM_INFO_ERROR_INVALID_PARAMETER;
391 return SYSTEM_INFO_ERROR_NONE;
394 static int system_info_get_string(enum tag_type tag, const char *key, char **value)
402 return SYSTEM_INFO_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
404 ret = db_get_value(tag, key, STR_TYPE, val, sizeof(val));
405 if (ret == SYSTEM_INFO_ERROR_NONE)
408 if (tag == TAG_TYPE_PLATFORM) {
409 ret = system_info_get_file(key, val, sizeof(val));
410 if (ret == SYSTEM_INFO_ERROR_NONE)
414 if (tag == TAG_TYPE_CUSTOM) {
415 ret = external_get_value(TAG_TYPE_CUSTOM_STR, key, DBL_TYPE, &valp);
416 if (ret == SYSTEM_INFO_ERROR_NONE) {
417 snprintf(val, sizeof(val), "%s", valp); //LCOV_EXCL_LINE
418 free(valp); //LCOV_EXCL_LINE
419 goto out; //LCOV_EXCL_LINE
423 _E("Invalid key (%s) type:string", key);
425 return SYSTEM_INFO_ERROR_INVALID_PARAMETER;
428 string = strdup(val);
430 _E("malloc failed"); //LCOV_EXCL_LINE
431 return SYSTEM_INFO_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
436 return SYSTEM_INFO_ERROR_NONE;
439 API int system_info_get_platform_bool(const char *key, bool *value)
441 return system_info_get_bool(TAG_TYPE_PLATFORM, key, value);
444 API int system_info_get_platform_int(const char *key, int *value)
446 return system_info_get_int(TAG_TYPE_PLATFORM, key, value);
449 API int system_info_get_platform_double(const char *key, double *value)
451 return system_info_get_double(TAG_TYPE_PLATFORM, key, value);
454 API int system_info_get_platform_string(const char *key, char **value)
456 return system_info_get_string(TAG_TYPE_PLATFORM, key, value);
459 API int system_info_get_custom_bool(const char *key, bool *value)
461 return system_info_get_bool(TAG_TYPE_CUSTOM, key, value);
464 API int system_info_get_custom_int(const char *key, int *value)
466 return system_info_get_int(TAG_TYPE_CUSTOM, key, value);
469 API int system_info_get_custom_double(const char *key, double *value)
471 return system_info_get_double(TAG_TYPE_CUSTOM, key, value);
474 API int system_info_get_custom_string(const char *key, char **value)
476 return system_info_get_string(TAG_TYPE_CUSTOM, key, value);
479 API int system_info_get_platform_type(const char *key, system_info_type_e *type)
481 return system_info_get_type(TAG_TYPE_PLATFORM, key, type);
484 API int system_info_get_custom_type(const char *key, system_info_type_e *type)
490 ret = system_info_get_type(TAG_TYPE_CUSTOM, key, type);
491 if (ret == SYSTEM_INFO_ERROR_NONE)
492 return SYSTEM_INFO_ERROR_NONE;
494 ret = external_get_type(TAG_TYPE_CUSTOM_STR, key, &val);
495 if (ret != SYSTEM_INFO_ERROR_NONE) {
496 _E("Failed to get type of key (%s)", key);
497 return SYSTEM_INFO_ERROR_INVALID_PARAMETER;
501 len = strlen(val) + 1;
502 if (!strncmp(BOOL_TYPE, val, len))
503 *type = SYSTEM_INFO_BOOL;
504 else if (!strncmp(INT_TYPE, val, len))
505 *type = SYSTEM_INFO_INT;
506 else if (!strncmp(DBL_TYPE, val, len))
507 *type = SYSTEM_INFO_DOUBLE;
508 else if (!strncmp(STR_TYPE, val, len))
509 *type = SYSTEM_INFO_STRING;
511 _E("Invalid type (%s)", val);
513 return SYSTEM_INFO_ERROR_INVALID_PARAMETER;
517 return SYSTEM_INFO_ERROR_NONE;