2 * Copyright (c) 2013 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.
18 #include <sys/types.h>
20 #if defined(USE_PTHREAD_WAITING)
28 #include <cynara-monitor.h>
29 #include "PrivacyGuardTypes.h"
31 #include "CynaraService.h"
32 #include "PrivacyGuardDb.h"
33 #include "PrivacyIdInfo.h"
37 static cynara_monitor_configuration *p_conf;
38 static cynara_monitor *p_cynara_monitor;
39 static cynara_monitor_entry **monitor_entries;
40 static bool exit_flag;
42 #if defined(USE_PTHREAD_WAITING)
43 static pthread_cond_t g_condition;
44 static pthread_mutex_t g_mutex;
47 CynaraService::CynaraService(void)
53 CynaraService::~CynaraService(void)
58 CynaraService::initialize(void)
60 PG_LOGD("[cynara_service] CynaraService initializing");
62 int res = cynara_monitor_configuration_create(&p_conf);
63 if(res != CYNARA_API_SUCCESS){
64 PG_LOGE("cynara_monitor_configuration_create() is failed.");
65 return PRIV_GUARD_ERROR_SYSTEM_ERROR;
68 res = cynara_monitor_configuration_set_buffer_size(p_conf, CYNARA_BUFFER_SIZE);
69 if(res != CYNARA_API_SUCCESS){
70 PG_LOGE("cynara_monitor_configuration_set_buffer_size() is failed.");
71 return PRIV_GUARD_ERROR_SYSTEM_ERROR;
74 res = cynara_monitor_initialize(&p_cynara_monitor, p_conf);
75 if(res != CYNARA_API_SUCCESS){
76 PG_LOGE("cynara_monitor_initialize() is failed.");
77 return PRIV_GUARD_ERROR_SYSTEM_ERROR;
80 // cynara_monitor_configuration_set_filter
82 PG_LOGI("CynaraService initialized");
84 return PRIV_GUARD_ERROR_SUCCESS;
88 CynaraService::start(void)
90 PG_LOGI("[cynara_service] CynaraService starting");
97 res = pthread_sigmask(SIG_BLOCK, &sigset, NULL);
98 TryReturn( res >= 0, PRIV_GUARD_ERROR_SYSTEM_ERROR, , "pthread_sigmask : %s", strerror_r(errno, buf, sizeof(buf)));
100 #if defined(USE_PTHREAD_WAITING)
101 pthread_mutex_init(&g_mutex, NULL);
102 pthread_cond_init(&g_condition, NULL);
105 pthread_t cynaraThread;
106 PG_LOGD("starting new thread (getEntriesThread)");
107 res = pthread_create(&cynaraThread, NULL, &getEntriesThread, this);
108 TryReturn( res >= 0, PRIV_GUARD_ERROR_SYSTEM_ERROR, errno = res, "pthread_create : %s", strerror_r(errno, buf, sizeof(buf)));
109 PG_LOGD("new thread (getEntriesThread) started");
111 m_cynaraThread = cynaraThread;
115 PG_LOGD("CynaraService started");
117 return PRIV_GUARD_ERROR_SUCCESS;
121 CynaraService::getEntriesThread(void* pData)
123 PG_LOGD("[cynara_service] Running get entries thread");
127 pthread_detach(pthread_self());
129 while (exit_flag == false) {
130 if (monitor_entries) {
131 cynara_monitor_entries_free(monitor_entries);
132 monitor_entries = NULL;
135 // returned when the cynara buffer is full or cynara_monitor_entries_flush() is called from another thread
136 res = cynara_monitor_entries_get(p_cynara_monitor, &monitor_entries);
137 if(res != CYNARA_API_SUCCESS){
138 PG_LOGE("cynara_monitor_entries_get() is failed. [%d]", res);
139 #if defined(USE_PTHREAD_WAITING)
142 gettimeofday(&now, NULL);
143 ts.tv_sec = now.tv_sec + 1;
144 ts.tv_nsec = now.tv_usec * 1000;
146 pthread_mutex_lock(&g_mutex);
147 PG_LOGD("now waiting wakeup signal about 1 sec..");
148 pthread_cond_timedwait(&g_condition, &g_mutex, &ts);
149 PG_LOGD("ok, i'm wakeup..");
150 pthread_mutex_unlock(&g_mutex);
152 usleep(SLEEP_TIME * 20); // 1 SEC
155 if (monitor_entries) {
156 res = CynaraService::updateDb(monitor_entries);
157 if(res != PRIV_GUARD_ERROR_SUCCESS) {
158 PG_LOGE("CynaraService::updateDb() is failed. [%d]", res);
163 if (monitor_entries) {
164 cynara_monitor_entries_free(monitor_entries);
165 monitor_entries = NULL;
169 return (void*) PRIV_GUARD_ERROR_SUCCESS;
173 CynaraService::updateDb(cynara_monitor_entry **monitor_entries)
175 cynara_monitor_entry **entryIter = monitor_entries;
178 const char *user = NULL, *client = NULL, *privilege = NULL;
179 const timespec *timestamp = NULL;
181 std::string packageId, privacyId;
185 while (*entryIter != nullptr) {
186 privilege = cynara_monitor_entry_get_privilege(*entryIter);
187 TryReturn(privilege != NULL, PRIV_GUARD_ERROR_SYSTEM_ERROR, , "Privilege Id in the entry is NULL");
189 // change from privilege to privacy
190 res = PrivacyIdInfo::getPrivacyIdFromPrivilege(privilege, privacyId);
191 if (res != PRIV_GUARD_ERROR_NO_DATA) {
193 user = cynara_monitor_entry_get_user(*entryIter);
194 TryReturn(user != NULL, PRIV_GUARD_ERROR_SYSTEM_ERROR, , "User Id in the entry is NULL");
196 // Package ID - string
197 client = cynara_monitor_entry_get_client(*entryIter);
198 TryReturn(client != NULL, PRIV_GUARD_ERROR_SYSTEM_ERROR, , "Package Id in the entry is NULL");
201 timestamp = cynara_monitor_entry_get_timestamp(*entryIter);
202 TryReturn(timestamp != NULL, PRIV_GUARD_ERROR_SYSTEM_ERROR, , "timestamp in the entry is NULL");
204 // convert string to integer
208 std::string tempPackageId = client;
209 PG_LOGD("Package ID from cynara: [%s]", client);
210 if (tempPackageId.substr(0, USER_APP_PREFIX_LEN).compare(USER_APP_PREFIX) == 0) {
211 packageId = tempPackageId.substr(USER_APP_PREFIX_LEN, tempPackageId.length() - USER_APP_PREFIX_LEN);
212 PG_LOGD("Fixed Package ID: [%s]", packageId.c_str());
215 PG_LOGD("Fixed Package ID: [%s]", client);
219 date = timestamp->tv_sec;
222 int ret = PrivacyGuardDb::getInstance()->PgAddPrivacyAccessLogForCynara(userId, packageId, privacyId, date);
223 if(ret == PRIV_GUARD_ERROR_SUCCESS){
224 PG_LOGD("Succeeded to add access log to DB. UserID:[%d], PackageID:[%s], Privacy:[%s]", userId, packageId.c_str(), privacyId.c_str());
227 PG_LOGE("Failed to add access log to DB. UserID:[%d], PackageID:[%s], Privacy:[%s]", userId, packageId.c_str(), privacyId.c_str());
233 return PRIV_GUARD_ERROR_SUCCESS;
238 CynaraService::stop(void)
243 // set thread exit condition
246 // [CYNARA] Flush Entries
247 ret = cynara_monitor_entries_flush(p_cynara_monitor);
248 if(ret != CYNARA_API_SUCCESS) {
249 if (ret == CYNARA_API_OPERATION_NOT_ALLOWED) {
250 PG_LOGD("There is no logs in the cynara buffer.");
252 PG_LOGE("cynara_monitor_entries_flush FAIL [%d]", ret);
253 return PRIV_GUARD_ERROR_SYSTEM_ERROR;
257 if((ret = pthread_kill(m_cynaraThread, m_signalToClose)) < 0) {
258 PG_LOGE("pthread_kill(): %s", strerror_r(ret, buf, sizeof(buf)));
259 return PRIV_GUARD_ERROR_IPC_ERROR;
261 pthread_join(m_cynaraThread, NULL);
263 #if defined(USE_PTHREAD_WAITING)
264 pthread_cond_destroy(&g_condition);
265 pthread_mutex_destroy(&g_mutex);
268 ret = cynara_monitor_finish(p_cynara_monitor);
269 if(ret != CYNARA_API_SUCCESS) {
270 PG_LOGE("cynara_monitor_finish() is failed. [%d]", ret);
271 return PRIV_GUARD_ERROR_SYSTEM_ERROR;
274 return PRIV_GUARD_ERROR_SUCCESS;
278 CynaraService::shutdown(void)
280 cynara_monitor_configuration_destroy(p_conf);
282 return PRIV_GUARD_ERROR_SUCCESS;