summaryrefslogtreecommitdiff
path: root/src/components/policy/policy_regular/src
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/policy/policy_regular/src')
-rw-r--r--src/components/policy/policy_regular/src/cache_manager.cc1636
-rw-r--r--src/components/policy/policy_regular/src/policy_helper.cc805
-rw-r--r--src/components/policy/policy_regular/src/policy_manager_impl.cc1130
-rw-r--r--src/components/policy/policy_regular/src/policy_table.cc52
-rw-r--r--src/components/policy/policy_regular/src/policy_table/enums.cc577
-rw-r--r--src/components/policy/policy_regular/src/policy_table/types.cc1389
-rw-r--r--src/components/policy/policy_regular/src/policy_table/validation.cc197
-rw-r--r--src/components/policy/policy_regular/src/sql_pt_ext_queries.cc268
-rw-r--r--src/components/policy/policy_regular/src/sql_pt_ext_representation.cc1807
-rw-r--r--src/components/policy/policy_regular/src/sql_pt_queries.cc712
-rw-r--r--src/components/policy/policy_regular/src/sql_pt_representation.cc1755
-rw-r--r--src/components/policy/policy_regular/src/status.cc141
-rw-r--r--src/components/policy/policy_regular/src/update_status_manager.cc190
-rw-r--r--src/components/policy/policy_regular/src/usage_statistics/counter.cc122
14 files changed, 10781 insertions, 0 deletions
diff --git a/src/components/policy/policy_regular/src/cache_manager.cc b/src/components/policy/policy_regular/src/cache_manager.cc
new file mode 100644
index 0000000000..6184320306
--- /dev/null
+++ b/src/components/policy/policy_regular/src/cache_manager.cc
@@ -0,0 +1,1636 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "policy/cache_manager.h"
+
+#include <algorithm>
+#include <functional>
+#include <ctime>
+#include <cmath>
+
+#include "utils/file_system.h"
+#include "json/reader.h"
+#include "json/features.h"
+#include "json/writer.h"
+#include "utils/logger.h"
+#include "utils/date_time.h"
+#include "utils/gen_hash.h"
+#include "utils/macro.h"
+#include "utils/threads/thread.h"
+#include "utils/threads/thread_delegate.h"
+
+#include "policy/sql_pt_representation.h"
+
+namespace policy_table = rpc::policy_table_interface_base;
+
+namespace policy {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Policy")
+
+#define CACHE_MANAGER_CHECK(return_value) \
+ { \
+ if (!pt_) { \
+ LOG4CXX_WARN(logger_, "The cache manager is not initialized"); \
+ return return_value; \
+ } \
+ }
+
+#define CACHE_MANAGER_CHECK_VOID() \
+ { \
+ if (!pt_) { \
+ LOG4CXX_WARN(logger_, "The cache manager is not initialized"); \
+ return; \
+ } \
+ }
+
+struct LanguageFinder {
+ LanguageFinder(const std::string& language) : language_(language) {}
+ bool operator()(const policy_table::Languages::value_type& lang) const {
+ return !strcasecmp(language_.c_str(), lang.first.c_str());
+ }
+
+ private:
+ const std::string& language_;
+};
+
+CacheManager::CacheManager()
+ : CacheManagerInterface()
+ , pt_(new policy_table::Table)
+ , backup_(new SQLPTRepresentation())
+ , update_required(false) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ backuper_ = new BackgroundBackuper(this);
+ backup_thread_ = threads::CreateThread("Backup thread", backuper_);
+ backup_thread_->start();
+}
+
+CacheManager::~CacheManager() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(backuper_locker_);
+ backup_thread_->join();
+ delete backup_thread_->delegate();
+ threads::DeleteThread(backup_thread_);
+}
+
+const policy_table::Strings& CacheManager::GetGroups(const PTString& app_id) {
+ return pt_->policy_table.app_policies_section.apps[app_id].groups;
+}
+
+bool CacheManager::CanAppKeepContext(const std::string& app_id) const {
+ CACHE_MANAGER_CHECK(false);
+ bool result = true;
+ return result;
+}
+
+uint32_t CacheManager::HeartBeatTimeout(const std::string& app_id) const {
+ CACHE_MANAGER_CHECK(0);
+ uint32_t result = 0;
+ if (!AppExists(app_id)) {
+ return result;
+ }
+
+ const policy_table::ApplicationPolicies::mapped_type& app =
+ pt_->policy_table.app_policies_section.apps[app_id];
+ if (app.heart_beat_timeout_ms.is_initialized()) {
+ result = *(app.heart_beat_timeout_ms);
+ }
+
+ return result;
+}
+
+bool CacheManager::CanAppStealFocus(const std::string& app_id) const {
+ CACHE_MANAGER_CHECK(false);
+ bool result = true;
+ return result;
+}
+
+bool CacheManager::GetDefaultHMI(const std::string& app_id,
+ std::string& default_hmi) const {
+ CACHE_MANAGER_CHECK(false);
+ bool result = true;
+ return result;
+}
+
+bool CacheManager::ResetUserConsent() {
+ CACHE_MANAGER_CHECK(false);
+ sync_primitives::AutoLock lock(cache_lock_);
+ return true;
+}
+
+bool CacheManager::GetUserPermissionsForDevice(
+ const std::string& device_id,
+ StringArray& consented_groups,
+ StringArray& disallowed_groups) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(false);
+ return true;
+}
+
+void CacheManager::GetAllAppGroups(const std::string& app_id,
+ FunctionalGroupIDs& all_group_ids) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+
+ if (kDeviceId == app_id) {
+ LOG4CXX_INFO(logger_, "Devices doesn't have groups");
+ return;
+ }
+
+ policy_table::ApplicationPolicies::const_iterator app_params_iter =
+ pt_->policy_table.app_policies_section.apps.find(app_id);
+
+ if (pt_->policy_table.app_policies_section.apps.end() != app_params_iter) {
+ policy_table::Strings::const_iterator iter =
+ (*app_params_iter).second.groups.begin();
+ policy_table::Strings::const_iterator iter_end =
+ (*app_params_iter).second.groups.end();
+
+ for (; iter != iter_end; ++iter) {
+ const uint32_t group_id = static_cast<uint32_t>((GenerateHash(*iter)));
+ all_group_ids.push_back(group_id);
+ }
+ }
+}
+
+void CacheManager::GetPreConsentedGroups(
+ const std::string& app_id, FunctionalGroupIDs& preconsented_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+}
+
+void CacheManager::GetConsentedGroups(const std::string& device_id,
+ const std::string& app_id,
+ FunctionalGroupIDs& allowed_groups,
+ FunctionalGroupIDs& disallowed_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+}
+
+void CacheManager::GetUnconsentedGroups(
+ const std::string& device_id,
+ const std::string& policy_app_id,
+ FunctionalGroupIDs& unconsented_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+}
+
+void CacheManager::RemoveAppConsentForGroup(const std::string& app_id,
+ const std::string& group_name) {
+ CACHE_MANAGER_CHECK_VOID();
+}
+
+bool CacheManager::ApplyUpdate(const policy_table::Table& update_pt) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(false);
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+ pt_->policy_table.functional_groupings =
+ update_pt.policy_table.functional_groupings;
+
+ policy_table::ApplicationPolicies::const_iterator iter =
+ update_pt.policy_table.app_policies_section.apps.begin();
+ policy_table::ApplicationPolicies::const_iterator iter_end =
+ update_pt.policy_table.app_policies_section.apps.end();
+
+ for (; iter != iter_end; ++iter) {
+ if (iter->second.is_null()) {
+ pt_->policy_table.app_policies_section.apps[iter->first].set_to_null();
+ pt_->policy_table.app_policies_section.apps[iter->first].set_to_string(
+ "");
+ } else if (policy::kDefaultId == (iter->second).get_string()) {
+ policy_table::ApplicationPolicies::const_iterator iter_default =
+ update_pt.policy_table.app_policies_section.apps.find(kDefaultId);
+ if (update_pt.policy_table.app_policies_section.apps.end() ==
+ iter_default) {
+ LOG4CXX_ERROR(logger_, "The default section was not found in PTU");
+ continue;
+ }
+ pt_->policy_table.app_policies_section.apps[iter->first] =
+ iter_default->second;
+ } else {
+ pt_->policy_table.app_policies_section.apps[iter->first] = iter->second;
+ }
+ }
+
+ pt_->policy_table.app_policies_section.device =
+ update_pt.policy_table.app_policies_section.device;
+
+ pt_->policy_table.module_config.SafeCopyFrom(
+ update_pt.policy_table.module_config);
+
+ pt_->policy_table.consumer_friendly_messages.assign_if_valid(
+ update_pt.policy_table.consumer_friendly_messages);
+
+ ResetCalculatedPermissions();
+ Backup();
+ return true;
+}
+
+void CacheManager::GetHMIAppTypeAfterUpdate(
+ std::map<std::string, StringArray>& app_hmi_types) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+ policy_table::ApplicationPolicies::const_iterator policy_iter_begin =
+ pt_->policy_table.app_policies_section.apps.begin();
+ policy_table::ApplicationPolicies::const_iterator policy_iter_end =
+ pt_->policy_table.app_policies_section.apps.end();
+ std::vector<std::string> transform_app_hmi_types;
+ for (; policy_iter_begin != policy_iter_end; ++policy_iter_begin) {
+ const policy_table::ApplicationParams& app_params =
+ (*policy_iter_begin).second;
+ if (app_params.AppHMIType.is_initialized()) {
+ if (!(transform_app_hmi_types.empty())) {
+ transform_app_hmi_types.clear();
+ }
+ std::transform(app_params.AppHMIType->begin(),
+ app_params.AppHMIType->end(),
+ std::back_inserter(transform_app_hmi_types),
+ AppHMITypeToString());
+ app_hmi_types[(*policy_iter_begin).first] = transform_app_hmi_types;
+ }
+ }
+}
+
+bool CacheManager::AppHasHMIType(const std::string& application_id,
+ policy_table::AppHMIType hmi_type) const {
+ const policy_table::ApplicationPolicies& policies =
+ pt_->policy_table.app_policies_section.apps;
+
+ policy_table::ApplicationPolicies::const_iterator policy_iter =
+ policies.find(application_id);
+
+ if (policy_iter == policies.end()) {
+ return false;
+ }
+
+ if (policy_iter->second.AppHMIType.is_initialized()) {
+ return helpers::in_range(*(policy_iter->second.AppHMIType),
+ rpc::Enum<policy_table::AppHMIType>(hmi_type));
+ }
+
+ return false;
+}
+
+void CacheManager::Backup() {
+ sync_primitives::AutoLock lock(backuper_locker_);
+ DCHECK(backuper_);
+ backuper_->DoBackup();
+}
+
+std::string CacheManager::currentDateTime() {
+ time_t now = time(0);
+ struct tm tstruct;
+ char buf[80];
+ tstruct = *localtime(&now);
+ // ISO_8601 format is expected, e.g. “2000-01-01T12:18:53Z”
+ strftime(buf, sizeof(buf), "%Y-%m-%dT%XZ", &tstruct);
+ return buf;
+}
+
+bool CacheManager::GetPermissionsForApp(const std::string& device_id,
+ const std::string& app_id,
+ FunctionalIdType& group_types) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ GetAllAppGroups(app_id, group_types[kTypeGeneral]);
+ GetAllAppGroups(kDefaultId, group_types[kTypeDefault]);
+ GetAllAppGroups(kPreDataConsentId, group_types[kTypePreDataConsented]);
+ return true;
+}
+
+bool CacheManager::GetDeviceGroupsFromPolicies(
+ policy_table::Strings& groups,
+ policy_table::Strings& preconsented_groups) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(false);
+ return true;
+}
+
+bool CacheManager::AddDevice(const std::string& device_id,
+ const std::string& connection_type) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+ CACHE_MANAGER_CHECK(false);
+ policy_table::DeviceParams& params =
+ (*(pt_->policy_table.device_data))[device_id];
+
+ // Open SDL stored just device id in policy
+ UNUSED(params);
+
+ // We have to set preloaded flag as false in policy table on adding new
+ // information (SDLAQ-CRS-2365). It can happens only after device addition.
+ *pt_->policy_table.module_config.preloaded_pt = false;
+
+ Backup();
+ return true;
+}
+
+bool CacheManager::SetDeviceData(const std::string& device_id,
+ const std::string& hardware,
+ const std::string& firmware,
+ const std::string& os,
+ const std::string& os_version,
+ const std::string& carrier,
+ const uint32_t number_of_ports,
+ const std::string& connection_type) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+ CACHE_MANAGER_CHECK(false);
+ Backup();
+ return true;
+}
+
+bool CacheManager::SetUserPermissionsForDevice(
+ const std::string& device_id,
+ const StringArray& consented_groups,
+ const StringArray& disallowed_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+ CACHE_MANAGER_CHECK(false);
+ Backup();
+ return true;
+}
+
+bool CacheManager::ReactOnUserDevConsentForApp(const std::string& app_id,
+ bool is_device_allowed) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(false);
+ bool result = true;
+ Backup();
+ return result;
+}
+
+void CacheManager::GetGroupNameByHashID(const int32_t group_id,
+ std::string& group_name) {
+ CACHE_MANAGER_CHECK_VOID();
+ policy_table::FunctionalGroupings::const_iterator fg_iter =
+ pt_->policy_table.functional_groupings.begin();
+ policy_table::FunctionalGroupings::const_iterator fg_iter_end =
+ pt_->policy_table.functional_groupings.end();
+
+ for (; fg_iter != fg_iter_end; ++fg_iter) {
+ const int32_t id = GenerateHash((*fg_iter).first);
+ if (group_id == id) {
+ group_name = (*fg_iter).first;
+ }
+ }
+}
+
+bool CacheManager::SetUserPermissionsForApp(
+ const PermissionConsent& permissions) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+ CACHE_MANAGER_CHECK(false);
+ Backup();
+ return true;
+}
+
+bool CacheManager::UpdateRequired() const {
+ return update_required;
+}
+
+void CacheManager::SaveUpdateRequired(bool status) {
+ update_required = status;
+ Backup();
+}
+
+bool CacheManager::IsApplicationRevoked(const std::string& app_id) const {
+ CACHE_MANAGER_CHECK(false);
+ bool is_revoked = false;
+ if (pt_->policy_table.app_policies_section.apps.end() !=
+ pt_->policy_table.app_policies_section.apps.find(app_id)) {
+ is_revoked = pt_->policy_table.app_policies_section.apps[app_id].is_null();
+ }
+
+ return is_revoked;
+}
+
+void CacheManager::CheckPermissions(const policy_table::Strings& groups,
+ const PTString& hmi_level,
+ const PTString& rpc,
+ CheckPermissionResult& result) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+
+ policy_table::Strings::const_iterator app_groups_iter = groups.begin();
+ policy_table::Strings::const_iterator app_groups_iter_end = groups.end();
+
+ policy_table::FunctionalGroupings::const_iterator concrete_group;
+
+ for (; app_groups_iter != app_groups_iter_end; ++app_groups_iter) {
+ concrete_group =
+ pt_->policy_table.functional_groupings.find(*app_groups_iter);
+ if (pt_->policy_table.functional_groupings.end() != concrete_group) {
+ const policy_table::Rpcs& rpcs = concrete_group->second;
+
+ policy_table::Rpc::const_iterator rpc_iter = rpcs.rpcs.find(rpc);
+ if (rpcs.rpcs.end() != rpc_iter) {
+ policy_table::RpcParameters rpc_param = rpc_iter->second;
+
+ policy_table::HmiLevel hmi_level_e;
+ policy_table::EnumFromJsonString(hmi_level, &hmi_level_e);
+
+ policy_table::HmiLevels::const_iterator hmi_iter =
+ std::find(rpc_param.hmi_levels.begin(),
+ rpc_param.hmi_levels.end(),
+ hmi_level_e);
+
+ if (rpc_param.hmi_levels.end() != hmi_iter) {
+ result.hmi_level_permitted = PermitResult::kRpcAllowed;
+
+ policy_table::Parameters::const_iterator params_iter =
+ rpc_param.parameters->begin();
+ policy_table::Parameters::const_iterator params_iter_end =
+ rpc_param.parameters->end();
+
+ for (; params_iter != params_iter_end; ++params_iter) {
+ result.list_of_allowed_params.insert(
+ policy_table::EnumToJsonString(*params_iter));
+ }
+ }
+ }
+ }
+ }
+}
+
+bool CacheManager::IsPTPreloaded() {
+ CACHE_MANAGER_CHECK(false);
+ return *pt_->policy_table.module_config.preloaded_pt;
+}
+
+int CacheManager::IgnitionCyclesBeforeExchange() {
+ CACHE_MANAGER_CHECK(0);
+ const uint8_t limit = std::max(
+ static_cast<int>(
+ pt_->policy_table.module_config.exchange_after_x_ignition_cycles),
+ 0);
+ LOG4CXX_DEBUG(logger_, "IgnitionCyclesBeforeExchange limit:" << limit);
+ uint8_t current = 0;
+
+ const int last_exch = static_cast<int>(
+ *pt_->policy_table.module_meta->ignition_cycles_since_last_exchange);
+ current = std::max(last_exch, 0);
+ LOG4CXX_DEBUG(
+ logger_,
+ "IgnitionCyclesBeforeExchange current:" << static_cast<int>(current));
+
+ return std::max(limit - current, 0);
+}
+
+int CacheManager::KilometersBeforeExchange(int current) {
+ CACHE_MANAGER_CHECK(0);
+ const int limit =
+ std::max(static_cast<int>(
+ pt_->policy_table.module_config.exchange_after_x_kilometers),
+ 0);
+ LOG4CXX_DEBUG(logger_, "KilometersBeforeExchange limit:" << limit);
+ int last = 0;
+
+ const int odo_val = static_cast<int>(
+ *pt_->policy_table.module_meta->pt_exchanged_at_odometer_x);
+ last = std::max(odo_val, 0);
+ LOG4CXX_DEBUG(logger_, "KilometersBeforeExchange last:" << last);
+
+ const int actual = std::max((current - last), 0);
+ LOG4CXX_DEBUG(logger_, "KilometersBeforeExchange actual:" << actual);
+ return std::max(limit - actual, 0);
+}
+
+bool CacheManager::SetCountersPassedForSuccessfulUpdate(
+ policy::Counters counter, int value) {
+ CACHE_MANAGER_CHECK(false);
+ switch (counter) {
+ case KILOMETERS:
+ *pt_->policy_table.module_meta->pt_exchanged_at_odometer_x = value;
+ LOG4CXX_DEBUG(logger_,
+ "SetCountersPassedForSuccessfulUpdate km:" << value);
+ break;
+ case DAYS_AFTER_EPOCH:
+ *pt_->policy_table.module_meta->pt_exchanged_x_days_after_epoch = value;
+ LOG4CXX_DEBUG(
+ logger_,
+ "SetCountersPassedForSuccessfulUpdate days after epoch:" << value);
+ break;
+ default:
+ LOG4CXX_ERROR(logger_,
+ "Unknown counter was requested to set: " << counter);
+ return false;
+ }
+
+ Backup();
+ return true;
+}
+
+int CacheManager::DaysBeforeExchange(int current) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(0);
+
+ const rpc::Optional<rpc::Integer<uint16_t, 0, 65535> >& days_after_epoch =
+ (pt_->policy_table.module_meta->pt_exchanged_x_days_after_epoch);
+
+ if (!days_after_epoch->is_initialized()) {
+ return -1;
+ }
+
+ const uint8_t limit = pt_->policy_table.module_config.exchange_after_x_days;
+ LOG4CXX_DEBUG(logger_,
+ "Exchange after: " << static_cast<int>(limit) << " days");
+
+ LOG4CXX_DEBUG(logger_, "Epoch since last update: " << *days_after_epoch);
+
+ const uint16_t actual =
+ std::max(static_cast<uint16_t>(current - *days_after_epoch), uint16_t(0));
+ LOG4CXX_DEBUG(logger_, "The days since last update: " << actual);
+
+ return std::max(limit - actual, 0);
+}
+
+void CacheManager::IncrementIgnitionCycles() {
+ CACHE_MANAGER_CHECK_VOID();
+ const int ign_val = static_cast<int>(
+ *pt_->policy_table.module_meta->ignition_cycles_since_last_exchange);
+ (*pt_->policy_table.module_meta->ignition_cycles_since_last_exchange) =
+ ign_val + 1;
+ LOG4CXX_DEBUG(logger_, "IncrementIgnitionCycles ignitions:" << ign_val);
+ Backup();
+}
+
+void CacheManager::ResetIgnitionCycles() {
+ CACHE_MANAGER_CHECK_VOID();
+ (*pt_->policy_table.module_meta->ignition_cycles_since_last_exchange) = 0;
+ Backup();
+}
+
+int CacheManager::TimeoutResponse() {
+ CACHE_MANAGER_CHECK(0);
+ return pt_->policy_table.module_config.timeout_after_x_seconds *
+ date_time::DateTime::MILLISECONDS_IN_SECOND;
+}
+
+bool CacheManager::SecondsBetweenRetries(std::vector<int>& seconds) {
+ CACHE_MANAGER_CHECK(false);
+ rpc::policy_table_interface_base::SecondsBetweenRetries::iterator iter =
+ pt_->policy_table.module_config.seconds_between_retries.begin();
+ rpc::policy_table_interface_base::SecondsBetweenRetries::iterator iter_end =
+ pt_->policy_table.module_config.seconds_between_retries.end();
+
+ const std::size_t size =
+ pt_->policy_table.module_config.seconds_between_retries.size();
+ seconds.reserve(size);
+ for (; iter != iter_end; ++iter) {
+ seconds.push_back(*iter);
+ }
+ return true;
+}
+
+const policy::VehicleInfo CacheManager::GetVehicleInfo() const {
+ CACHE_MANAGER_CHECK(VehicleInfo());
+ policy_table::ModuleConfig& module_config = pt_->policy_table.module_config;
+ VehicleInfo vehicle_info;
+ vehicle_info.vehicle_make = *module_config.vehicle_make;
+ vehicle_info.vehicle_model = *module_config.vehicle_model;
+ vehicle_info.vehicle_year = *module_config.vehicle_year;
+ LOG4CXX_DEBUG(
+ logger_,
+ "Vehicle info (make, model, year):" << vehicle_info.vehicle_make << ","
+ << vehicle_info.vehicle_model << ","
+ << vehicle_info.vehicle_year);
+ return vehicle_info;
+}
+
+std::vector<UserFriendlyMessage> CacheManager::GetUserFriendlyMsg(
+ const std::vector<std::string>& msg_codes, const std::string& language) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ std::vector<UserFriendlyMessage> result;
+ CACHE_MANAGER_CHECK(result);
+
+ std::vector<std::string>::const_iterator it = msg_codes.begin();
+ std::vector<std::string>::const_iterator it_end = msg_codes.end();
+ for (; it != it_end; ++it) {
+ policy_table::MessageLanguages msg_languages =
+ (*pt_->policy_table.consumer_friendly_messages->messages)[*it];
+
+ policy_table::MessageString message_string;
+
+ // If message has no records with required language, fallback language
+ // should be used instead.
+ LanguageFinder finder(language);
+ policy_table::Languages::const_iterator it_language = std::find_if(
+ msg_languages.languages.begin(), msg_languages.languages.end(), finder);
+
+ if (msg_languages.languages.end() == it_language) {
+ LOG4CXX_WARN(logger_,
+ "Language "
+ << language
+ << " haven't been found for message code: " << *it);
+
+ LanguageFinder fallback_language_finder("en-us");
+
+ policy_table::Languages::const_iterator it_fallback_language =
+ std::find_if(msg_languages.languages.begin(),
+ msg_languages.languages.end(),
+ fallback_language_finder);
+
+ if (msg_languages.languages.end() == it_fallback_language) {
+ LOG4CXX_ERROR(logger_,
+ "No fallback language found for message code: " << *it);
+ continue;
+ }
+
+ message_string = it_fallback_language->second;
+ } else {
+ message_string = it_language->second;
+ }
+
+ UserFriendlyMessage msg;
+ msg.message_code = *it;
+ result.push_back(msg);
+ }
+ return result;
+}
+
+void CacheManager::GetUpdateUrls(const uint32_t service_type,
+ EndpointUrls& out_end_points) {
+ std::stringstream service_type_stream;
+ service_type_stream << (service_type <= 9 ? "0x0" : "0x") << service_type;
+
+ const std::string service_type_str = service_type_stream.str();
+ GetUpdateUrls(service_type_str, out_end_points);
+}
+
+void CacheManager::GetUpdateUrls(const std::string& service_type,
+ EndpointUrls& out_end_points) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+
+ LOG4CXX_DEBUG(logger_, "Search service value is: " << service_type);
+
+ policy_table::ServiceEndpoints::const_iterator iter =
+ pt_->policy_table.module_config.endpoints.find(service_type);
+
+ if (pt_->policy_table.module_config.endpoints.end() != iter) {
+ policy_table::URLList::const_iterator url_list_iter =
+ (*iter).second.begin();
+ policy_table::URLList::const_iterator url_list_iter_end =
+ (*iter).second.end();
+ for (; url_list_iter != url_list_iter_end; ++url_list_iter) {
+ EndpointData data;
+ data.app_id = (*url_list_iter).first;
+ std::copy((*url_list_iter).second.begin(),
+ (*url_list_iter).second.end(),
+ std::back_inserter(data.url));
+
+ out_end_points.push_back(data);
+ }
+ }
+}
+
+std::string CacheManager::GetLockScreenIconUrl() const {
+ if (backup_) {
+ return backup_->GetLockScreenIconUrl();
+ }
+ return std::string("");
+}
+
+rpc::policy_table_interface_base::NumberOfNotificationsType
+CacheManager::GetNotificationsNumber(const std::string& priority) {
+ CACHE_MANAGER_CHECK(0);
+ typedef rpc::policy_table_interface_base::NumberOfNotificationsPerMinute NNPM;
+
+ const NNPM& nnpm =
+ pt_->policy_table.module_config.notifications_per_minute_by_priority;
+
+ NNPM::const_iterator priority_iter = nnpm.find(priority);
+
+ const rpc::policy_table_interface_base::NumberOfNotificationsType result =
+ (nnpm.end() != priority_iter ? (*priority_iter).second : 0u);
+ return result;
+}
+
+bool CacheManager::GetPriority(const std::string& policy_app_id,
+ std::string& priority) const {
+ CACHE_MANAGER_CHECK(false);
+ if (kDeviceId == policy_app_id) {
+ priority = EnumToJsonString(
+ pt_->policy_table.app_policies_section.device.priority);
+ return true;
+ }
+
+ const policy_table::ApplicationPolicies& policies =
+ pt_->policy_table.app_policies_section.apps;
+
+ policy_table::ApplicationPolicies::const_iterator policy_iter =
+ policies.find(policy_app_id);
+ const bool app_id_exists = policies.end() != policy_iter;
+ if (app_id_exists) {
+ priority = EnumToJsonString((*policy_iter).second.priority);
+ }
+
+ return app_id_exists;
+}
+
+void CacheManager::CheckSnapshotInitialization() {
+ CACHE_MANAGER_CHECK_VOID();
+ if (!snapshot_) {
+ LOG4CXX_ERROR(logger_, "Snapshot pointer is not initialized");
+ return;
+ }
+
+ *(snapshot_->policy_table.module_config.preloaded_pt) = false;
+
+ // SDL must not send certificate in snapshot
+ snapshot_->policy_table.module_config.certificate =
+ rpc::Optional<rpc::String<0, 65535> >();
+
+ rpc::Optional<policy_table::ModuleMeta>& module_meta =
+ snapshot_->policy_table.module_meta;
+ if (!module_meta->pt_exchanged_at_odometer_x->is_initialized()) {
+ *(module_meta->pt_exchanged_at_odometer_x) = 0;
+ }
+ if (!module_meta->ignition_cycles_since_last_exchange->is_initialized()) {
+ *(module_meta->ignition_cycles_since_last_exchange) = 0;
+ }
+ if (!module_meta->pt_exchanged_x_days_after_epoch->is_initialized()) {
+ *(module_meta->pt_exchanged_x_days_after_epoch) = 0;
+ }
+
+ /* consumer_friendly_messages are required for the snapshot;
+ * consumer_friendly_messages->version is required always, but
+ * consumer_friendly_messages->messages must be omitted in PTS */
+ if (snapshot_->policy_table.consumer_friendly_messages->is_initialized()) {
+ snapshot_->policy_table.consumer_friendly_messages->messages =
+ rpc::Optional<policy_table::Messages>();
+ } else {
+ LOG4CXX_WARN(logger_,
+ "policy_table.consumer_friendly_messages is not initialized");
+ }
+
+ /* policy_table.usage_and_error_counts are required for PTS and
+ * policy_table.usage_and_error_counts->app_level is optional */
+ rpc::Optional<policy_table::UsageAndErrorCounts>& usage_and_error_counts =
+ snapshot_->policy_table.usage_and_error_counts;
+
+ if (usage_and_error_counts->app_level->is_initialized()) {
+ policy_table::AppLevels::iterator it =
+ usage_and_error_counts->app_level->begin();
+ policy_table::AppLevels::const_iterator it_end =
+ usage_and_error_counts->app_level->end();
+ for (; it != it_end; ++it) {
+ if (!(*it).second.minutes_in_hmi_full.is_initialized()) {
+ (*it).second.minutes_in_hmi_full = 0;
+ }
+
+ if (!(*it).second.app_registration_language_gui.is_initialized()) {
+ (*it).second.app_registration_language_gui = "unknown";
+ }
+
+ if (!(*it).second.app_registration_language_vui.is_initialized()) {
+ (*it).second.app_registration_language_vui = "unknown";
+ }
+
+ if (!(*it).second.minutes_in_hmi_limited.is_initialized()) {
+ (*it).second.minutes_in_hmi_limited = 0;
+ }
+
+ if (!(*it).second.minutes_in_hmi_background.is_initialized()) {
+ (*it).second.minutes_in_hmi_background = 0;
+ }
+
+ if (!(*it).second.minutes_in_hmi_none.is_initialized()) {
+ (*it).second.minutes_in_hmi_none = 0;
+ }
+
+ if (!(*it).second.count_of_user_selections.is_initialized()) {
+ (*it).second.count_of_user_selections = 0;
+ }
+
+ if (!(*it)
+ .second.count_of_rejections_sync_out_of_memory
+ .is_initialized()) {
+ (*it).second.count_of_rejections_sync_out_of_memory = 0;
+ }
+
+ if (!(*it)
+ .second.count_of_rejections_nickname_mismatch.is_initialized()) {
+ (*it).second.count_of_rejections_nickname_mismatch = 0;
+ }
+
+ if (!(*it).second.count_of_rejections_duplicate_name.is_initialized()) {
+ (*it).second.count_of_rejections_duplicate_name = 0;
+ }
+
+ if (!(*it).second.count_of_rejected_rpc_calls.is_initialized()) {
+ (*it).second.count_of_rejected_rpc_calls = 0;
+ }
+
+ if (!(*it).second.count_of_rpcs_sent_in_hmi_none.is_initialized()) {
+ (*it).second.count_of_rpcs_sent_in_hmi_none = 0;
+ }
+
+ if (!(*it).second.count_of_removals_for_bad_behavior.is_initialized()) {
+ (*it).second.count_of_removals_for_bad_behavior = 0;
+ }
+
+ if (!(*it).second.count_of_tls_errors.is_initialized()) {
+ (*it).second.count_of_tls_errors = 0;
+ }
+
+ if (!(*it).second.count_of_run_attempts_while_revoked.is_initialized()) {
+ (*it).second.count_of_run_attempts_while_revoked = 0;
+ }
+ }
+ } else {
+ LOG4CXX_WARN(logger_, "app_level is not initialized");
+ }
+}
+
+void CacheManager::PersistData() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (backup_.valid()) {
+ if (pt_.valid()) {
+ cache_lock_.Acquire();
+ policy_table::Table copy_pt(*pt_);
+ cache_lock_.Release();
+
+ backup_->Save(copy_pt);
+ backup_->SaveUpdateRequired(update_required);
+
+ policy_table::ApplicationPolicies::const_iterator app_policy_iter =
+ copy_pt.policy_table.app_policies_section.apps.begin();
+ policy_table::ApplicationPolicies::const_iterator app_policy_iter_end =
+ copy_pt.policy_table.app_policies_section.apps.end();
+
+ bool is_revoked = false;
+ bool is_default_policy;
+ bool is_predata_policy;
+
+ for (; app_policy_iter != app_policy_iter_end; ++app_policy_iter) {
+ const std::string app_id = (*app_policy_iter).first;
+
+ if (copy_pt.policy_table.app_policies_section.apps.end() !=
+ copy_pt.policy_table.app_policies_section.apps.find(app_id)) {
+ is_revoked =
+ copy_pt.policy_table.app_policies_section.apps[app_id].is_null();
+ }
+
+ is_default_policy =
+ copy_pt.policy_table.app_policies_section.apps.end() !=
+ copy_pt.policy_table.app_policies_section.apps.find(app_id) &&
+ policy::kDefaultId ==
+ copy_pt.policy_table.app_policies_section.apps[app_id]
+ .get_string();
+
+ // TODO(AOleynik): Remove this field from DB
+ is_predata_policy =
+ copy_pt.policy_table.app_policies_section.apps.end() !=
+ copy_pt.policy_table.app_policies_section.apps.find(app_id) &&
+ policy::kPreDataConsentId ==
+ copy_pt.policy_table.app_policies_section.apps[app_id]
+ .get_string();
+
+ backup_->SaveApplicationCustomData(
+ app_id, is_revoked, is_default_policy, is_predata_policy);
+ is_revoked = false;
+ }
+
+ // In case of extended policy the meta info should be backuped as well.
+ backup_->WriteDb();
+ }
+ }
+}
+
+void CacheManager::ResetCalculatedPermissions() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(calculated_permissions_lock_);
+ calculated_permissions_.clear();
+}
+
+void CacheManager::AddCalculatedPermissions(const std::string& device_id,
+ const std::string& policy_app_id,
+ const Permissions& permissions) {
+ LOG4CXX_DEBUG(logger_,
+ "AddCalculatedPermissions for device: "
+ << device_id << " and app: " << policy_app_id);
+ sync_primitives::AutoLock lock(calculated_permissions_lock_);
+ calculated_permissions_[device_id][policy_app_id] = permissions;
+}
+
+bool CacheManager::IsPermissionsCalculated(const std::string& device_id,
+ const std::string& policy_app_id,
+ Permissions& permission) {
+ LOG4CXX_DEBUG(logger_,
+ "IsPermissionsCalculated for device: "
+ << device_id << " and app: " << policy_app_id);
+ sync_primitives::AutoLock lock(calculated_permissions_lock_);
+ CalculatedPermissions::const_iterator it =
+ calculated_permissions_.find(device_id);
+
+ if (calculated_permissions_.end() == it) {
+ return false;
+ }
+
+ AppCalculatedPermissions::const_iterator app_it =
+ (*it).second.find(policy_app_id);
+ if ((*it).second.end() == app_it) {
+ return false;
+ } else {
+ permission = (*app_it).second;
+ return true;
+ }
+ return false;
+}
+
+utils::SharedPtr<policy_table::Table> CacheManager::GenerateSnapshot() {
+ CACHE_MANAGER_CHECK(snapshot_);
+ sync_primitives::AutoLock lock(cache_lock_);
+
+ snapshot_ = new policy_table::Table();
+
+ // Copy all members of policy table except messages in consumer friendly
+ // messages
+ snapshot_->policy_table.app_policies_section =
+ pt_->policy_table.app_policies_section;
+ snapshot_->policy_table.functional_groupings =
+ pt_->policy_table.functional_groupings;
+ snapshot_->policy_table.consumer_friendly_messages->version =
+ pt_->policy_table.consumer_friendly_messages->version;
+ snapshot_->policy_table.consumer_friendly_messages->mark_initialized();
+ snapshot_->policy_table.module_config = pt_->policy_table.module_config;
+ snapshot_->policy_table.module_meta = pt_->policy_table.module_meta;
+ snapshot_->policy_table.usage_and_error_counts =
+ pt_->policy_table.usage_and_error_counts;
+ snapshot_->policy_table.device_data = pt_->policy_table.device_data;
+
+ // Set policy table type to Snapshot
+ snapshot_->SetPolicyTableType(
+ rpc::policy_table_interface_base::PolicyTableType::PT_SNAPSHOT);
+
+ CheckSnapshotInitialization();
+ return snapshot_;
+}
+
+bool CacheManager::GetInitialAppData(const std::string& app_id,
+ StringArray& nicknames,
+ StringArray& app_hmi_types) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(false);
+ policy_table::ApplicationPolicies::const_iterator policy_iter =
+ pt_->policy_table.app_policies_section.apps.find(app_id);
+
+ if (pt_->policy_table.app_policies_section.apps.end() != policy_iter) {
+ const policy_table::ApplicationParams& app_params = (*policy_iter).second;
+
+ std::copy(app_params.nicknames->begin(),
+ app_params.nicknames->end(),
+ std::back_inserter(nicknames));
+
+ std::transform(app_params.AppHMIType->begin(),
+ app_params.AppHMIType->end(),
+ std::back_inserter(app_hmi_types),
+ AppHMITypeToString());
+ }
+ return true;
+}
+
+bool CacheManager::GetFunctionalGroupings(
+ policy_table::FunctionalGroupings& groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(false);
+ const policy_table::FunctionalGroupings& f_groupings =
+ pt_->policy_table.functional_groupings;
+
+ groups.insert(f_groupings.begin(), f_groupings.end());
+ return true;
+}
+
+int CacheManager::CountUnconsentedGroups(const std::string& policy_app_id,
+ const std::string& device_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(false);
+ LOG4CXX_DEBUG(logger_, "Application id: " << policy_app_id);
+ int result = 0;
+ return result;
+}
+
+bool CacheManager::SetMetaInfo(const std::string& ccpu_version,
+ const std::string& wers_country_code,
+ const std::string& language) {
+ CACHE_MANAGER_CHECK(false);
+
+ // We have to set preloaded flag as false in policy table on any response
+ // of GetSystemInfo (SDLAQ-CRS-2365)
+ *pt_->policy_table.module_config.preloaded_pt = false;
+
+ Backup();
+ return true;
+}
+
+bool CacheManager::IsMetaInfoPresent() const {
+ CACHE_MANAGER_CHECK(false);
+ bool result = true;
+ return result;
+}
+
+bool CacheManager::SetSystemLanguage(const std::string& language) {
+ CACHE_MANAGER_CHECK(false);
+ Backup();
+ return true;
+}
+
+bool CacheManager::GetFunctionalGroupNames(FunctionalGroupNames& names) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK(false);
+ rpc::policy_table_interface_base::FunctionalGroupings::iterator iter =
+ pt_->policy_table.functional_groupings.begin();
+ rpc::policy_table_interface_base::FunctionalGroupings::iterator iter_end =
+ pt_->policy_table.functional_groupings.end();
+
+ for (; iter != iter_end; ++iter) {
+ const int32_t id = GenerateHash((*iter).first);
+ std::pair<std::string, std::string> value =
+ std::make_pair(*(*iter).second.user_consent_prompt, (*iter).first);
+
+ names.insert(
+ std::pair<uint32_t, std::pair<std::string, std::string> >(id, value));
+ }
+ return true;
+}
+
+bool CacheManager::CleanupUnpairedDevices() {
+ CACHE_MANAGER_CHECK(false);
+ Backup();
+ return true;
+}
+
+void CacheManager::Increment(usage_statistics::GlobalCounterId type) {
+ CACHE_MANAGER_CHECK_VOID();
+ Backup();
+}
+
+void CacheManager::Increment(const std::string& app_id,
+ usage_statistics::AppCounterId type) {
+ CACHE_MANAGER_CHECK_VOID();
+ sync_primitives::AutoLock lock(cache_lock_);
+ switch (type) {
+ case usage_statistics::USER_SELECTIONS:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_user_selections;
+ break;
+ case usage_statistics::REJECTIONS_SYNC_OUT_OF_MEMORY:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_rejections_sync_out_of_memory;
+ break;
+ case usage_statistics::REJECTIONS_NICKNAME_MISMATCH:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_rejections_nickname_mismatch;
+ break;
+ case usage_statistics::REJECTIONS_DUPLICATE_NAME:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_rejections_duplicate_name;
+ break;
+ case usage_statistics::REJECTED_RPC_CALLS:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_rejected_rpc_calls;
+ break;
+ case usage_statistics::RPCS_IN_HMI_NONE:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_rpcs_sent_in_hmi_none;
+ break;
+ case usage_statistics::REMOVALS_MISBEHAVED:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_removals_for_bad_behavior;
+ break;
+ case usage_statistics::RUN_ATTEMPTS_WHILE_REVOKED:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_run_attempts_while_revoked;
+ break;
+ case usage_statistics::COUNT_OF_TLS_ERRORS:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .count_of_tls_errors;
+ break;
+ default:
+ LOG4CXX_WARN(logger_, "Type app counter is unknown");
+ return;
+ }
+ Backup();
+}
+
+void CacheManager::Set(const std::string& app_id,
+ usage_statistics::AppInfoId type,
+ const std::string& value) {
+ CACHE_MANAGER_CHECK_VOID();
+ sync_primitives::AutoLock lock(cache_lock_);
+ switch (type) {
+ case usage_statistics::LANGUAGE_GUI:
+ (*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .app_registration_language_gui = value;
+ break;
+ case usage_statistics::LANGUAGE_VUI:
+ (*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .app_registration_language_vui = value;
+ break;
+ default:
+ LOG4CXX_WARN(logger_, "Type app info is unknown");
+ return;
+ }
+ Backup();
+}
+
+void CacheManager::Add(const std::string& app_id,
+ usage_statistics::AppStopwatchId type,
+ int seconds) {
+ CACHE_MANAGER_CHECK_VOID();
+ sync_primitives::AutoLock lock(cache_lock_);
+ const int minutes = ConvertSecondsToMinute(seconds);
+ switch (type) {
+ case usage_statistics::SECONDS_HMI_FULL:
+ (*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .minutes_in_hmi_full += minutes;
+ break;
+ case usage_statistics::SECONDS_HMI_LIMITED:
+ (*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .minutes_in_hmi_limited += minutes;
+ break;
+ case usage_statistics::SECONDS_HMI_BACKGROUND:
+ (*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .minutes_in_hmi_background += minutes;
+ break;
+ case usage_statistics::SECONDS_HMI_NONE:
+ (*pt_->policy_table.usage_and_error_counts->app_level)[app_id]
+ .minutes_in_hmi_none += minutes;
+ break;
+ default:
+ LOG4CXX_WARN(logger_, "Type app stopwatch is unknown");
+ return;
+ }
+ Backup();
+}
+
+long CacheManager::ConvertSecondsToMinute(int seconds) {
+ const float seconds_in_minute = 60.0;
+ return std::round(seconds / seconds_in_minute);
+}
+
+bool CacheManager::SetDefaultPolicy(const std::string& app_id) {
+ CACHE_MANAGER_CHECK(false);
+ sync_primitives::AutoLock lock(cache_lock_);
+ policy_table::ApplicationPolicies::const_iterator iter =
+ pt_->policy_table.app_policies_section.apps.find(kDefaultId);
+ if (pt_->policy_table.app_policies_section.apps.end() != iter) {
+ pt_->policy_table.app_policies_section.apps[app_id] =
+ pt_->policy_table.app_policies_section.apps[kDefaultId];
+
+ SetIsDefault(app_id);
+ }
+ Backup();
+ return true;
+}
+
+bool CacheManager::IsDefaultPolicy(const std::string& app_id) const {
+ CACHE_MANAGER_CHECK(false);
+ const bool result =
+ pt_->policy_table.app_policies_section.apps.end() !=
+ pt_->policy_table.app_policies_section.apps.find(app_id) &&
+ policy::kDefaultId ==
+ pt_->policy_table.app_policies_section.apps[app_id].get_string();
+
+ return result;
+}
+
+bool CacheManager::SetIsDefault(const std::string& app_id) {
+ CACHE_MANAGER_CHECK(false);
+ policy_table::ApplicationPolicies::const_iterator iter =
+ pt_->policy_table.app_policies_section.apps.find(app_id);
+ if (pt_->policy_table.app_policies_section.apps.end() != iter) {
+ pt_->policy_table.app_policies_section.apps[app_id].set_to_string(
+ kDefaultId);
+ }
+ return true;
+}
+
+bool CacheManager::SetPredataPolicy(const std::string& app_id) {
+ CACHE_MANAGER_CHECK(false);
+ sync_primitives::AutoLock lock(cache_lock_);
+ policy_table::ApplicationPolicies::const_iterator iter =
+ pt_->policy_table.app_policies_section.apps.find(kPreDataConsentId);
+
+ if (pt_->policy_table.app_policies_section.apps.end() == iter) {
+ LOG4CXX_ERROR(logger_,
+ "Could not set " << kPreDataConsentId
+ << " permissions for app " << app_id);
+ return false;
+ }
+
+ pt_->policy_table.app_policies_section.apps[app_id] =
+ pt_->policy_table.app_policies_section.apps[kPreDataConsentId];
+
+ pt_->policy_table.app_policies_section.apps[app_id].set_to_string(
+ kPreDataConsentId);
+
+ Backup();
+ return true;
+}
+
+bool CacheManager::IsPredataPolicy(const std::string& app_id) const {
+ // TODO(AOleynik): Maybe change for comparison with pre_DataConsent
+ // permissions or check string value from get_string()
+ if (!IsApplicationRepresented(app_id)) {
+ return false;
+ }
+
+ policy_table::ApplicationPolicies& apps =
+ pt_->policy_table.app_policies_section.apps;
+ const policy_table::ApplicationPolicies::mapped_type& pre_data_app =
+ apps[kPreDataConsentId];
+ const policy_table::ApplicationPolicies::mapped_type& specific_app =
+ apps[app_id];
+
+ policy_table::Strings res;
+ std::set_intersection(pre_data_app.groups.begin(),
+ pre_data_app.groups.end(),
+ specific_app.groups.begin(),
+ specific_app.groups.end(),
+ std::back_inserter(res));
+
+ const bool is_marked_as_predata =
+ (kPreDataConsentId == specific_app.get_string());
+
+ return !res.empty() && is_marked_as_predata;
+}
+
+bool CacheManager::SetUnpairedDevice(const std::string& device_id,
+ bool unpaired) {
+ const bool result = pt_->policy_table.device_data->end() !=
+ pt_->policy_table.device_data->find(device_id);
+ if (!result) {
+ LOG4CXX_DEBUG(logger_,
+ "Couldn't set unpaired flag for device id "
+ << device_id << " , since it wasn't found.");
+ return false;
+ }
+
+ sync_primitives::AutoLock lock(unpaired_lock_);
+ if (unpaired) {
+ is_unpaired_.insert(device_id);
+ LOG4CXX_DEBUG(logger_, "Unpaired flag was set for device id " << device_id);
+ } else {
+ is_unpaired_.erase(device_id);
+ LOG4CXX_DEBUG(logger_,
+ "Unpaired flag was removed for device id " << device_id);
+ }
+ return result;
+}
+
+bool CacheManager::SetVINValue(const std::string& value) {
+ CACHE_MANAGER_CHECK(false);
+ Backup();
+ return true;
+}
+
+bool CacheManager::IsApplicationRepresented(const std::string& app_id) const {
+ CACHE_MANAGER_CHECK(false);
+ if (kDeviceId == app_id) {
+ return true;
+ }
+ policy_table::ApplicationPolicies::const_iterator iter =
+ pt_->policy_table.app_policies_section.apps.find(app_id);
+ return pt_->policy_table.app_policies_section.apps.end() != iter;
+}
+
+bool CacheManager::Init(const std::string& file_name,
+ const PolicySettings* settings) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ settings_ = settings;
+ InitResult init_result = backup_->Init(settings);
+
+ bool result = true;
+ switch (init_result) {
+ case InitResult::EXISTS: {
+ LOG4CXX_INFO(logger_, "Policy Table exists, was loaded correctly.");
+ result = LoadFromBackup();
+ if (result) {
+ if (!backup_->IsDBVersionActual()) {
+ LOG4CXX_INFO(logger_, "DB version is NOT actual");
+ if (!backup_->RefreshDB()) {
+ LOG4CXX_ERROR(logger_, "RefreshDB() failed");
+ return false;
+ }
+ backup_->UpdateDBVersion();
+ Backup();
+ }
+ if (!MergePreloadPT(file_name)) {
+ result = false;
+ }
+ }
+ } break;
+ case InitResult::SUCCESS: {
+ LOG4CXX_INFO(logger_, "Policy Table was inited successfully");
+
+ result = LoadFromFile(file_name, *pt_);
+
+ utils::SharedPtr<policy_table::Table> snapshot = GenerateSnapshot();
+ result &= snapshot->is_valid();
+ LOG4CXX_DEBUG(logger_,
+ "Check if snapshot is valid: " << std::boolalpha << result);
+ if (!result) {
+ rpc::ValidationReport report("policy_table");
+ snapshot->ReportErrors(&report);
+ return result;
+ }
+
+ backup_->UpdateDBVersion();
+ Backup();
+ } break;
+ default: {
+ result = false;
+ LOG4CXX_ERROR(logger_, "Failed to init policy table.");
+ } break;
+ }
+
+ return result;
+}
+
+void CacheManager::FillDeviceSpecificData() {}
+
+bool CacheManager::LoadFromBackup() {
+ sync_primitives::AutoLock lock(cache_lock_);
+ pt_ = backup_->GenerateSnapshot();
+ update_required = backup_->UpdateRequired();
+
+ FillDeviceSpecificData();
+
+ return true;
+}
+
+bool CacheManager::LoadFromFile(const std::string& file_name,
+ policy_table::Table& table) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ BinaryMessage json_string;
+ if (!file_system::ReadBinaryFile(file_name, json_string)) {
+ LOG4CXX_FATAL(logger_, "Failed to read pt file.");
+ return false;
+ }
+
+ Json::Value value;
+ Json::Reader reader(Json::Features::strictMode());
+ std::string json(json_string.begin(), json_string.end());
+ if (!reader.parse(json.c_str(), value)) {
+ LOG4CXX_FATAL(
+ logger_,
+ "Preloaded PT is corrupted: " << reader.getFormattedErrorMessages());
+ return false;
+ }
+
+ LOG4CXX_TRACE(logger_, "Start create PT");
+ sync_primitives::AutoLock locker(cache_lock_);
+
+ table = policy_table::Table(&value);
+
+ Json::StyledWriter s_writer;
+ LOG4CXX_DEBUG(logger_, "PT out:");
+ LOG4CXX_DEBUG(logger_, s_writer.write(table.ToJsonValue()));
+
+ if (!table.is_valid()) {
+ rpc::ValidationReport report("policy_table");
+ table.ReportErrors(&report);
+ LOG4CXX_FATAL(logger_,
+ "Parsed table is not valid " << rpc::PrettyFormat(report));
+ return false;
+ }
+ return true;
+}
+
+bool CacheManager::ResetPT(const std::string& file_name) {
+ bool result = true;
+ Backup();
+ return result;
+}
+
+bool CacheManager::AppExists(const std::string& app_id) const {
+ CACHE_MANAGER_CHECK(false);
+ policy_table::ApplicationPolicies::iterator policy_iter =
+ pt_->policy_table.app_policies_section.apps.find(app_id);
+ return pt_->policy_table.app_policies_section.apps.end() != policy_iter;
+}
+
+int32_t CacheManager::GenerateHash(const std::string& str_to_hash) {
+ uint32_t hash = 5381U;
+ std::string::const_iterator it = str_to_hash.begin();
+ std::string::const_iterator it_end = str_to_hash.end();
+
+ for (; it != it_end; ++it) {
+ hash = ((hash << 5) + hash) + (*it);
+ }
+
+ // Reset sign bit in case it has been set.
+ // This is needed to avoid overflow for signed int.
+ const int32_t result = hash & 0x7FFFFFFF;
+ return result;
+}
+
+void CacheManager::GetAppRequestTypes(
+ const std::string& policy_app_id,
+ std::vector<std::string>& request_types) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ CACHE_MANAGER_CHECK_VOID();
+ if (kDeviceId == policy_app_id) {
+ LOG4CXX_DEBUG(logger_,
+ "Request types not applicable for app_id " << kDeviceId);
+ return;
+ }
+ policy_table::ApplicationPolicies::iterator policy_iter =
+ pt_->policy_table.app_policies_section.apps.find(policy_app_id);
+ if (pt_->policy_table.app_policies_section.apps.end() == policy_iter) {
+ LOG4CXX_DEBUG(logger_,
+ "Can't find request types for app_id " << policy_app_id);
+ return;
+ }
+ policy_table::RequestTypes::iterator it_request_type =
+ policy_iter->second.RequestType->begin();
+ for (; it_request_type != policy_iter->second.RequestType->end();
+ ++it_request_type) {
+ request_types.push_back(EnumToJsonString(*it_request_type));
+ }
+ return;
+}
+
+std::string CacheManager::GetCertificate() const {
+ CACHE_MANAGER_CHECK(std::string(""));
+ if (pt_->policy_table.module_config.certificate.is_initialized()) {
+ return *pt_->policy_table.module_config.certificate;
+ }
+ return std::string("");
+}
+
+bool CacheManager::MergePreloadPT(const std::string& file_name) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ policy_table::Table table;
+ if (!LoadFromFile(file_name, table)) {
+ LOG4CXX_DEBUG(logger_, "Unable to load preloaded PT.");
+ return false;
+ }
+
+ sync_primitives::AutoLock lock(cache_lock_);
+ policy_table::PolicyTable& current = pt_->policy_table;
+ policy_table::PolicyTable& new_table = table.policy_table;
+ const std::string date_current = *current.module_config.preloaded_date;
+ const std::string date_new = *new_table.module_config.preloaded_date;
+ if (date_current != date_new) {
+ MergeMC(new_table, current);
+ MergeFG(new_table, current);
+ MergeAP(new_table, current);
+ MergeCFM(new_table, current);
+ Backup();
+ }
+ return true;
+}
+
+void CacheManager::MergeMC(const policy_table::PolicyTable& new_pt,
+ policy_table::PolicyTable& pt) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ policy_table::ModuleConfig copy(pt.module_config);
+
+ pt.module_config = new_pt.module_config;
+ pt.module_config.vehicle_make = copy.vehicle_make;
+ pt.module_config.vehicle_year = copy.vehicle_year;
+ pt.module_config.vehicle_model = copy.vehicle_model;
+}
+
+void CacheManager::MergeFG(const policy_table::PolicyTable& new_pt,
+ policy_table::PolicyTable& pt) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ policy_table::FunctionalGroupings::const_iterator it =
+ new_pt.functional_groupings.begin();
+
+ for (; it != new_pt.functional_groupings.end(); ++it) {
+ LOG4CXX_DEBUG(logger_, "Merge functional group: " << it->first);
+ pt.functional_groupings[it->first] = it->second;
+ }
+}
+
+void CacheManager::MergeAP(const policy_table::PolicyTable& new_pt,
+ policy_table::PolicyTable& pt) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ pt.app_policies_section.device = const_cast<policy_table::PolicyTable&>(
+ new_pt).app_policies_section.device;
+
+ pt.app_policies_section.apps[kDefaultId] =
+ const_cast<policy_table::PolicyTable&>(new_pt)
+ .app_policies_section.apps[kDefaultId];
+
+ pt.app_policies_section.apps[kPreDataConsentId] =
+ const_cast<policy_table::PolicyTable&>(new_pt)
+ .app_policies_section.apps[kPreDataConsentId];
+}
+
+void CacheManager::MergeCFM(const policy_table::PolicyTable& new_pt,
+ policy_table::PolicyTable& pt) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (new_pt.consumer_friendly_messages.is_initialized()) {
+ if (!pt.consumer_friendly_messages.is_initialized()) {
+ pt.consumer_friendly_messages = new_pt.consumer_friendly_messages;
+ } else {
+ policy_table::Messages::const_iterator it =
+ new_pt.consumer_friendly_messages->messages->begin();
+
+ pt.consumer_friendly_messages->version =
+ new_pt.consumer_friendly_messages->version;
+ for (; it != new_pt.consumer_friendly_messages->messages->end(); ++it) {
+ LOG4CXX_DEBUG(logger_, "Merge CFM: " << it->first);
+ if (!(pt.consumer_friendly_messages->messages.is_initialized())) {
+ LOG4CXX_DEBUG(logger_, "CFM not initialized.");
+ }
+ (*pt.consumer_friendly_messages->messages)[it->first] = it->second;
+ }
+ }
+ }
+}
+
+const PolicySettings& CacheManager::get_settings() const {
+ DCHECK(settings_);
+
+ return *settings_;
+}
+
+CacheManager::BackgroundBackuper::BackgroundBackuper(
+ CacheManager* cache_manager)
+ : cache_manager_(cache_manager)
+ , stop_flag_(false)
+ , new_data_available_(false) {
+ LOG4CXX_AUTO_TRACE(logger_);
+}
+
+CacheManager::BackgroundBackuper::~BackgroundBackuper() {
+ LOG4CXX_AUTO_TRACE(logger_);
+}
+
+void CacheManager::BackgroundBackuper::InternalBackup() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ DCHECK(cache_manager_);
+
+ while (new_data_available_) {
+ new_data_available_ = false;
+ LOG4CXX_DEBUG(logger_, "DoBackup");
+ cache_manager_->PersistData();
+ }
+}
+
+void CacheManager::BackgroundBackuper::threadMain() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(need_backup_lock_);
+ while (!stop_flag_) {
+ need_backup_lock_.Release();
+ InternalBackup();
+ need_backup_lock_.Acquire();
+ if (new_data_available_ || stop_flag_) {
+ continue;
+ }
+ LOG4CXX_DEBUG(logger_, "Wait for a next backup");
+ backup_notifier_.Wait(need_backup_lock_);
+ }
+}
+
+void CacheManager::BackgroundBackuper::exitThreadMain() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(need_backup_lock_);
+ stop_flag_ = true;
+ backup_notifier_.NotifyOne();
+}
+
+void CacheManager::BackgroundBackuper::DoBackup() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(need_backup_lock_);
+ new_data_available_ = true;
+ backup_notifier_.NotifyOne();
+}
+
+} // namespace policy
diff --git a/src/components/policy/policy_regular/src/policy_helper.cc b/src/components/policy/policy_regular/src/policy_helper.cc
new file mode 100644
index 0000000000..b72a041a83
--- /dev/null
+++ b/src/components/policy/policy_regular/src/policy_helper.cc
@@ -0,0 +1,805 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <algorithm>
+#include <sstream>
+#include <string.h>
+#include "utils/logger.h"
+#include "utils/custom_string.h"
+#include "policy/policy_helper.h"
+#include "policy/policy_manager_impl.h"
+
+namespace policy {
+
+namespace custom_str = utils::custom_string;
+
+namespace {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Policy")
+
+bool Compare(const StringsValueType& first, const StringsValueType& second) {
+ const std::string& first_str = first;
+ const std::string& second_str = second;
+ return (strcasecmp(first_str.c_str(), second_str.c_str()) < 0);
+}
+
+struct CheckGroupName {
+ CheckGroupName(const policy::StringsValueType& value) : value_(value) {}
+
+ bool operator()(const FunctionalGroupNames::value_type& value) {
+ return value.second.second == std::string(value_);
+ }
+
+ private:
+ const policy::StringsValueType& value_;
+};
+
+struct CopyAttributes {
+ CopyAttributes(const FunctionalGroupNames& groups_attributes,
+ std::vector<FunctionalGroupPermission>& groups_permissions)
+ : groups_attributes_(groups_attributes)
+ , groups_permissions_(groups_permissions) {}
+
+ bool operator()(const policy::StringsValueType& value) {
+ CheckGroupName checker(value);
+ FunctionalGroupNames::const_iterator it = std::find_if(
+ groups_attributes_.begin(), groups_attributes_.end(), checker);
+ if (groups_attributes_.end() == it) {
+ return false;
+ }
+ FunctionalGroupPermission group;
+ group.group_name = it->second.second;
+ group.group_alias = it->second.first;
+ group.group_id = it->first;
+ groups_permissions_.push_back(group);
+ return true;
+ }
+
+ private:
+ const FunctionalGroupNames& groups_attributes_;
+ std::vector<FunctionalGroupPermission>& groups_permissions_;
+};
+} // namespace
+
+CompareGroupName::CompareGroupName(const StringsValueType& group_name)
+ : group_name_(group_name) {}
+
+bool CompareGroupName::operator()(
+ const StringsValueType& group_name_to_compare) const {
+ const std::string gn_ = group_name_;
+ const std::string gn_compare = group_name_to_compare;
+ return !(strcasecmp(gn_.c_str(), gn_compare.c_str()));
+}
+
+bool operator!=(const policy_table::ApplicationParams& first,
+ const policy_table::ApplicationParams& second) {
+ if (first.groups.size() != second.groups.size()) {
+ return true;
+ }
+ StringsConstItr it_first = first.groups.begin();
+ StringsConstItr it_first_end = first.groups.end();
+ StringsConstItr it_second = second.groups.begin();
+ StringsConstItr it_second_end = second.groups.end();
+ for (; it_first != it_first_end; ++it_first) {
+ CompareGroupName gp(*it_first);
+ StringsConstItr it = std::find_if(it_second, it_second_end, gp);
+ if (it_first_end == it) {
+ return true;
+ }
+ }
+ return false;
+}
+
+CheckAppPolicy::CheckAppPolicy(
+ PolicyManagerImpl* pm,
+ const utils::SharedPtr<policy_table::Table> update,
+ const utils::SharedPtr<policy_table::Table> snapshot)
+ : pm_(pm), update_(update), snapshot_(snapshot) {}
+
+bool policy::CheckAppPolicy::HasRevokedGroups(
+ const policy::AppPoliciesValueType& app_policy,
+ policy_table::Strings* revoked_groups) const {
+ AppPoliciesConstItr it =
+ snapshot_->policy_table.app_policies_section.apps.find(app_policy.first);
+
+ policy_table::Strings groups_new = app_policy.second.groups;
+ std::sort(groups_new.begin(), groups_new.end(), Compare);
+
+ policy_table::Strings groups_curr = (*it).second.groups;
+ std::sort(groups_curr.begin(), groups_curr.end(), Compare);
+
+ StringsConstItr it_groups_new = groups_new.begin();
+ StringsConstItr it_groups_new_end = groups_new.end();
+
+ StringsConstItr it_groups_curr = groups_curr.begin();
+ StringsConstItr it_groups_curr_end = groups_curr.end();
+
+ policy_table::Strings revoked_group_list;
+ std::set_difference(it_groups_curr,
+ it_groups_curr_end,
+ it_groups_new,
+ it_groups_new_end,
+ std::back_inserter(revoked_group_list),
+ Compare);
+
+ // Remove groups which are not required user consent
+ policy_table::Strings::iterator it_revoked = revoked_group_list.begin();
+ for (; revoked_group_list.end() != it_revoked;) {
+ if (!IsConsentRequired(app_policy.first, std::string(*it_revoked))) {
+ revoked_group_list.erase(it_revoked);
+ it_revoked = revoked_group_list.begin();
+ } else {
+ ++it_revoked;
+ }
+ }
+
+ if (revoked_groups) {
+ *revoked_groups = revoked_group_list;
+ }
+
+ return !revoked_group_list.empty();
+}
+
+bool policy::CheckAppPolicy::HasNewGroups(
+ const policy::AppPoliciesValueType& app_policy,
+ policy_table::Strings* new_groups) const {
+ AppPoliciesConstItr it =
+ snapshot_->policy_table.app_policies_section.apps.find(app_policy.first);
+
+ policy_table::Strings groups_new = app_policy.second.groups;
+ std::sort(groups_new.begin(), groups_new.end(), Compare);
+
+ policy_table::Strings groups_curr = (*it).second.groups;
+ std::sort(groups_curr.begin(), groups_curr.end(), Compare);
+
+ StringsConstItr it_groups_new = groups_new.begin();
+ StringsConstItr it_groups_new_end = groups_new.end();
+
+ StringsConstItr it_groups_curr = groups_curr.begin();
+ StringsConstItr it_groups_curr_end = groups_curr.end();
+
+ policy_table::Strings new_group_list;
+ std::set_difference(it_groups_new,
+ it_groups_new_end,
+ it_groups_curr,
+ it_groups_curr_end,
+ std::back_inserter(new_group_list),
+ Compare);
+
+ if (new_groups) {
+ *new_groups = new_group_list;
+ }
+
+ return !new_group_list.empty();
+}
+
+bool policy::CheckAppPolicy::HasConsentNeededGroups(
+ const policy::AppPoliciesValueType& app_policy) const {
+ policy_table::Strings new_groups;
+ if (!HasNewGroups(app_policy, &new_groups)) {
+ return false;
+ }
+
+ StringsConstItr it_new = new_groups.begin();
+ StringsConstItr it_new_end = new_groups.end();
+ for (; it_new != it_new_end; ++it_new) {
+ if (IsConsentRequired(app_policy.first, *it_new)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+std::vector<FunctionalGroupPermission> policy::CheckAppPolicy::GetRevokedGroups(
+ const policy::AppPoliciesValueType& app_policy) const {
+ policy_table::Strings revoked_groups_names;
+ if (!HasRevokedGroups(app_policy, &revoked_groups_names)) {
+ return std::vector<FunctionalGroupPermission>();
+ }
+
+ FunctionalGroupNames groups_attributes;
+ if (!pm_->cache_->GetFunctionalGroupNames(groups_attributes)) {
+ LOG4CXX_WARN(logger_, "Can't get functional group names");
+ return std::vector<FunctionalGroupPermission>();
+ }
+
+ std::vector<FunctionalGroupPermission> revoked_groups_permissions;
+ CopyAttributes copier(groups_attributes, revoked_groups_permissions);
+ std::for_each(
+ revoked_groups_names.begin(), revoked_groups_names.end(), copier);
+
+ return revoked_groups_permissions;
+}
+
+void policy::CheckAppPolicy::RemoveRevokedConsents(
+ const AppPoliciesValueType& app_policy,
+ const std::vector<FunctionalGroupPermission>& revoked_groups) const {
+ std::vector<policy::FunctionalGroupPermission>::const_iterator it =
+ revoked_groups.begin();
+ std::vector<policy::FunctionalGroupPermission>::const_iterator it_end =
+ revoked_groups.end();
+ for (; it != it_end; ++it) {
+ pm_->RemoveAppConsentForGroup(app_policy.first, it->group_name);
+ }
+}
+
+bool CheckAppPolicy::IsKnownAppication(
+ const std::string& application_id) const {
+ const policy_table::ApplicationPolicies& current_policies =
+ snapshot_->policy_table.app_policies_section.apps;
+
+ return !(current_policies.end() == current_policies.find(application_id));
+}
+
+void policy::CheckAppPolicy::NotifySystem(
+ const policy::AppPoliciesValueType& app_policy) const {
+ pm_->listener()->OnPendingPermissionChange(app_policy.first);
+}
+
+void CheckAppPolicy::SendPermissionsToApp(
+ const AppPoliciesValueType& app_policy) const {
+ const std::string app_id = app_policy.first;
+
+ const std::string device_id = pm_->GetCurrentDeviceId(app_id);
+ if (device_id.empty()) {
+ LOG4CXX_WARN(logger_,
+ "Couldn't find device info for application id: " << app_id);
+ return;
+ }
+ std::vector<FunctionalGroupPermission> group_permissons;
+ pm_->GetPermissionsForApp(device_id, app_id, group_permissons);
+
+ Permissions notification_data;
+ pm_->PrepareNotificationData(update_->policy_table.functional_groupings,
+ app_policy.second.groups,
+ group_permissons,
+ notification_data);
+
+ LOG4CXX_INFO(logger_, "Send notification for application_id: " << app_id);
+ // Default_hmi is Ford-specific and should not be used with basic policy
+ const std::string default_hmi;
+ pm_->listener()->OnPermissionsUpdated(app_id, notification_data, default_hmi);
+}
+
+bool CheckAppPolicy::IsAppRevoked(
+ const AppPoliciesValueType& app_policy) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ // Application params are not initialized = application revoked
+ // i.e. "123":null
+ return app_policy.second.is_null();
+}
+
+bool CheckAppPolicy::NicknamesMatch(
+ const AppPoliciesValueType& app_policy) const {
+ const std::string& app_id = app_policy.first;
+ const custom_str::CustomString app_name = pm_->listener()->GetAppName(app_id);
+ if (!app_name.empty() && app_policy.second.nicknames &&
+ !app_policy.second.nicknames->empty()) {
+ for (policy_table::Strings::const_iterator it =
+ app_policy.second.nicknames->begin();
+ app_policy.second.nicknames->end() != it;
+ ++it) {
+ std::string temp = *it;
+ if (app_name.CompareIgnoreCase(temp.c_str())) {
+ return true;
+ }
+ }
+ return false;
+ }
+ return true;
+}
+
+bool CheckAppPolicy::operator()(const AppPoliciesValueType& app_policy) {
+ const std::string app_id = app_policy.first;
+
+ if (!IsKnownAppication(app_id)) {
+ LOG4CXX_WARN(logger_,
+ "Application:" << app_id << " is not present in snapshot.");
+ return true;
+ }
+
+ if (!IsPredefinedApp(app_policy) && IsAppRevoked(app_policy)) {
+ SetPendingPermissions(app_policy, RESULT_APP_REVOKED);
+ NotifySystem(app_policy);
+ return true;
+ }
+
+ if (!IsPredefinedApp(app_policy) && !NicknamesMatch(app_policy)) {
+ SetPendingPermissions(app_policy, RESULT_NICKNAME_MISMATCH);
+ NotifySystem(app_policy);
+ return true;
+ }
+
+ PermissionsCheckResult result = CheckPermissionsChanges(app_policy);
+ if (!IsPredefinedApp(app_policy) && IsRequestTypeChanged(app_policy)) {
+ SetPendingPermissions(app_policy, RESULT_REQUEST_TYPE_CHANGED);
+ NotifySystem(app_policy);
+ }
+ if (RESULT_NO_CHANGES == result) {
+ LOG4CXX_INFO(logger_,
+ "Permissions for application:" << app_id
+ << " wasn't changed.");
+ return true;
+ }
+
+ LOG4CXX_INFO(logger_,
+ "Permissions for application:" << app_id
+ << " have been changed.");
+
+ if (!IsPredefinedApp(app_policy) && RESULT_CONSENT_NOT_REQIURED != result) {
+ SetPendingPermissions(app_policy, result);
+ NotifySystem(app_policy);
+ }
+
+ // Don't sent notification for predefined apps (e.g. default, device etc.)
+ if (!IsPredefinedApp(app_policy)) {
+ SendPermissionsToApp(app_policy);
+ }
+ return true;
+}
+
+void policy::CheckAppPolicy::SetPendingPermissions(
+ const AppPoliciesValueType& app_policy,
+ PermissionsCheckResult result) const {
+ const std::string app_id = app_policy.first;
+ AppPermissions permissions_diff(app_id);
+ permissions_diff.priority =
+ policy_table::EnumToJsonString(app_policy.second.priority);
+
+ switch (result) {
+ case RESULT_APP_REVOKED:
+ permissions_diff.appRevoked = true;
+ break;
+ case RESULT_NICKNAME_MISMATCH:
+ permissions_diff.appUnauthorized = true;
+ break;
+ case RESULT_PERMISSIONS_REVOKED:
+ permissions_diff.isAppPermissionsRevoked = true;
+ permissions_diff.appRevokedPermissions = GetRevokedGroups(app_policy);
+ RemoveRevokedConsents(app_policy, permissions_diff.appRevokedPermissions);
+ break;
+ case RESULT_CONSENT_NEEDED:
+ permissions_diff.appPermissionsConsentNeeded = true;
+ break;
+ case RESULT_PERMISSIONS_REVOKED_AND_CONSENT_NEEDED:
+ permissions_diff.isAppPermissionsRevoked = true;
+ permissions_diff.appPermissionsConsentNeeded = true;
+ permissions_diff.appRevokedPermissions = GetRevokedGroups(app_policy);
+ RemoveRevokedConsents(app_policy, permissions_diff.appRevokedPermissions);
+ break;
+ case RESULT_REQUEST_TYPE_CHANGED:
+ permissions_diff.priority.clear();
+ permissions_diff.requestTypeChanged = true;
+ {
+ // Getting RequestTypes from PTU (not from cache)
+ policy_table::RequestTypes::const_iterator it_request_type =
+ app_policy.second.RequestType->begin();
+ for (; app_policy.second.RequestType->end() != it_request_type;
+ ++it_request_type) {
+ permissions_diff.requestType.push_back(
+ EnumToJsonString(*it_request_type));
+ }
+ }
+
+ break;
+ default:
+ return;
+ }
+ pm_->app_permissions_diff_lock_.Acquire();
+ pm_->app_permissions_diff_.insert(std::make_pair(app_id, permissions_diff));
+ pm_->app_permissions_diff_lock_.Release();
+}
+
+policy::CheckAppPolicy::PermissionsCheckResult
+policy::CheckAppPolicy::CheckPermissionsChanges(
+ const policy::AppPoliciesValueType& app_policy) const {
+ bool has_revoked_groups = HasRevokedGroups(app_policy);
+
+ bool has_consent_needed_groups = HasConsentNeededGroups(app_policy);
+
+ bool has_new_groups = HasNewGroups(app_policy);
+
+ if (has_revoked_groups && has_consent_needed_groups) {
+ return RESULT_PERMISSIONS_REVOKED_AND_CONSENT_NEEDED;
+ } else if (has_revoked_groups) {
+ return RESULT_PERMISSIONS_REVOKED;
+ } else if (has_consent_needed_groups) {
+ return RESULT_CONSENT_NEEDED;
+ } else if (has_new_groups) {
+ return RESULT_CONSENT_NOT_REQIURED;
+ }
+
+ return RESULT_NO_CHANGES;
+}
+
+bool CheckAppPolicy::IsConsentRequired(const std::string& app_id,
+ const std::string& group_name) const {
+ const policy_table::FunctionalGroupings& functional_groupings =
+ snapshot_->policy_table.functional_groupings;
+
+ FuncGroupConstItr it = functional_groupings.find(group_name);
+
+ if (functional_groupings.end() == it) {
+ return false;
+ }
+
+ bool is_preconsented = false;
+ return it->second.user_consent_prompt.is_initialized() && !is_preconsented;
+}
+
+bool CheckAppPolicy::IsRequestTypeChanged(
+ const AppPoliciesValueType& app_policy) const {
+ policy::AppPoliciesConstItr it =
+ snapshot_->policy_table.app_policies_section.apps.find(app_policy.first);
+ if (it == snapshot_->policy_table.app_policies_section.apps.end()) {
+ if (!app_policy.second.RequestType->empty()) {
+ return true;
+ }
+ return false;
+ }
+ if (it->second.RequestType->size() != app_policy.second.RequestType->size()) {
+ return true;
+ }
+ policy_table::RequestTypes diff;
+ std::set_difference(it->second.RequestType->begin(),
+ it->second.RequestType->end(),
+ app_policy.second.RequestType->begin(),
+ app_policy.second.RequestType->end(),
+ std::back_inserter(diff));
+ return diff.size();
+}
+
+FillNotificationData::FillNotificationData(Permissions& data,
+ GroupConsent group_state,
+ GroupConsent undefined_group_consent)
+ : data_(data) {
+ switch (group_state) {
+ case kGroupAllowed:
+ current_key_ = kAllowedKey;
+ break;
+ case kGroupUndefined:
+ if (kGroupUndefined == undefined_group_consent) {
+ current_key_ = kUndefinedKey;
+ break;
+ }
+ current_key_ = kGroupAllowed == undefined_group_consent
+ ? kAllowedKey
+ : kUserDisallowedKey;
+ break;
+ default:
+ current_key_ = kUserDisallowedKey;
+ break;
+ }
+}
+
+bool FillNotificationData::operator()(const RpcValueType& rpc) {
+ Permissions::iterator it = data_.find(rpc.first);
+ // If rpc is present already - update its permissions
+ if (data_.end() != it) {
+ UpdateHMILevels(rpc.second.hmi_levels,
+ (*it).second.hmi_permissions[current_key_]);
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ UpdateParameters(*rpc.second.parameters,
+ (*it).second.parameter_permissions[current_key_]);
+ ExcludeSame();
+ } else {
+ // Init mandatory keys, since they should be present irrespectively of
+ // values presence
+ InitRpcKeys(rpc.first);
+ // If rpc is not present - add its permissions
+ UpdateHMILevels(rpc.second.hmi_levels,
+ data_[rpc.first].hmi_permissions[current_key_]);
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ UpdateParameters(*rpc.second.parameters,
+ data_[rpc.first].parameter_permissions[current_key_]);
+ ExcludeSame();
+ }
+ return true;
+}
+
+void FillNotificationData::UpdateHMILevels(
+ const policy_table::HmiLevels& in_hmi, std::set<HMILevel>& out_hmi) {
+ HMILevelsConstItr it_hmi_levels = in_hmi.begin();
+ HMILevelsConstItr it_hmi_levels_end = in_hmi.end();
+
+ for (; it_hmi_levels != it_hmi_levels_end; ++it_hmi_levels) {
+ out_hmi.insert(policy_table::EnumToJsonString(*it_hmi_levels));
+ }
+}
+
+void FillNotificationData::UpdateParameters(
+ const policy_table::Parameters& in_parameters,
+ std::set<Parameter>& out_parameter) {
+ ParametersConstItr it_parameters = in_parameters.begin();
+ ParametersConstItr it_parameters_end = in_parameters.end();
+
+ for (; it_parameters != it_parameters_end; ++it_parameters) {
+ out_parameter.insert(policy_table::EnumToJsonString(*it_parameters));
+ }
+}
+
+void FillNotificationData::ExcludeSame() {
+ Permissions::iterator it = data_.begin();
+ Permissions::const_iterator it_end = data_.end();
+ // Groups
+ for (; it != it_end; ++it) {
+ HMIPermissions& rpc_hmi_permissions = (*it).second.hmi_permissions;
+ HMIPermissions::const_iterator it_hmi_allowed =
+ (*it).second.hmi_permissions.find(kAllowedKey);
+ HMIPermissions::const_iterator it_hmi_undefined =
+ (*it).second.hmi_permissions.find(kUndefinedKey);
+ HMIPermissions::const_iterator it_hmi_user_disallowed =
+ (*it).second.hmi_permissions.find(kUserDisallowedKey);
+
+ ParameterPermissions& rpc_parameter_permissions =
+ (*it).second.parameter_permissions;
+ ParameterPermissions::const_iterator it_parameter_allowed =
+ (*it).second.parameter_permissions.find(kAllowedKey);
+ ParameterPermissions::const_iterator it_parameter_undefined =
+ (*it).second.parameter_permissions.find(kUndefinedKey);
+ ParameterPermissions::const_iterator it_parameter_user_disallowed =
+ (*it).second.parameter_permissions.find(kUserDisallowedKey);
+
+ // First, remove disallowed from other types
+ if (rpc_hmi_permissions.end() != it_hmi_user_disallowed) {
+ if (rpc_hmi_permissions.end() != it_hmi_allowed) {
+ ExcludeSameHMILevels(rpc_hmi_permissions[kAllowedKey],
+ rpc_hmi_permissions[kUserDisallowedKey]);
+ }
+ if (rpc_hmi_permissions.end() != it_hmi_undefined) {
+ ExcludeSameHMILevels(rpc_hmi_permissions[kUndefinedKey],
+ rpc_hmi_permissions[kUserDisallowedKey]);
+ }
+ }
+
+ if (rpc_parameter_permissions.end() != it_parameter_user_disallowed) {
+ if (rpc_parameter_permissions.end() != it_parameter_allowed) {
+ ExcludeSameParameters(rpc_parameter_permissions[kAllowedKey],
+ rpc_parameter_permissions[kUserDisallowedKey]);
+ }
+ if (rpc_parameter_permissions.end() != it_parameter_undefined) {
+ ExcludeSameParameters(rpc_parameter_permissions[kUndefinedKey],
+ rpc_parameter_permissions[kUserDisallowedKey]);
+ }
+ }
+
+ // Then, remove undefined from allowed
+ if (rpc_hmi_permissions.end() != it_hmi_undefined) {
+ if (rpc_hmi_permissions.end() != it_hmi_allowed) {
+ ExcludeSameHMILevels(rpc_hmi_permissions[kAllowedKey],
+ rpc_hmi_permissions[kUndefinedKey]);
+ }
+ }
+
+ if (rpc_parameter_permissions.end() != it_parameter_undefined) {
+ if (rpc_parameter_permissions.end() != it_parameter_allowed) {
+ ExcludeSameParameters(rpc_parameter_permissions[kAllowedKey],
+ rpc_parameter_permissions[kUndefinedKey]);
+ }
+ }
+ }
+}
+
+void FillNotificationData::ExcludeSameHMILevels(
+ std::set<HMILevel>& source, const std::set<HMILevel>& target) {
+ std::set<HMILevel> diff_hmi;
+
+ std::set_difference(source.begin(),
+ source.end(),
+ target.begin(),
+ target.end(),
+ std::inserter(diff_hmi, diff_hmi.begin()));
+
+ source = diff_hmi;
+}
+
+void FillNotificationData::ExcludeSameParameters(
+ std::set<Parameter>& source, const std::set<Parameter>& target) {
+ std::set<Parameter> diff_parameter;
+
+ std::set_difference(source.begin(),
+ source.end(),
+ target.begin(),
+ target.end(),
+ std::inserter(diff_parameter, diff_parameter.begin()));
+
+ source = diff_parameter;
+}
+
+void FillNotificationData::InitRpcKeys(const std::string& rpc_name) {
+ data_[rpc_name].hmi_permissions[kAllowedKey];
+ data_[rpc_name].hmi_permissions[kUserDisallowedKey];
+ data_[rpc_name].parameter_permissions[kAllowedKey];
+ data_[rpc_name].parameter_permissions[kUserDisallowedKey];
+}
+
+ProcessFunctionalGroup::ProcessFunctionalGroup(
+ const policy_table::FunctionalGroupings& fg,
+ const std::vector<FunctionalGroupPermission>& group_permissions,
+ Permissions& data,
+ GroupConsent undefined_group_consent)
+ : fg_(fg)
+ , group_permissions_(group_permissions)
+ , data_(data)
+ , undefined_group_consent_(undefined_group_consent) {}
+
+bool ProcessFunctionalGroup::operator()(const StringsValueType& group_name) {
+ const std::string group_name_str = group_name;
+ FuncGroupConstItr it = fg_.find(group_name_str);
+
+ if (fg_.end() != it) {
+ const policy_table::Rpc& rpcs = (*it).second.rpcs;
+ FillNotificationData filler(
+ data_, GetGroupState(group_name_str), undefined_group_consent_);
+ std::for_each(rpcs.begin(), rpcs.end(), filler);
+ }
+ return true;
+}
+
+GroupConsent ProcessFunctionalGroup::GetGroupState(
+ const std::string& group_name) {
+ std::vector<FunctionalGroupPermission>::const_iterator it =
+ group_permissions_.begin();
+ std::vector<FunctionalGroupPermission>::const_iterator it_end =
+ group_permissions_.end();
+ for (; it != it_end; ++it) {
+ if (group_name == (*it).group_name) {
+ return (*it).state;
+ }
+ }
+ return kGroupUndefined;
+}
+
+FunctionalGroupInserter::FunctionalGroupInserter(
+ const policy_table::Strings& preconsented_groups, PermissionsList& list)
+ : list_(list), preconsented_(preconsented_groups) {}
+
+void FunctionalGroupInserter::operator()(const StringsValueType& group_name) {
+ CompareGroupName name(group_name);
+ if (std::find_if(preconsented_.begin(), preconsented_.end(), name) ==
+ preconsented_.end()) {
+ list_.push_back(group_name);
+ }
+}
+
+void FillFunctionalGroupPermissions(
+ FunctionalGroupIDs& ids,
+ FunctionalGroupNames& names,
+ GroupConsent state,
+ std::vector<FunctionalGroupPermission>& permissions) {
+ LOG4CXX_INFO(logger_, "FillFunctionalGroupPermissions");
+ FunctionalGroupIDs::const_iterator it = ids.begin();
+ FunctionalGroupIDs::const_iterator it_end = ids.end();
+ for (; it != it_end; ++it) {
+ FunctionalGroupPermission current_group;
+ current_group.group_id = *it;
+ current_group.group_alias = names[*it].first;
+ current_group.group_name = names[*it].second;
+ current_group.state = state;
+ permissions.push_back(current_group);
+ }
+}
+
+bool IsPredefinedApp(const AppPoliciesValueType& app) {
+ return app.first == kDefaultId || app.first == kPreDataConsentId ||
+ app.first == kDeviceId;
+}
+
+FunctionalGroupIDs ExcludeSame(const FunctionalGroupIDs& from,
+ const FunctionalGroupIDs& what) {
+ LOG4CXX_INFO(logger_, "Exclude same groups");
+ FunctionalGroupIDs from_copy(from);
+ FunctionalGroupIDs what_copy(what);
+
+ std::sort(from_copy.begin(), from_copy.end());
+ std::sort(what_copy.begin(), what_copy.end());
+
+ FunctionalGroupIDs no_same;
+ std::set_difference(from_copy.begin(),
+ from_copy.end(),
+ what_copy.begin(),
+ what_copy.end(),
+ std::back_inserter(no_same));
+
+ no_same.resize(std::distance(no_same.begin(),
+ std::unique(no_same.begin(), no_same.end())));
+
+ return no_same;
+}
+
+FunctionalGroupIDs Merge(const FunctionalGroupIDs& first,
+ const FunctionalGroupIDs& second) {
+ LOG4CXX_INFO(logger_, "Merge groups");
+ FunctionalGroupIDs first_copy(first);
+ FunctionalGroupIDs second_copy(second);
+
+ std::sort(first_copy.begin(), first_copy.end());
+ std::sort(second_copy.begin(), second_copy.end());
+
+ FunctionalGroupIDs merged;
+ std::set_union(first_copy.begin(),
+ first_copy.end(),
+ second_copy.begin(),
+ second_copy.end(),
+ std::back_inserter(merged));
+
+ merged.resize(
+ std::distance(merged.begin(), std::unique(merged.begin(), merged.end())));
+
+ return merged;
+}
+
+FunctionalGroupIDs FindSame(const FunctionalGroupIDs& first,
+ const FunctionalGroupIDs& second) {
+ LOG4CXX_INFO(logger_, "Find same groups");
+ FunctionalGroupIDs first_copy(first);
+ FunctionalGroupIDs second_copy(second);
+
+ std::sort(first_copy.begin(), first_copy.end());
+ std::sort(second_copy.begin(), second_copy.end());
+
+ FunctionalGroupIDs same;
+ std::set_intersection(first_copy.begin(),
+ first_copy.end(),
+ second_copy.begin(),
+ second_copy.end(),
+ std::back_inserter(same));
+
+ same.resize(
+ std::distance(same.begin(), std::unique(same.begin(), same.end())));
+
+ return same;
+}
+
+bool UnwrapAppPolicies(policy_table::ApplicationPolicies& app_policies) {
+ policy_table::ApplicationPolicies::iterator it = app_policies.begin();
+ policy_table::ApplicationPolicies::iterator it_default =
+ app_policies.find(kDefaultId);
+ for (; app_policies.end() != it; ++it) {
+ // Set default policies for app, if there is record like "123":"default"
+ if (kDefaultId.compare((*it).second.get_string()) == 0) {
+ if (it != app_policies.end()) {
+ (*it).second = (*it_default).second;
+ it->second.set_to_string(kDefaultId);
+ } else {
+ LOG4CXX_ERROR(logger_,
+ "There is no default application policy was "
+ "found in PTU.");
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+}
diff --git a/src/components/policy/policy_regular/src/policy_manager_impl.cc b/src/components/policy/policy_regular/src/policy_manager_impl.cc
new file mode 100644
index 0000000000..f05ac9cb67
--- /dev/null
+++ b/src/components/policy/policy_regular/src/policy_manager_impl.cc
@@ -0,0 +1,1130 @@
+/*
+ Copyright (c) 2016, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "policy/policy_manager_impl.h"
+
+#include <algorithm>
+#include <set>
+#include <queue>
+#include <iterator>
+#include <limits>
+#include "json/reader.h"
+#include "json/writer.h"
+#include "policy/policy_table.h"
+#include "policy/pt_representation.h"
+#include "policy/policy_helper.h"
+#include "utils/file_system.h"
+#include "utils/logger.h"
+#include "utils/date_time.h"
+#include "utils/make_shared.h"
+#include "policy/cache_manager.h"
+#include "policy/update_status_manager.h"
+#include "config_profile/profile.h"
+#include "utils/timer_task_impl.h"
+#include "utils/make_shared.h"
+
+policy::PolicyManager* CreateManager() {
+ return new policy::PolicyManagerImpl();
+}
+void DeleteManager(policy::PolicyManager* pm) {
+ delete pm;
+}
+
+namespace {
+const uint32_t kDefaultRetryTimeoutInMSec =
+ 60u * date_time::DateTime::MILLISECONDS_IN_SECOND;
+} // namespace
+
+namespace policy {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Policy")
+
+PolicyManagerImpl::PolicyManagerImpl()
+ : PolicyManager()
+ , listener_(NULL)
+ , cache_(new CacheManager)
+ , retry_sequence_timeout_(kDefaultRetryTimeoutInMSec)
+ , retry_sequence_index_(0)
+ , timer_retry_sequence_("Retry sequence timer",
+ new timer::TimerTaskImpl<PolicyManagerImpl>(
+ this, &PolicyManagerImpl::RetrySequence))
+ , ignition_check(true)
+ , retry_sequence_url_(0, 0, "")
+ , wrong_ptu_update_received_(false)
+ , send_on_update_sent_out_(false)
+ , trigger_ptu_(false) {}
+
+void PolicyManagerImpl::set_listener(PolicyListener* listener) {
+ listener_ = listener;
+ update_status_manager_.set_listener(listener);
+}
+
+#ifdef USE_HMI_PTU_DECRYPTION
+
+utils::SharedPtr<policy_table::Table> PolicyManagerImpl::Parse(
+ const BinaryMessage& pt_content) {
+ std::string json(pt_content.begin(), pt_content.end());
+ Json::Value value;
+ Json::Reader reader;
+ if (reader.parse(json.c_str(), value)) {
+ return new policy_table::Table(&value);
+ } else {
+ return utils::SharedPtr<policy_table::Table>();
+ }
+}
+
+#else
+
+utils::SharedPtr<policy_table::Table> PolicyManagerImpl::ParseArray(
+ const BinaryMessage& pt_content) {
+ std::string json(pt_content.begin(), pt_content.end());
+ Json::Value value;
+ Json::Reader reader;
+ if (reader.parse(json.c_str(), value)) {
+ // For PT Update received from SDL Server.
+ if (value["data"].size() != 0) {
+ Json::Value data = value["data"];
+ return new policy_table::Table(&data[0]);
+ } else {
+ return new policy_table::Table(&value);
+ }
+ } else {
+ return utils::SharedPtr<policy_table::Table>();
+ }
+}
+
+#endif
+
+void PolicyManagerImpl::CheckTriggers() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const bool exceed_ignition_cycles = ExceededIgnitionCycles();
+ const bool exceed_days = ExceededDays();
+
+ LOG4CXX_DEBUG(
+ logger_,
+ "\nDays exceeded: " << std::boolalpha << exceed_days
+ << "\nIgnition cycles exceeded: " << std::boolalpha
+ << exceed_ignition_cycles);
+
+ if (exceed_ignition_cycles || exceed_days) {
+ update_status_manager_.ScheduleUpdate();
+ }
+}
+
+bool PolicyManagerImpl::LoadPT(const std::string& file,
+ const BinaryMessage& pt_content) {
+ LOG4CXX_INFO(logger_, "LoadPT of size " << pt_content.size());
+
+#ifdef USE_HMI_PTU_DECRYPTION
+ // Assuemes Policy Table was parsed, formatted, and/or decrypted by
+ // the HMI after system request before calling OnReceivedPolicyUpdate
+ // Parse message into table struct
+ utils::SharedPtr<policy_table::Table> pt_update = Parse(pt_content);
+#else
+ // Message Received from server unecnrypted with PTU in first element
+ // of 'data' array. No Parsing was done by HMI.
+ utils::SharedPtr<policy_table::Table> pt_update = ParseArray(pt_content);
+#endif
+ if (!pt_update) {
+ LOG4CXX_WARN(logger_, "Parsed table pointer is 0.");
+ update_status_manager_.OnWrongUpdateReceived();
+ return false;
+ }
+
+ file_system::DeleteFile(file);
+
+ if (!IsPTValid(pt_update, policy_table::PT_UPDATE)) {
+ wrong_ptu_update_received_ = true;
+ update_status_manager_.OnWrongUpdateReceived();
+ return false;
+ }
+
+ update_status_manager_.OnValidUpdateReceived();
+ cache_->SaveUpdateRequired(false);
+
+ // Update finished, no need retry
+ if (timer_retry_sequence_.is_running()) {
+ LOG4CXX_INFO(logger_, "Stop retry sequence");
+ timer_retry_sequence_.Stop();
+ }
+
+ {
+ sync_primitives::AutoLock lock(apps_registration_lock_);
+
+ // Get current DB data, since it could be updated during awaiting of PTU
+ utils::SharedPtr<policy_table::Table> policy_table_snapshot =
+ cache_->GenerateSnapshot();
+ if (!policy_table_snapshot) {
+ LOG4CXX_ERROR(logger_, "Failed to create snapshot of policy table");
+ return false;
+ }
+
+ // Checking of difference between PTU and current policy state
+ // Must to be done before PTU applying since it is possible, that functional
+ // groups, which had been present before are absent in PTU and will be
+ // removed after update. So in case of revoked groups system has to know
+ // names and ids of revoked groups before they will be removed.
+ CheckPermissionsChanges(pt_update, policy_table_snapshot);
+
+ // Replace current data with updated
+ if (!cache_->ApplyUpdate(*pt_update)) {
+ LOG4CXX_WARN(logger_, "Unsuccessful save of updated policy table.");
+ return false;
+ }
+
+ if (pt_update->policy_table.module_config.certificate.is_initialized()) {
+ listener_->OnCertificateUpdated(
+ *(pt_update->policy_table.module_config.certificate));
+ }
+
+ std::map<std::string, StringArray> app_hmi_types;
+ cache_->GetHMIAppTypeAfterUpdate(app_hmi_types);
+ if (!app_hmi_types.empty()) {
+ LOG4CXX_INFO(logger_, "app_hmi_types is full calling OnUpdateHMIAppType");
+ listener_->OnUpdateHMIAppType(app_hmi_types);
+ } else {
+ LOG4CXX_INFO(logger_, "app_hmi_types empty" << pt_content.size());
+ }
+ }
+
+ // If there was a user request for policy table update, it should be started
+ // right after current update is finished
+ if (update_status_manager_.IsUpdateRequired()) {
+ StartPTExchange();
+ return true;
+ }
+
+ RefreshRetrySequence();
+ return true;
+}
+
+void PolicyManagerImpl::CheckPermissionsChanges(
+ const utils::SharedPtr<policy_table::Table> pt_update,
+ const utils::SharedPtr<policy_table::Table> snapshot) {
+ LOG4CXX_INFO(logger_, "Checking incoming permissions.");
+
+ // Replace predefined policies with its actual setting, e.g. "123":"default"
+ // to actual values of default section
+ UnwrapAppPolicies(pt_update->policy_table.app_policies_section.apps);
+
+ std::for_each(pt_update->policy_table.app_policies_section.apps.begin(),
+ pt_update->policy_table.app_policies_section.apps.end(),
+ CheckAppPolicy(this, pt_update, snapshot));
+}
+
+void PolicyManagerImpl::PrepareNotificationData(
+ const policy_table::FunctionalGroupings& groups,
+ const policy_table::Strings& group_names,
+ const std::vector<FunctionalGroupPermission>& group_permission,
+ Permissions& notification_data) {
+ LOG4CXX_INFO(logger_, "Preparing data for notification.");
+ ProcessFunctionalGroup processor(groups, group_permission, notification_data);
+ std::for_each(group_names.begin(), group_names.end(), processor);
+}
+
+void PolicyManagerImpl::GetUpdateUrls(const std::string& service_type,
+ EndpointUrls& out_end_points) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ cache_->GetUpdateUrls(service_type, out_end_points);
+}
+void PolicyManagerImpl::GetUpdateUrls(const uint32_t service_type,
+ EndpointUrls& out_end_points) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ cache_->GetUpdateUrls(service_type, out_end_points);
+}
+
+bool PolicyManagerImpl::RequestPTUpdate() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::SharedPtr<policy_table::Table> policy_table_snapshot =
+ cache_->GenerateSnapshot();
+ if (!policy_table_snapshot) {
+ LOG4CXX_ERROR(logger_, "Failed to create snapshot of policy table");
+ return false;
+ }
+
+ IsPTValid(policy_table_snapshot, policy_table::PT_SNAPSHOT);
+
+ Json::Value value = policy_table_snapshot->ToJsonValue();
+ Json::FastWriter writer;
+ std::string message_string = writer.write(value);
+
+ LOG4CXX_DEBUG(logger_, "Snapshot contents is : " << message_string);
+
+ BinaryMessage update(message_string.begin(), message_string.end());
+
+ listener_->OnSnapshotCreated(update);
+ return true;
+}
+
+std::string PolicyManagerImpl::GetLockScreenIconUrl() const {
+ return cache_->GetLockScreenIconUrl();
+}
+
+void PolicyManagerImpl::StartPTExchange() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ const bool update_required = update_status_manager_.IsUpdateRequired();
+
+ if (update_status_manager_.IsAppsSearchInProgress() && update_required) {
+ update_status_manager_.ScheduleUpdate();
+ LOG4CXX_INFO(logger_,
+ "Starting exchange skipped, since applications "
+ "search is in progress.");
+ return;
+ }
+
+ if (update_status_manager_.IsUpdatePending() && update_required) {
+ if (trigger_ptu_)
+ update_status_manager_.ScheduleUpdate();
+ LOG4CXX_INFO(logger_,
+ "Starting exchange skipped, since another exchange "
+ "is in progress.");
+ return;
+ }
+
+ if (listener_ && listener_->CanUpdate()) {
+ if (ignition_check) {
+ CheckTriggers();
+ ignition_check = false;
+ }
+
+ if (update_status_manager_.IsUpdateRequired()) {
+ if (RequestPTUpdate() && !timer_retry_sequence_.is_running()) {
+ // Start retry sequency
+ const uint32_t timeout_msec = NextRetryTimeout();
+
+ if (timeout_msec) {
+ LOG4CXX_DEBUG(logger_,
+ "Start retry sequence timeout = " << timeout_msec);
+ timer_retry_sequence_.Start(timeout_msec, timer::kPeriodic);
+ }
+ }
+ }
+ }
+}
+
+void PolicyManagerImpl::OnAppsSearchStarted() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ update_status_manager_.OnAppsSearchStarted();
+}
+
+void PolicyManagerImpl::OnAppsSearchCompleted(const bool trigger_ptu) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ update_status_manager_.OnAppsSearchCompleted();
+
+ trigger_ptu_ = trigger_ptu;
+
+ if (update_status_manager_.IsUpdateRequired()) {
+ StartPTExchange();
+ }
+}
+
+void PolicyManagerImpl::OnAppRegisteredOnMobile(
+ const std::string& application_id) {
+ StartPTExchange();
+ SendNotificationOnPermissionsUpdated(application_id);
+}
+
+const std::vector<std::string> PolicyManagerImpl::GetAppRequestTypes(
+ const std::string policy_app_id) const {
+ std::vector<std::string> request_types;
+ cache_->GetAppRequestTypes(policy_app_id, request_types);
+ return request_types;
+}
+
+const VehicleInfo PolicyManagerImpl::GetVehicleInfo() const {
+ return cache_->GetVehicleInfo();
+}
+
+void PolicyManagerImpl::CheckPermissions(const PTString& device_id,
+ const PTString& app_id,
+ const PTString& hmi_level,
+ const PTString& rpc,
+ const RPCParams& rpc_params,
+ CheckPermissionResult& result) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (!cache_->IsApplicationRepresented(app_id)) {
+ LOG4CXX_WARN(logger_, "Application " << app_id << " isn't exist");
+ return;
+ }
+
+ LOG4CXX_INFO(logger_,
+ "CheckPermissions for " << app_id << " and rpc " << rpc
+ << " for " << hmi_level << " level.");
+
+ const policy_table::Strings& groups = cache_->GetGroups(app_id);
+ cache_->CheckPermissions(groups, hmi_level, rpc, result);
+ if (cache_->IsApplicationRevoked(app_id)) {
+ // SDL must be able to notify mobile side with its status after app has
+ // been revoked by backend
+ if ("OnHMIStatus" == rpc && "NONE" == hmi_level) {
+ result.hmi_level_permitted = kRpcAllowed;
+ } else {
+ result.hmi_level_permitted = kRpcDisallowed;
+ }
+ }
+}
+
+bool PolicyManagerImpl::ResetUserConsent() {
+ bool result = true;
+
+ return result;
+}
+
+void PolicyManagerImpl::SendNotificationOnPermissionsUpdated(
+ const std::string& application_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const std::string device_id = GetCurrentDeviceId(application_id);
+ if (device_id.empty()) {
+ LOG4CXX_WARN(logger_,
+ "Couldn't find device info for application id "
+ "'" << application_id << "'");
+ return;
+ }
+
+ std::vector<FunctionalGroupPermission> app_group_permissions;
+ GetPermissionsForApp(device_id, application_id, app_group_permissions);
+
+ policy_table::FunctionalGroupings functional_groupings;
+ cache_->GetFunctionalGroupings(functional_groupings);
+
+ policy_table::Strings app_groups;
+ std::vector<FunctionalGroupPermission>::const_iterator it =
+ app_group_permissions.begin();
+ std::vector<FunctionalGroupPermission>::const_iterator it_end =
+ app_group_permissions.end();
+ for (; it != it_end; ++it) {
+ app_groups.push_back((*it).group_name);
+ }
+
+ Permissions notification_data;
+ PrepareNotificationData(functional_groupings,
+ app_groups,
+ app_group_permissions,
+ notification_data);
+
+ LOG4CXX_INFO(logger_,
+ "Send notification for application_id:" << application_id);
+
+ std::string default_hmi;
+ default_hmi = "NONE";
+
+ listener()->OnPermissionsUpdated(
+ application_id, notification_data, default_hmi);
+}
+
+bool PolicyManagerImpl::CleanupUnpairedDevices() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ // For SDL-specific it doesn't matter
+ return true;
+}
+
+DeviceConsent PolicyManagerImpl::GetUserConsentForDevice(
+ const std::string& device_id) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return kDeviceAllowed;
+}
+
+void PolicyManagerImpl::SetUserConsentForDevice(const std::string& device_id,
+ bool is_allowed) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Device :" << device_id);
+ DeviceConsent current_consent = GetUserConsentForDevice(device_id);
+ bool is_current_device_allowed =
+ DeviceConsent::kDeviceAllowed == current_consent ? true : false;
+ if (DeviceConsent::kDeviceHasNoConsent != current_consent &&
+ is_current_device_allowed == is_allowed) {
+ const std::string consent = is_allowed ? "allowed" : "disallowed";
+ LOG4CXX_INFO(logger_, "Device is already " << consent << ".");
+ return;
+ }
+}
+
+bool PolicyManagerImpl::ReactOnUserDevConsentForApp(const std::string app_id,
+ bool is_device_allowed) {
+ return true;
+}
+
+bool PolicyManagerImpl::GetInitialAppData(const std::string& application_id,
+ StringArray* nicknames,
+ StringArray* app_hmi_types) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const bool result = nicknames && app_hmi_types;
+ if (result) {
+ cache_->GetInitialAppData(application_id, *nicknames, *app_hmi_types);
+ }
+ return result;
+}
+
+void PolicyManagerImpl::AddDevice(const std::string& device_id,
+ const std::string& connection_type) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Device: " << device_id);
+ if (!cache_->AddDevice(device_id, connection_type)) {
+ LOG4CXX_WARN(logger_, "Can't add device.");
+ }
+}
+
+void PolicyManagerImpl::SetDeviceInfo(const std::string& device_id,
+ const DeviceInfo& device_info) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Device :" << device_id);
+}
+
+PermissionConsent PolicyManagerImpl::EnsureCorrectPermissionConsent(
+ const PermissionConsent& permissions_to_check) {
+ std::vector<FunctionalGroupPermission> current_user_consents;
+ GetUserConsentForApp(permissions_to_check.device_id,
+ permissions_to_check.policy_app_id,
+ current_user_consents);
+
+ PermissionConsent permissions_to_set;
+ permissions_to_set.device_id = permissions_to_check.device_id;
+ permissions_to_set.policy_app_id = permissions_to_check.policy_app_id;
+ permissions_to_set.consent_source = permissions_to_check.consent_source;
+
+ std::vector<FunctionalGroupPermission>::const_iterator it =
+ permissions_to_check.group_permissions.begin();
+ std::vector<FunctionalGroupPermission>::const_iterator it_end =
+ permissions_to_check.group_permissions.end();
+
+ for (; it != it_end; ++it) {
+ std::vector<FunctionalGroupPermission>::const_iterator it_curr =
+ current_user_consents.begin();
+ std::vector<FunctionalGroupPermission>::const_iterator it_curr_end =
+ current_user_consents.end();
+
+ for (; it_curr != it_curr_end; ++it_curr) {
+ if (it->group_alias == it_curr->group_alias &&
+ it->group_id == it_curr->group_id) {
+ permissions_to_set.group_permissions.push_back(*it);
+ }
+ }
+ }
+
+ return permissions_to_set;
+}
+
+void PolicyManagerImpl::CheckPendingPermissionsChanges(
+ const std::string& policy_app_id,
+ const std::vector<FunctionalGroupPermission>& current_permissions) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(app_permissions_diff_lock_);
+ std::map<std::string, AppPermissions>::iterator it_pending =
+ app_permissions_diff_.find(policy_app_id);
+ if (app_permissions_diff_.end() == it_pending) {
+ LOG4CXX_WARN(
+ logger_,
+ "No pending permissions had been found for appID: " << policy_app_id);
+ return;
+ }
+
+ LOG4CXX_DEBUG(
+ logger_,
+ "Pending permissions had been found for appID: " << policy_app_id);
+
+ // Change appPermissionsConsentNeeded depending on unconsented groups
+ // presence
+ std::vector<policy::FunctionalGroupPermission>::const_iterator it_groups =
+ current_permissions.begin();
+ std::vector<policy::FunctionalGroupPermission>::const_iterator it_end_groups =
+ current_permissions.end();
+
+ for (; it_groups != it_end_groups; ++it_groups) {
+ if (policy::kGroupUndefined == it_groups->state) {
+ LOG4CXX_DEBUG(
+ logger_,
+ "Unconsented groups still present for appID: " << policy_app_id);
+ it_pending->second.appPermissionsConsentNeeded = true;
+ return;
+ }
+ }
+
+ LOG4CXX_DEBUG(
+ logger_,
+ "Unconsented groups not present anymore for appID: " << policy_app_id);
+ it_pending->second.appPermissionsConsentNeeded = false;
+ return;
+}
+
+void PolicyManagerImpl::SetUserConsentForApp(
+ const PermissionConsent& permissions) {
+ LOG4CXX_AUTO_TRACE(logger_);
+}
+
+bool PolicyManagerImpl::GetDefaultHmi(const std::string& policy_app_id,
+ std::string* default_hmi) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const std::string device_id = GetCurrentDeviceId(policy_app_id);
+ DeviceConsent device_consent = GetUserConsentForDevice(device_id);
+ const std::string app_id = policy::kDeviceAllowed != device_consent
+ ? kPreDataConsentId
+ : policy_app_id;
+ return cache_->GetDefaultHMI(app_id, *default_hmi);
+}
+
+bool PolicyManagerImpl::GetPriority(const std::string& policy_app_id,
+ std::string* priority) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (!priority) {
+ LOG4CXX_WARN(logger_, "Input priority parameter is null.");
+ return false;
+ }
+
+ return cache_->GetPriority(policy_app_id, *priority);
+}
+
+std::vector<UserFriendlyMessage> PolicyManagerImpl::GetUserFriendlyMessages(
+ const std::vector<std::string>& message_code, const std::string& language) {
+ return cache_->GetUserFriendlyMsg(message_code, language);
+}
+
+void PolicyManagerImpl::GetUserConsentForApp(
+ const std::string& device_id,
+ const std::string& policy_app_id,
+ std::vector<FunctionalGroupPermission>& permissions) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ FunctionalIdType group_types;
+ if (!cache_->GetPermissionsForApp(device_id, policy_app_id, group_types)) {
+ LOG4CXX_WARN(logger_,
+ "Can't get user permissions for app " << policy_app_id);
+ return;
+ }
+
+ // Functional groups w/o alias ("user_consent_prompt") considered as
+ // automatically allowed and it could not be changed by user
+ FunctionalGroupNames group_names;
+ if (!cache_->GetFunctionalGroupNames(group_names)) {
+ LOG4CXX_WARN(logger_, "Can't get functional group names");
+ return;
+ }
+
+ FunctionalGroupNames::const_iterator it = group_names.begin();
+ FunctionalGroupNames::const_iterator it_end = group_names.end();
+ FunctionalGroupIDs auto_allowed_groups;
+ for (; it != it_end; ++it) {
+ if (it->second.first.empty()) {
+ auto_allowed_groups.push_back(it->first);
+ }
+ }
+
+ // For basic policy
+ FunctionalGroupIDs all_groups = group_types[kTypeGeneral];
+ FunctionalGroupIDs default_groups = group_types[kTypeDefault];
+ FunctionalGroupIDs predataconsented_groups =
+ group_types[kTypePreDataConsented];
+
+ FunctionalGroupIDs allowed_groups;
+ FunctionalGroupIDs no_auto = ExcludeSame(all_groups, auto_allowed_groups);
+
+ if (cache_->IsDefaultPolicy(policy_app_id)) {
+ allowed_groups = ExcludeSame(no_auto, default_groups);
+ } else if (cache_->IsPredataPolicy(policy_app_id)) {
+ allowed_groups = ExcludeSame(no_auto, predataconsented_groups);
+ }
+ FillFunctionalGroupPermissions(
+ allowed_groups, group_names, kGroupAllowed, permissions);
+}
+
+void PolicyManagerImpl::GetPermissionsForApp(
+ const std::string& device_id,
+ const std::string& policy_app_id,
+ std::vector<FunctionalGroupPermission>& permissions) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ std::string app_id_to_check = policy_app_id;
+
+ bool allowed_by_default = false;
+ if (cache_->IsDefaultPolicy(policy_app_id)) {
+ app_id_to_check = kDefaultId;
+ allowed_by_default = true;
+ } else if (cache_->IsPredataPolicy(policy_app_id) ||
+ policy::kDeviceDisallowed == GetUserConsentForDevice(device_id)) {
+ app_id_to_check = kPreDataConsentId;
+ allowed_by_default = true;
+ }
+
+ FunctionalIdType group_types;
+ if (!cache_->GetPermissionsForApp(device_id, app_id_to_check, group_types)) {
+ LOG4CXX_WARN(logger_,
+ "Can't get user permissions for app " << policy_app_id);
+ return;
+ }
+
+ // Functional groups w/o alias ("user_consent_prompt") considered as
+ // automatically allowed and it could not be changed by user
+ FunctionalGroupNames group_names;
+ if (!cache_->GetFunctionalGroupNames(group_names)) {
+ LOG4CXX_WARN(logger_, "Can't get functional group names");
+ return;
+ }
+
+ // The "default" and "pre_DataConsent" are auto-allowed groups
+ // So, check if application in the one of these mode.
+ if (allowed_by_default) {
+ LOG4CXX_INFO(logger_, "Get auto allowed groups");
+ GroupType type =
+ (kDefaultId == app_id_to_check ? kTypeDefault : kTypePreDataConsented);
+
+ FillFunctionalGroupPermissions(
+ group_types[type], group_names, kGroupAllowed, permissions);
+ } else {
+ // The code bellow allows to process application which
+ // has specific permissions(not default and pre_DataConsent).
+
+ // All groups for specific application
+ FunctionalGroupIDs all_groups = group_types[kTypeGeneral];
+
+ // In case of GENIVI all groups are allowed
+ FunctionalGroupIDs common_allowed = all_groups;
+ FillFunctionalGroupPermissions(
+ common_allowed, group_names, kGroupAllowed, permissions);
+ }
+ return;
+}
+
+std::string& PolicyManagerImpl::GetCurrentDeviceId(
+ const std::string& policy_app_id) const {
+ LOG4CXX_INFO(logger_, "GetDeviceInfo");
+ last_device_id_ = listener()->OnCurrentDeviceIdUpdateRequired(policy_app_id);
+ return last_device_id_;
+}
+
+void PolicyManagerImpl::SetSystemLanguage(const std::string& language) {}
+
+void PolicyManagerImpl::SetSystemInfo(const std::string& ccpu_version,
+ const std::string& wers_country_code,
+ const std::string& language) {
+ LOG4CXX_AUTO_TRACE(logger_);
+}
+
+void PolicyManagerImpl::OnSystemReady() {
+ // Update policy table for the first time with system information
+ if (cache_->IsPTPreloaded()) {
+ listener()->OnSystemInfoUpdateRequired();
+ return;
+ }
+}
+
+uint32_t PolicyManagerImpl::GetNotificationsNumber(
+ const std::string& priority) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return cache_->GetNotificationsNumber(priority);
+}
+
+bool PolicyManagerImpl::ExceededIgnitionCycles() {
+ return 0 == cache_->IgnitionCyclesBeforeExchange();
+}
+
+bool PolicyManagerImpl::IsPTValid(
+ utils::SharedPtr<policy_table::Table> policy_table,
+ policy_table::PolicyTableType type) const {
+ policy_table->SetPolicyTableType(type);
+ if (!policy_table->is_valid()) {
+ LOG4CXX_ERROR(logger_, "Policy table is not valid.");
+ rpc::ValidationReport report("policy_table");
+ policy_table->ReportErrors(&report);
+ LOG4CXX_DEBUG(logger_, "Errors: " << rpc::PrettyFormat(report));
+ return false;
+ }
+ return true;
+}
+
+const PolicySettings& PolicyManagerImpl::get_settings() const {
+ DCHECK(settings_);
+ return *settings_;
+}
+
+bool PolicyManagerImpl::ExceededDays() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ TimevalStruct current_time = date_time::DateTime::getCurrentTime();
+ const int kSecondsInDay = 60 * 60 * 24;
+ const int days = current_time.tv_sec / kSecondsInDay;
+
+ return 0 == cache_->DaysBeforeExchange(days);
+}
+
+void PolicyManagerImpl::KmsChanged(int kilometers) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (0 == cache_->KilometersBeforeExchange(kilometers)) {
+ LOG4CXX_INFO(logger_, "Enough kilometers passed to send for PT update.");
+ update_status_manager_.ScheduleUpdate();
+ StartPTExchange();
+ }
+}
+
+void PolicyManagerImpl::IncrementIgnitionCycles() {
+ cache_->IncrementIgnitionCycles();
+}
+
+std::string PolicyManagerImpl::ForcePTExchange() {
+ update_status_manager_.ScheduleUpdate();
+ StartPTExchange();
+ return update_status_manager_.StringifiedUpdateStatus();
+}
+
+std::string PolicyManagerImpl::ForcePTExchangeAtUserRequest() {
+ update_status_manager_.ScheduleManualUpdate();
+ StartPTExchange();
+ return update_status_manager_.StringifiedUpdateStatus();
+}
+
+std::string PolicyManagerImpl::GetPolicyTableStatus() const {
+ return update_status_manager_.StringifiedUpdateStatus();
+}
+
+uint32_t PolicyManagerImpl::NextRetryTimeout() {
+ sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
+ LOG4CXX_DEBUG(logger_, "Index: " << retry_sequence_index_);
+ uint32_t next = 0u;
+ if (retry_sequence_seconds_.empty() ||
+ retry_sequence_index_ > retry_sequence_seconds_.size()) {
+ return next;
+ }
+
+ if (0 == retry_sequence_index_) {
+ ++retry_sequence_index_;
+ // Return miliseconds
+ return retry_sequence_timeout_;
+ }
+
+ for (uint32_t i = 0u; i < retry_sequence_index_; ++i) {
+ next += retry_sequence_seconds_[i] *
+ date_time::DateTime::MILLISECONDS_IN_SECOND;
+ next += retry_sequence_timeout_;
+ }
+ ++retry_sequence_index_;
+
+ // Return miliseconds
+ return next;
+}
+
+void PolicyManagerImpl::RefreshRetrySequence() {
+ sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
+ retry_sequence_timeout_ = cache_->TimeoutResponse();
+ retry_sequence_seconds_.clear();
+ cache_->SecondsBetweenRetries(retry_sequence_seconds_);
+}
+
+void PolicyManagerImpl::ResetRetrySequence() {
+ sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
+ retry_sequence_index_ = 0;
+ update_status_manager_.OnResetRetrySequence();
+}
+
+uint32_t PolicyManagerImpl::TimeoutExchangeMSec() {
+ return retry_sequence_timeout_;
+}
+
+const std::vector<int> PolicyManagerImpl::RetrySequenceDelaysSeconds() {
+ sync_primitives::AutoLock auto_lock(retry_sequence_lock_);
+ return retry_sequence_seconds_;
+}
+
+void PolicyManagerImpl::OnExceededTimeout() {
+ update_status_manager_.OnUpdateTimeoutOccurs();
+}
+
+void PolicyManagerImpl::OnUpdateStarted() {
+ update_status_manager_.OnUpdateSentOut();
+ cache_->SaveUpdateRequired(true);
+}
+
+void PolicyManagerImpl::PTUpdatedAt(Counters counter, int value) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ cache_->SetCountersPassedForSuccessfulUpdate(counter, value);
+ cache_->ResetIgnitionCycles();
+}
+
+void PolicyManagerImpl::Increment(usage_statistics::GlobalCounterId type) {
+ LOG4CXX_INFO(logger_, "Increment without app id");
+ cache_->Increment(type);
+}
+
+void PolicyManagerImpl::Increment(const std::string& app_id,
+ usage_statistics::AppCounterId type) {
+ LOG4CXX_DEBUG(logger_, "Increment " << app_id << " AppCounter: " << type);
+ cache_->Increment(app_id, type);
+}
+
+void PolicyManagerImpl::Set(const std::string& app_id,
+ usage_statistics::AppInfoId type,
+ const std::string& value) {
+ LOG4CXX_INFO(logger_, "Set " << app_id);
+ cache_->Set(app_id, type, value);
+}
+
+void PolicyManagerImpl::Add(const std::string& app_id,
+ usage_statistics::AppStopwatchId type,
+ int32_t timespan_seconds) {
+ LOG4CXX_INFO(logger_, "Add " << app_id);
+ cache_->Add(app_id, type, timespan_seconds);
+}
+
+bool PolicyManagerImpl::IsApplicationRevoked(const std::string& app_id) const {
+ return cache_->IsApplicationRevoked(app_id);
+}
+
+bool PolicyManagerImpl::IsConsentNeeded(const std::string& app_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return false;
+}
+
+void PolicyManagerImpl::SetVINValue(const std::string& value) {}
+
+AppPermissions PolicyManagerImpl::GetAppPermissionsChanges(
+ const std::string& policy_app_id) {
+ typedef std::map<std::string, AppPermissions>::iterator PermissionsIt;
+ PermissionsIt app_id_diff = app_permissions_diff_.find(policy_app_id);
+ AppPermissions permissions(policy_app_id);
+ if (app_permissions_diff_.end() != app_id_diff) {
+ permissions = app_id_diff->second;
+ } else {
+ permissions.appPermissionsConsentNeeded = IsConsentNeeded(policy_app_id);
+ permissions.appRevoked = IsApplicationRevoked(policy_app_id);
+ GetPriority(permissions.application_id, &permissions.priority);
+ }
+ return permissions;
+}
+
+void PolicyManagerImpl::RemovePendingPermissionChanges(
+ const std::string& app_id) {
+ app_permissions_diff_.erase(app_id);
+}
+
+bool PolicyManagerImpl::CanAppKeepContext(const std::string& app_id) const {
+ return cache_->CanAppKeepContext(app_id);
+}
+
+bool PolicyManagerImpl::CanAppStealFocus(const std::string& app_id) const {
+ return cache_->CanAppStealFocus(app_id);
+}
+
+void PolicyManagerImpl::MarkUnpairedDevice(const std::string& device_id) {}
+
+std::string PolicyManagerImpl::RetrieveCertificate() const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return cache_->GetCertificate();
+}
+
+AppIdURL PolicyManagerImpl::GetNextUpdateUrl(const EndpointUrls& urls) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ const AppIdURL next_app_url = RetrySequenceUrl(retry_sequence_url_, urls);
+
+ retry_sequence_url_.url_idx_ = next_app_url.second + 1;
+ retry_sequence_url_.app_idx_ = next_app_url.first;
+ retry_sequence_url_.policy_app_id_ = urls[next_app_url.first].app_id;
+
+ return next_app_url;
+}
+
+AppIdURL PolicyManagerImpl::RetrySequenceUrl(const struct RetrySequenceURL& rs,
+ const EndpointUrls& urls) const {
+ uint32_t url_idx = rs.url_idx_;
+ uint32_t app_idx = rs.app_idx_;
+ const std::string& app_id = rs.policy_app_id_;
+
+ if (urls.size() <= app_idx) {
+ // Index of current application doesn't exist any more due to app(s)
+ // unregistration
+ url_idx = 0;
+ app_idx = 0;
+ } else if (urls[app_idx].app_id != app_id) {
+ // Index of current application points to another one due to app(s)
+ // registration/unregistration
+ url_idx = 0;
+ } else if (url_idx >= urls[app_idx].url.size()) {
+ // Index of current application is OK, but all of its URL are sent,
+ // move to the next application
+ url_idx = 0;
+ if (++app_idx >= urls.size()) {
+ app_idx = 0;
+ }
+ }
+ const AppIdURL next_app_url = std::make_pair(app_idx, url_idx);
+
+ return next_app_url;
+}
+
+bool PolicyManagerImpl::HasCertificate() const {
+ return !cache_->GetCertificate().empty();
+}
+
+class CallStatusChange : public utils::Callable {
+ public:
+ CallStatusChange(UpdateStatusManager& upd_manager,
+ const DeviceConsent& device_consent)
+ : upd_manager_(upd_manager), device_consent_(device_consent) {}
+
+ // Callable interface
+ void operator()() const {
+ upd_manager_.OnNewApplicationAdded(device_consent_);
+ }
+
+ private:
+ UpdateStatusManager& upd_manager_;
+ const DeviceConsent device_consent_;
+};
+
+StatusNotifier PolicyManagerImpl::AddApplication(
+ const std::string& application_id,
+ const rpc::policy_table_interface_base::AppHmiTypes& hmi_types) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const std::string device_id = GetCurrentDeviceId(application_id);
+ DeviceConsent device_consent = GetUserConsentForDevice(device_id);
+ sync_primitives::AutoLock lock(apps_registration_lock_);
+ if (IsNewApplication(application_id)) {
+ AddNewApplication(application_id, device_consent);
+ return utils::MakeShared<CallStatusChange>(update_status_manager_,
+ device_consent);
+ } else {
+ PromoteExistedApplication(application_id, device_consent);
+ const policy_table::AppHMIType type = policy_table::AHT_NAVIGATION;
+ if (helpers::in_range(hmi_types,
+ (rpc::Enum<policy_table::AppHMIType>)type) &&
+ !HasCertificate()) {
+ LOG4CXX_DEBUG(logger_, "Certificate does not exist, scheduling update.");
+ update_status_manager_.ScheduleUpdate();
+ }
+ return utils::MakeShared<utils::CallNothing>();
+ }
+}
+void PolicyManagerImpl::RemoveAppConsentForGroup(
+ const std::string& app_id, const std::string& group_name) {
+ cache_->RemoveAppConsentForGroup(app_id, group_name);
+}
+
+bool PolicyManagerImpl::IsPredataPolicy(
+ const std::string& policy_app_id) const {
+ LOG4CXX_INFO(logger_, "IsPredataApp");
+ return cache_->IsPredataPolicy(policy_app_id);
+}
+
+void PolicyManagerImpl::AddNewApplication(const std::string& application_id,
+ DeviceConsent device_consent) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ cache_->SetDefaultPolicy(application_id);
+}
+
+void PolicyManagerImpl::PromoteExistedApplication(
+ const std::string& application_id, DeviceConsent device_consent) {
+ // If device consent changed to allowed during application being
+ // disconnected, app permissions should be changed also
+ if (kDeviceAllowed == device_consent &&
+ cache_->IsPredataPolicy(application_id)) {
+ cache_->SetDefaultPolicy(application_id);
+ }
+}
+
+bool PolicyManagerImpl::IsNewApplication(
+ const std::string& application_id) const {
+ return false == cache_->IsApplicationRepresented(application_id);
+}
+
+bool PolicyManagerImpl::ResetPT(const std::string& file_name) {
+ cache_->ResetCalculatedPermissions();
+ const bool result = cache_->ResetPT(file_name);
+ if (result) {
+ RefreshRetrySequence();
+ }
+ return result;
+}
+
+bool PolicyManagerImpl::CheckAppStorageFolder() const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const std::string app_storage_folder = get_settings().app_storage_folder();
+ LOG4CXX_DEBUG(logger_, "AppStorageFolder " << app_storage_folder);
+ if (!file_system::DirectoryExists(app_storage_folder)) {
+ LOG4CXX_WARN(logger_,
+ "Storage directory doesn't exist " << app_storage_folder);
+ return false;
+ }
+ if (!(file_system::IsWritingAllowed(app_storage_folder) &&
+ file_system::IsReadingAllowed(app_storage_folder))) {
+ LOG4CXX_WARN(logger_,
+ "Storage directory doesn't have read/write permissions "
+ << app_storage_folder);
+ return false;
+ }
+ return true;
+}
+
+bool PolicyManagerImpl::InitPT(const std::string& file_name,
+ const PolicySettings* settings) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ settings_ = settings;
+ if (!CheckAppStorageFolder()) {
+ LOG4CXX_ERROR(logger_, "Can not read/write into AppStorageFolder");
+ return false;
+ }
+ const bool ret = cache_->Init(file_name, settings);
+ if (ret) {
+ RefreshRetrySequence();
+ update_status_manager_.OnPolicyInit(cache_->UpdateRequired());
+ }
+ return ret;
+}
+
+uint32_t PolicyManagerImpl::HeartBeatTimeout(const std::string& app_id) const {
+ return cache_->HeartBeatTimeout(app_id);
+}
+
+void PolicyManagerImpl::SaveUpdateStatusRequired(bool is_update_needed) {
+ cache_->SaveUpdateRequired(is_update_needed);
+}
+
+void PolicyManagerImpl::set_cache_manager(
+ CacheManagerInterface* cache_manager) {
+ cache_ = cache_manager;
+}
+
+void PolicyManagerImpl::RetrySequence() {
+ LOG4CXX_INFO(logger_, "Start new retry sequence");
+ update_status_manager_.OnUpdateTimeoutOccurs();
+
+ const uint32_t timeout_msec = NextRetryTimeout();
+ LOG4CXX_DEBUG(logger_, "New retry sequence timeout = " << timeout_msec);
+ if (!timeout_msec) {
+ if (timer_retry_sequence_.is_running()) {
+ timer_retry_sequence_.Stop();
+ }
+ return;
+ }
+
+ RequestPTUpdate();
+ timer_retry_sequence_.Start(timeout_msec, timer::kPeriodic);
+}
+
+} // namespace policy
diff --git a/src/components/policy/policy_regular/src/policy_table.cc b/src/components/policy/policy_regular/src/policy_table.cc
new file mode 100644
index 0000000000..c5c6e3e132
--- /dev/null
+++ b/src/components/policy/policy_regular/src/policy_table.cc
@@ -0,0 +1,52 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "policy/policy_table.h"
+
+#include "policy/sql_pt_representation.h"
+
+#include "utils/logger.h"
+
+namespace policy {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Policy")
+
+PolicyTable::PolicyTable() : pt_data_(new SQLPTRepresentation()) {}
+
+PolicyTable::PolicyTable(utils::SharedPtr<PTRepresentation> pt_data)
+ : pt_data_(pt_data) {}
+
+PolicyTable::~PolicyTable() {
+ LOG4CXX_INFO(logger_, "Destroying policy table.");
+}
+
+} // namespace policy
diff --git a/src/components/policy/policy_regular/src/policy_table/enums.cc b/src/components/policy/policy_regular/src/policy_table/enums.cc
new file mode 100644
index 0000000000..26c7b96b32
--- /dev/null
+++ b/src/components/policy/policy_regular/src/policy_table/enums.cc
@@ -0,0 +1,577 @@
+// This file is generated, do not edit
+#include "policy/policy_table/enums.h"
+
+namespace rpc {
+namespace policy_table_interface_base {
+bool IsValidEnum(Priority val) {
+ switch (val) {
+ case P_EMERGENCY:
+ return true;
+ case P_NAVIGATION:
+ return true;
+ case P_VOICECOM:
+ return true;
+ case P_COMMUNICATION:
+ return true;
+ case P_NORMAL:
+ return true;
+ case P_NONE:
+ return true;
+ default:
+ return false;
+ }
+}
+const char* EnumToJsonString(Priority val) {
+ switch (val) {
+ case P_EMERGENCY:
+ return "EMERGENCY";
+ case P_NAVIGATION:
+ return "NAVIGATION";
+ case P_VOICECOM:
+ return "VOICECOM";
+ case P_COMMUNICATION:
+ return "COMMUNICATION";
+ case P_NORMAL:
+ return "NORMAL";
+ case P_NONE:
+ return "NONE";
+ default:
+ return "";
+ }
+}
+bool EnumFromJsonString(const std::string& literal, Priority* result) {
+ if ("EMERGENCY" == literal) {
+ *result = P_EMERGENCY;
+ return true;
+ } else if ("NAVIGATION" == literal) {
+ *result = P_NAVIGATION;
+ return true;
+ } else if ("VOICECOM" == literal) {
+ *result = P_VOICECOM;
+ return true;
+ } else if ("COMMUNICATION" == literal) {
+ *result = P_COMMUNICATION;
+ return true;
+ } else if ("NORMAL" == literal) {
+ *result = P_NORMAL;
+ return true;
+ } else if ("NONE" == literal) {
+ *result = P_NONE;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool IsValidEnum(HmiLevel val) {
+ switch (val) {
+ case HL_BACKGROUND:
+ return true;
+ case HL_FULL:
+ return true;
+ case HL_LIMITED:
+ return true;
+ case HL_NONE:
+ return true;
+ default:
+ return false;
+ }
+}
+const char* EnumToJsonString(HmiLevel val) {
+ switch (val) {
+ case HL_BACKGROUND:
+ return "BACKGROUND";
+ case HL_FULL:
+ return "FULL";
+ case HL_LIMITED:
+ return "LIMITED";
+ case HL_NONE:
+ return "NONE";
+ default:
+ return "";
+ }
+}
+bool EnumFromJsonString(const std::string& literal, HmiLevel* result) {
+ if ("BACKGROUND" == literal) {
+ *result = HL_BACKGROUND;
+ return true;
+ } else if ("FULL" == literal) {
+ *result = HL_FULL;
+ return true;
+ } else if ("LIMITED" == literal) {
+ *result = HL_LIMITED;
+ return true;
+ } else if ("NONE" == literal) {
+ *result = HL_NONE;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool IsValidEnum(Parameter val) {
+ switch (val) {
+ case P_GPS:
+ return true;
+ case P_SPEED:
+ return true;
+ case P_ENGINETORQUE:
+ return true;
+ case P_EXTERNALTEMPERATURE:
+ return true;
+ case P_FUELLEVEL:
+ return true;
+ case P_FUELLEVEL_STATE:
+ return true;
+ case P_HEADLAMPSTATUS:
+ return true;
+ case P_INSTANTFUELCONSUMPTION:
+ return true;
+ case P_ODOMETER:
+ return true;
+ case P_TIREPRESSURE:
+ return true;
+ case P_WIPERSTATUS:
+ return true;
+ case P_VIN:
+ return true;
+ case P_ACCPEDALPOSITION:
+ return true;
+ case P_BELTSTATUS:
+ return true;
+ case P_DRIVERBRAKING:
+ return true;
+ case P_PRNDL:
+ return true;
+ case P_RPM:
+ return true;
+ case P_STEERINGWHEELANGLE:
+ return true;
+ case P_MYKEY:
+ return true;
+ case P_AIRBAGSTATUS:
+ return true;
+ case P_BODYINFORMATION:
+ return true;
+ case P_CLUSTERMODESTATUS:
+ return true;
+ case P_DEVICESTATUS:
+ return true;
+ case P_EMERGENCYEVENT:
+ return true;
+ case P_ECALLINFO:
+ return true;
+ default:
+ return false;
+ }
+}
+const char* EnumToJsonString(Parameter val) {
+ switch (val) {
+ case P_GPS:
+ return "gps";
+ case P_SPEED:
+ return "speed";
+ case P_ENGINETORQUE:
+ return "engineTorque";
+ case P_EXTERNALTEMPERATURE:
+ return "externalTemperature";
+ case P_FUELLEVEL:
+ return "fuelLevel";
+ case P_FUELLEVEL_STATE:
+ return "fuelLevel_State";
+ case P_HEADLAMPSTATUS:
+ return "headLampStatus";
+ case P_INSTANTFUELCONSUMPTION:
+ return "instantFuelConsumption";
+ case P_ODOMETER:
+ return "odometer";
+ case P_TIREPRESSURE:
+ return "tirePressure";
+ case P_WIPERSTATUS:
+ return "wiperStatus";
+ case P_VIN:
+ return "vin";
+ case P_ACCPEDALPOSITION:
+ return "accPedalPosition";
+ case P_BELTSTATUS:
+ return "beltStatus";
+ case P_DRIVERBRAKING:
+ return "driverBraking";
+ case P_PRNDL:
+ return "prndl";
+ case P_RPM:
+ return "rpm";
+ case P_STEERINGWHEELANGLE:
+ return "steeringWheelAngle";
+ case P_MYKEY:
+ return "myKey";
+ case P_AIRBAGSTATUS:
+ return "airbagStatus";
+ case P_BODYINFORMATION:
+ return "bodyInformation";
+ case P_CLUSTERMODESTATUS:
+ return "clusterModeStatus";
+ case P_DEVICESTATUS:
+ return "deviceStatus";
+ case P_EMERGENCYEVENT:
+ return "emergencyEvent";
+ case P_ECALLINFO:
+ return "eCallInfo";
+ default:
+ return "";
+ }
+}
+bool EnumFromJsonString(const std::string& literal, Parameter* result) {
+ if ("gps" == literal) {
+ *result = P_GPS;
+ return true;
+ } else if ("speed" == literal) {
+ *result = P_SPEED;
+ return true;
+ } else if ("engineTorque" == literal) {
+ *result = P_ENGINETORQUE;
+ return true;
+ } else if ("externalTemperature" == literal) {
+ *result = P_EXTERNALTEMPERATURE;
+ return true;
+ } else if ("fuelLevel" == literal) {
+ *result = P_FUELLEVEL;
+ return true;
+ } else if ("fuelLevel_State" == literal) {
+ *result = P_FUELLEVEL_STATE;
+ return true;
+ } else if ("headLampStatus" == literal) {
+ *result = P_HEADLAMPSTATUS;
+ return true;
+ } else if ("instantFuelConsumption" == literal) {
+ *result = P_INSTANTFUELCONSUMPTION;
+ return true;
+ } else if ("odometer" == literal) {
+ *result = P_ODOMETER;
+ return true;
+ } else if ("tirePressure" == literal) {
+ *result = P_TIREPRESSURE;
+ return true;
+ } else if ("wiperStatus" == literal) {
+ *result = P_WIPERSTATUS;
+ return true;
+ } else if ("vin" == literal) {
+ *result = P_VIN;
+ return true;
+ } else if ("accPedalPosition" == literal) {
+ *result = P_ACCPEDALPOSITION;
+ return true;
+ } else if ("beltStatus" == literal) {
+ *result = P_BELTSTATUS;
+ return true;
+ } else if ("driverBraking" == literal) {
+ *result = P_DRIVERBRAKING;
+ return true;
+ } else if ("prndl" == literal) {
+ *result = P_PRNDL;
+ return true;
+ } else if ("rpm" == literal) {
+ *result = P_RPM;
+ return true;
+ } else if ("steeringWheelAngle" == literal) {
+ *result = P_STEERINGWHEELANGLE;
+ return true;
+ } else if ("myKey" == literal) {
+ *result = P_MYKEY;
+ return true;
+ } else if ("airbagStatus" == literal) {
+ *result = P_AIRBAGSTATUS;
+ return true;
+ } else if ("bodyInformation" == literal) {
+ *result = P_BODYINFORMATION;
+ return true;
+ } else if ("clusterModeStatus" == literal) {
+ *result = P_CLUSTERMODESTATUS;
+ return true;
+ } else if ("deviceStatus" == literal) {
+ *result = P_DEVICESTATUS;
+ return true;
+ } else if ("emergencyEvent" == literal) {
+ *result = P_EMERGENCYEVENT;
+ return true;
+ } else if ("eCallInfo" == literal) {
+ *result = P_ECALLINFO;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool IsValidEnum(AppHMIType val) {
+ switch (val) {
+ case AHT_DEFAULT:
+ return true;
+ case AHT_COMMUNICATION:
+ return true;
+ case AHT_MEDIA:
+ return true;
+ case AHT_MESSAGING:
+ return true;
+ case AHT_NAVIGATION:
+ return true;
+ case AHT_INFORMATION:
+ return true;
+ case AHT_SOCIAL:
+ return true;
+ case AHT_BACKGROUND_PROCESS:
+ return true;
+ case AHT_TESTING:
+ return true;
+ case AHT_SYSTEM:
+ return true;
+ default:
+ return false;
+ }
+}
+const char* EnumToJsonString(AppHMIType val) {
+ switch (val) {
+ case AHT_DEFAULT:
+ return "DEFAULT";
+ case AHT_COMMUNICATION:
+ return "COMMUNICATION";
+ case AHT_MEDIA:
+ return "MEDIA";
+ case AHT_MESSAGING:
+ return "MESSAGING";
+ case AHT_NAVIGATION:
+ return "NAVIGATION";
+ case AHT_INFORMATION:
+ return "INFORMATION";
+ case AHT_SOCIAL:
+ return "SOCIAL";
+ case AHT_BACKGROUND_PROCESS:
+ return "BACKGROUND_PROCESS";
+ case AHT_TESTING:
+ return "TESTING";
+ case AHT_SYSTEM:
+ return "SYSTEM";
+ default:
+ return "";
+ }
+}
+bool EnumFromJsonString(const std::string& literal, AppHMIType* result) {
+ if ("DEFAULT" == literal) {
+ *result = AHT_DEFAULT;
+ return true;
+ } else if ("COMMUNICATION" == literal) {
+ *result = AHT_COMMUNICATION;
+ return true;
+ } else if ("MEDIA" == literal) {
+ *result = AHT_MEDIA;
+ return true;
+ } else if ("MESSAGING" == literal) {
+ *result = AHT_MESSAGING;
+ return true;
+ } else if ("NAVIGATION" == literal) {
+ *result = AHT_NAVIGATION;
+ return true;
+ } else if ("INFORMATION" == literal) {
+ *result = AHT_INFORMATION;
+ return true;
+ } else if ("SOCIAL" == literal) {
+ *result = AHT_SOCIAL;
+ return true;
+ } else if ("BACKGROUND_PROCESS" == literal) {
+ *result = AHT_BACKGROUND_PROCESS;
+ return true;
+ } else if ("TESTING" == literal) {
+ *result = AHT_TESTING;
+ return true;
+ } else if ("SYSTEM" == literal) {
+ *result = AHT_SYSTEM;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool IsValidEnum(RequestType val) {
+ switch (val) {
+ case RT_HTTP:
+ return true;
+ case RT_FILE_RESUME:
+ return true;
+ case RT_AUTH_REQUEST:
+ return true;
+ case RT_AUTH_CHALLENGE:
+ return true;
+ case RT_AUTH_ACK:
+ return true;
+ case RT_PROPRIETARY:
+ return true;
+ case RT_QUERY_APPS:
+ return true;
+ case RT_LAUNCH_APP:
+ return true;
+ case RT_LOCK_SCREEN_ICON_URL:
+ return true;
+ case RT_TRAFFIC_MESSAGE_CHANNEL:
+ return true;
+ case RT_DRIVER_PROFILE:
+ return true;
+ case RT_VOICE_SEARCH:
+ return true;
+ case RT_NAVIGATION:
+ return true;
+ case RT_PHONE:
+ return true;
+ case RT_CLIMATE:
+ return true;
+ case RT_SETTINGS:
+ return true;
+ case RT_VEHICLE_DIAGNOSTICS:
+ return true;
+ case RT_EMERGENCY:
+ return true;
+ case RT_MEDIA:
+ return true;
+ case RT_FOTA:
+ return true;
+ default:
+ return false;
+ }
+}
+
+const char* EnumToJsonString(RequestType val) {
+ switch (val) {
+ case RT_HTTP:
+ return "HTTP";
+ case RT_FILE_RESUME:
+ return "FILE_RESUME";
+ case RT_AUTH_REQUEST:
+ return "AUTH_REQUEST";
+ case RT_AUTH_CHALLENGE:
+ return "AUTH_CHALLENGE";
+ case RT_AUTH_ACK:
+ return "AUTH_ACK";
+ case RT_PROPRIETARY:
+ return "PROPRIETARY";
+ case RT_QUERY_APPS:
+ return "QUERY_APPS";
+ case RT_LAUNCH_APP:
+ return "LAUNCH_APP";
+ case RT_LOCK_SCREEN_ICON_URL:
+ return "LOCK_SCREEN_ICON_URL";
+ case RT_TRAFFIC_MESSAGE_CHANNEL:
+ return "TRAFFIC_MESSAGE_CHANNEL";
+ case RT_DRIVER_PROFILE:
+ return "DRIVER_PROFILE";
+ case RT_VOICE_SEARCH:
+ return "VOICE_SEARCH";
+ case RT_NAVIGATION:
+ return "NAVIGATION";
+ case RT_PHONE:
+ return "PHONE";
+ case RT_CLIMATE:
+ return "CLIMATE";
+ case RT_SETTINGS:
+ return "SETTINGS";
+ case RT_VEHICLE_DIAGNOSTICS:
+ return "VEHICLE_DIAGNOSTICS";
+ case RT_EMERGENCY:
+ return "EMERGENCY";
+ case RT_MEDIA:
+ return "MEDIA";
+ case RT_FOTA:
+ return "FOTA";
+ default:
+ return "";
+ }
+}
+
+bool EnumFromJsonString(const std::string& literal, RequestType* result) {
+ if ("HTTP" == literal) {
+ *result = RT_HTTP;
+ return true;
+ }
+ if ("FILE_RESUME" == literal) {
+ *result = RT_FILE_RESUME;
+ return true;
+ }
+ if ("AUTH_REQUEST" == literal) {
+ *result = RT_AUTH_REQUEST;
+ return true;
+ }
+ if ("AUTH_CHALLENGE" == literal) {
+ *result = RT_AUTH_CHALLENGE;
+ return true;
+ }
+ if ("AUTH_ACK" == literal) {
+ *result = RT_AUTH_ACK;
+ return true;
+ }
+ if ("PROPRIETARY" == literal) {
+ *result = RT_PROPRIETARY;
+ return true;
+ }
+ if ("QUERY_APPS" == literal) {
+ *result = RT_QUERY_APPS;
+ return true;
+ }
+ if ("LAUNCH_APP" == literal) {
+ *result = RT_LAUNCH_APP;
+ return true;
+ }
+ if ("LOCK_SCREEN_ICON_URL" == literal) {
+ *result = RT_LOCK_SCREEN_ICON_URL;
+ return true;
+ }
+ if ("TRAFFIC_MESSAGE_CHANNEL" == literal) {
+ *result = RT_TRAFFIC_MESSAGE_CHANNEL;
+ return true;
+ }
+ if ("DRIVER_PROFILE" == literal) {
+ *result = RT_DRIVER_PROFILE;
+ return true;
+ }
+ if ("VOICE_SEARCH" == literal) {
+ *result = RT_VOICE_SEARCH;
+ return true;
+ }
+ if ("NAVIGATION" == literal) {
+ *result = RT_NAVIGATION;
+ return true;
+ }
+ if ("PHONE" == literal) {
+ *result = RT_PHONE;
+ return true;
+ }
+ if ("CLIMATE" == literal) {
+ *result = RT_CLIMATE;
+ return true;
+ }
+ if ("SETTINGS" == literal) {
+ *result = RT_SETTINGS;
+ return true;
+ }
+ if ("VEHICLE_DIAGNOSTICS" == literal) {
+ *result = RT_VEHICLE_DIAGNOSTICS;
+ return true;
+ }
+ if ("EMERGENCY" == literal) {
+ *result = RT_EMERGENCY;
+ return true;
+ }
+ if ("MEDIA" == literal) {
+ *result = RT_MEDIA;
+ return true;
+ }
+ if ("FOTA" == literal) {
+ *result = RT_FOTA;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+const std::string kDefaultApp = "default";
+const std::string kPreDataConsentApp = "pre_DataConsent";
+const std::string kDeviceApp = "device";
+
+} // namespace policy_table_interface_base
+} // namespace rpc
diff --git a/src/components/policy/policy_regular/src/policy_table/types.cc b/src/components/policy/policy_regular/src/policy_table/types.cc
new file mode 100644
index 0000000000..7928973919
--- /dev/null
+++ b/src/components/policy/policy_regular/src/policy_table/types.cc
@@ -0,0 +1,1389 @@
+// This file is generated, do not edit
+#include "policy/policy_table/types.h"
+#include "rpc_base/rpc_base_json_inl.h"
+
+namespace rpc {
+namespace policy_table_interface_base {
+
+std::string PolicyTableTypeToString(const PolicyTableType pt_type) {
+ switch (pt_type) {
+ case PT_PRELOADED: {
+ return "PT_PRELOADED";
+ }
+ case PT_UPDATE: {
+ return "PT_UPDATE";
+ }
+ case PT_SNAPSHOT: {
+ return "PT_SNAPSHOT";
+ }
+ default: { return "INVALID_PT_TYPE"; }
+ }
+}
+
+// PolicyBase methods
+PolicyBase::PolicyBase() : CompositeType(kUninitialized) {}
+
+PolicyBase::PolicyBase(Priority priority)
+ : CompositeType(kUninitialized), priority(priority) {}
+
+PolicyBase::~PolicyBase() {}
+
+PolicyBase::PolicyBase(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , priority(impl::ValueMember(value__, "priority")) {}
+
+Json::Value PolicyBase::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("priority", priority, &result__);
+ return result__;
+}
+
+bool PolicyBase::is_valid() const {
+ if (!priority.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool PolicyBase::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool PolicyBase::struct_empty() const {
+ if (priority.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+void PolicyBase::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!priority.is_valid()) {
+ priority.ReportErrors(&report__->ReportSubobject("priority"));
+ }
+}
+
+void PolicyBase::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ priority.SetPolicyTableType(pt_type);
+}
+
+// DevicePolicy methods
+DevicePolicy::DevicePolicy() : PolicyBase() {}
+
+DevicePolicy::DevicePolicy(Priority priority) : PolicyBase(priority) {}
+
+DevicePolicy::~DevicePolicy() {}
+
+DevicePolicy::DevicePolicy(const Json::Value* value__) : PolicyBase(value__) {}
+
+// AppPoliciesSection methods
+ApplicationPoliciesSection::ApplicationPoliciesSection()
+ : CompositeType(kUninitialized) {}
+
+ApplicationPoliciesSection::ApplicationPoliciesSection(
+ const ApplicationPolicies& apps, const DevicePolicy& device)
+ : CompositeType(kUninitialized), apps(apps), device(device) {}
+
+ApplicationPoliciesSection::~ApplicationPoliciesSection() {}
+
+ApplicationPoliciesSection::ApplicationPoliciesSection(
+ const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , apps(value__)
+ , device(impl::ValueMember(value__, "device")) {
+ // Since "device" is moved to separate struct, we have to delete it from
+ // parsed apps to avoid validation issues due to possible wrong params in
+ // device section
+ apps.erase("device");
+}
+
+Json::Value ApplicationPoliciesSection::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ result__ = apps.ToJsonValue();
+ impl::WriteJsonField("device", device, &result__);
+ return result__;
+}
+
+bool ApplicationPoliciesSection::is_valid() const {
+ if (!device.is_valid()) {
+ return false;
+ }
+ if (!apps.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool ApplicationPoliciesSection::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool ApplicationPoliciesSection::struct_empty() const {
+ if (device.is_initialized()) {
+ return false;
+ }
+ if (apps.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+void ApplicationPoliciesSection::ReportErrors(
+ rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!device.is_valid()) {
+ device.ReportErrors(&report__->ReportSubobject("device"));
+ }
+ if (!apps.is_valid()) {
+ apps.ReportErrors(&report__->ReportSubobject("apps"));
+ }
+}
+
+void ApplicationPoliciesSection::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ device.SetPolicyTableType(pt_type);
+ apps.SetPolicyTableType(pt_type);
+}
+
+// ApplicationParams methods
+ApplicationParams::ApplicationParams() : PolicyBase(), groups() {}
+
+ApplicationParams::ApplicationParams(const Strings& groups, Priority priority)
+ : PolicyBase(priority), groups(groups) {}
+
+ApplicationParams::~ApplicationParams() {}
+
+ApplicationParams::ApplicationParams(const Json::Value* value__)
+ : PolicyBase(value__)
+ , groups(impl::ValueMember(value__, "groups"))
+ , nicknames(impl::ValueMember(value__, "nicknames"))
+ , AppHMIType(impl::ValueMember(value__, "AppHMIType"))
+ , RequestType(impl::ValueMember(value__, "RequestType"))
+ , memory_kb(impl::ValueMember(value__, "memory_kb"), 0)
+ , heart_beat_timeout_ms(impl::ValueMember(value__, "heart_beat_timeout_ms"))
+ , certificate(impl::ValueMember(value__, "certificate"), "not_specified") {}
+
+Json::Value ApplicationParams::ToJsonValue() const {
+ Json::Value result__(PolicyBase::ToJsonValue());
+ impl::WriteJsonField("groups", groups, &result__);
+ impl::WriteJsonField("nicknames", nicknames, &result__);
+ impl::WriteJsonField("AppHMIType", AppHMIType, &result__);
+ impl::WriteJsonField("RequestType", RequestType, &result__);
+ impl::WriteJsonField("memory_kb", memory_kb, &result__);
+ impl::WriteJsonField(
+ "heart_beat_timeout_ms", heart_beat_timeout_ms, &result__);
+ return result__;
+}
+
+bool ApplicationParams::is_valid() const {
+ // RequestType is not validated since there is high-level validation logic,
+ // which takes into account information not available here.
+ if (!PolicyBase::is_valid()) {
+ return false;
+ }
+ if (!groups.is_valid()) {
+ return false;
+ }
+ if (!nicknames.is_valid()) {
+ return false;
+ }
+ if (!AppHMIType.is_valid()) {
+ return false;
+ }
+ if (!memory_kb.is_valid()) {
+ return false;
+ }
+ if (!heart_beat_timeout_ms.is_valid()) {
+ return false;
+ }
+ if (!certificate.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+
+bool ApplicationParams::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+
+bool ApplicationParams::struct_empty() const {
+ if (!PolicyBase::is_initialized()) {
+ return false;
+ }
+ if (groups.is_initialized()) {
+ return false;
+ }
+ if (nicknames.is_initialized()) {
+ return false;
+ }
+ if (AppHMIType.is_initialized()) {
+ return false;
+ }
+ if (RequestType.is_initialized()) {
+ return false;
+ }
+ if (memory_kb.is_initialized()) {
+ return false;
+ }
+ if (heart_beat_timeout_ms.is_initialized()) {
+ return false;
+ }
+ if (certificate.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+void ApplicationParams::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!groups.is_valid()) {
+ groups.ReportErrors(&report__->ReportSubobject("groups"));
+ }
+ if (!nicknames.is_valid()) {
+ nicknames.ReportErrors(&report__->ReportSubobject("nicknames"));
+ }
+ if (!AppHMIType.is_valid()) {
+ AppHMIType.ReportErrors(&report__->ReportSubobject("AppHMIType"));
+ }
+ if (!RequestType.is_valid()) {
+ RequestType.ReportErrors(&report__->ReportSubobject("RequestType"));
+ }
+ if (!priority.is_valid()) {
+ priority.ReportErrors(&report__->ReportSubobject("priority"));
+ }
+ if (!memory_kb.is_valid()) {
+ memory_kb.ReportErrors(&report__->ReportSubobject("memory_kb"));
+ }
+ if (!heart_beat_timeout_ms.is_valid()) {
+ heart_beat_timeout_ms.ReportErrors(
+ &report__->ReportSubobject("heart_beat_timeout_ms"));
+ }
+ if (!certificate.is_valid()) {
+ certificate.ReportErrors(&report__->ReportSubobject("certificate"));
+ }
+}
+
+void ApplicationParams::SetPolicyTableType(PolicyTableType pt_type) {
+ PolicyBase::SetPolicyTableType(pt_type);
+ groups.SetPolicyTableType(pt_type);
+ AppHMIType.SetPolicyTableType(pt_type);
+ RequestType.SetPolicyTableType(pt_type);
+ memory_kb.SetPolicyTableType(pt_type);
+ heart_beat_timeout_ms.SetPolicyTableType(pt_type);
+ certificate.SetPolicyTableType(pt_type);
+}
+
+// RpcParameters methods
+RpcParameters::RpcParameters() : CompositeType(kUninitialized) {}
+RpcParameters::RpcParameters(const HmiLevels& hmi_levels)
+ : CompositeType(kUninitialized), hmi_levels(hmi_levels) {}
+RpcParameters::~RpcParameters() {}
+RpcParameters::RpcParameters(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , hmi_levels(impl::ValueMember(value__, "hmi_levels"))
+ , parameters(impl::ValueMember(value__, "parameters")) {}
+Json::Value RpcParameters::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("hmi_levels", hmi_levels, &result__);
+ impl::WriteJsonField("parameters", parameters, &result__);
+ return result__;
+}
+bool RpcParameters::is_valid() const {
+ if (!hmi_levels.is_valid()) {
+ return false;
+ }
+ if (!parameters.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+bool RpcParameters::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+bool RpcParameters::struct_empty() const {
+ if (hmi_levels.is_initialized()) {
+ return false;
+ }
+ if (parameters.is_initialized()) {
+ return false;
+ }
+
+ return true;
+}
+void RpcParameters::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!hmi_levels.is_valid()) {
+ hmi_levels.ReportErrors(&report__->ReportSubobject("hmi_levels"));
+ }
+ if (!parameters.is_valid()) {
+ parameters.ReportErrors(&report__->ReportSubobject("parameters"));
+ }
+}
+
+void RpcParameters::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ hmi_levels.SetPolicyTableType(pt_type);
+ parameters.SetPolicyTableType(pt_type);
+}
+
+// Rpcs methods
+Rpcs::Rpcs() : CompositeType(kUninitialized) {}
+Rpcs::Rpcs(const Rpc& rpcs) : CompositeType(kUninitialized), rpcs(rpcs) {}
+Rpcs::~Rpcs() {}
+Rpcs::Rpcs(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , user_consent_prompt(impl::ValueMember(value__, "user_consent_prompt"))
+ , rpcs(impl::ValueMember(value__, "rpcs")) {}
+Json::Value Rpcs::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("user_consent_prompt", user_consent_prompt, &result__);
+ impl::WriteJsonField("rpcs", rpcs, &result__);
+ return result__;
+}
+bool Rpcs::is_valid() const {
+ if (!user_consent_prompt.is_valid()) {
+ return false;
+ }
+ if (!rpcs.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+bool Rpcs::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+bool Rpcs::struct_empty() const {
+ if (user_consent_prompt.is_initialized()) {
+ return false;
+ }
+ if (rpcs.is_initialized()) {
+ return false;
+ }
+
+ return true;
+}
+void Rpcs::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!user_consent_prompt.is_valid()) {
+ user_consent_prompt.ReportErrors(
+ &report__->ReportSubobject("user_consent_prompt"));
+ }
+ if (!rpcs.is_valid()) {
+ rpcs.ReportErrors(&report__->ReportSubobject("rpcs"));
+ }
+}
+
+void Rpcs::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ user_consent_prompt.SetPolicyTableType(pt_type);
+ rpcs.SetPolicyTableType(pt_type);
+}
+
+// ModuleConfig methods
+ModuleConfig::ModuleConfig() : CompositeType(kUninitialized) {}
+ModuleConfig::ModuleConfig(
+ uint8_t exchange_after_x_ignition_cycles,
+ int64_t exchange_after_x_kilometers,
+ uint8_t exchange_after_x_days,
+ uint16_t timeout_after_x_seconds,
+ const SecondsBetweenRetries& seconds_between_retries,
+ const ServiceEndpoints& endpoints,
+ const NumberOfNotificationsPerMinute& notifications_per_minute_by_priority)
+ : CompositeType(kUninitialized)
+ , exchange_after_x_ignition_cycles(exchange_after_x_ignition_cycles)
+ , exchange_after_x_kilometers(exchange_after_x_kilometers)
+ , exchange_after_x_days(exchange_after_x_days)
+ , timeout_after_x_seconds(timeout_after_x_seconds)
+ , seconds_between_retries(seconds_between_retries)
+ , endpoints(endpoints)
+ , notifications_per_minute_by_priority(
+ notifications_per_minute_by_priority) {}
+ModuleConfig::~ModuleConfig() {}
+ModuleConfig::ModuleConfig(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , device_certificates(impl::ValueMember(value__, "device_certificates"))
+ , preloaded_pt(impl::ValueMember(value__, "preloaded_pt"))
+ , exchange_after_x_ignition_cycles(
+ impl::ValueMember(value__, "exchange_after_x_ignition_cycles"))
+ , exchange_after_x_kilometers(
+ impl::ValueMember(value__, "exchange_after_x_kilometers"))
+ , exchange_after_x_days(impl::ValueMember(value__, "exchange_after_x_days"))
+ , timeout_after_x_seconds(
+ impl::ValueMember(value__, "timeout_after_x_seconds"))
+ , seconds_between_retries(
+ impl::ValueMember(value__, "seconds_between_retries"))
+ , endpoints(impl::ValueMember(value__, "endpoints"))
+ , notifications_per_minute_by_priority(
+ impl::ValueMember(value__, "notifications_per_minute_by_priority"))
+ , vehicle_make(impl::ValueMember(value__, "vehicle_make"))
+ , vehicle_model(impl::ValueMember(value__, "vehicle_model"))
+ , vehicle_year(impl::ValueMember(value__, "vehicle_year"))
+ , preloaded_date(impl::ValueMember(value__, "preloaded_date"))
+ , certificate(impl::ValueMember(value__, "certificate")) {}
+
+void ModuleConfig::SafeCopyFrom(const ModuleConfig& from) {
+ // device_certificates = from.device_certificates; // According to the
+ // requirements this is optional.
+ exchange_after_x_ignition_cycles = from.exchange_after_x_ignition_cycles;
+ exchange_after_x_kilometers = from.exchange_after_x_kilometers;
+ exchange_after_x_days = from.exchange_after_x_days;
+ timeout_after_x_seconds = from.timeout_after_x_seconds;
+ seconds_between_retries = from.seconds_between_retries;
+ endpoints = from.endpoints;
+ notifications_per_minute_by_priority =
+ from.notifications_per_minute_by_priority;
+
+ vehicle_make.assign_if_valid(from.vehicle_make);
+ vehicle_model.assign_if_valid(from.vehicle_model);
+ vehicle_year.assign_if_valid(from.vehicle_year);
+ certificate.assign_if_valid(from.certificate);
+}
+
+Json::Value ModuleConfig::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("preloaded_pt", preloaded_pt, &result__);
+ impl::WriteJsonField("exchange_after_x_ignition_cycles",
+ exchange_after_x_ignition_cycles,
+ &result__);
+ impl::WriteJsonField(
+ "exchange_after_x_kilometers", exchange_after_x_kilometers, &result__);
+ impl::WriteJsonField(
+ "exchange_after_x_days", exchange_after_x_days, &result__);
+ impl::WriteJsonField(
+ "timeout_after_x_seconds", timeout_after_x_seconds, &result__);
+ impl::WriteJsonField(
+ "seconds_between_retries", seconds_between_retries, &result__);
+ impl::WriteJsonField("endpoints", endpoints, &result__);
+ impl::WriteJsonField("notifications_per_minute_by_priority",
+ notifications_per_minute_by_priority,
+ &result__);
+ impl::WriteJsonField("vehicle_make", vehicle_make, &result__);
+ impl::WriteJsonField("vehicle_model", vehicle_model, &result__);
+ impl::WriteJsonField("vehicle_year", vehicle_year, &result__);
+ impl::WriteJsonField("certificate", certificate, &result__);
+ impl::WriteJsonField("preloaded_date", preloaded_date, &result__);
+ return result__;
+}
+bool ModuleConfig::is_valid() const {
+ if (!preloaded_pt.is_valid()) {
+ return false;
+ }
+ if (!exchange_after_x_ignition_cycles.is_valid()) {
+ return false;
+ }
+ if (!exchange_after_x_kilometers.is_valid()) {
+ return false;
+ }
+ if (!exchange_after_x_days.is_valid()) {
+ return false;
+ }
+ if (!timeout_after_x_seconds.is_valid()) {
+ return false;
+ }
+ if (!seconds_between_retries.is_valid()) {
+ return false;
+ }
+ if (!endpoints.is_valid()) {
+ return false;
+ }
+ if (!notifications_per_minute_by_priority.is_valid()) {
+ return false;
+ }
+ if (!vehicle_make.is_valid()) {
+ return false;
+ }
+ if (!vehicle_model.is_valid()) {
+ return false;
+ }
+ if (!vehicle_year.is_valid()) {
+ return false;
+ }
+ if (!certificate.is_valid()) {
+ return false;
+ }
+ if (!preloaded_date.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+bool ModuleConfig::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+bool ModuleConfig::struct_empty() const {
+ if (preloaded_pt.is_initialized()) {
+ return false;
+ }
+
+ if (exchange_after_x_ignition_cycles.is_initialized()) {
+ return false;
+ }
+ if (exchange_after_x_kilometers.is_initialized()) {
+ return false;
+ }
+
+ if (exchange_after_x_days.is_initialized()) {
+ return false;
+ }
+ if (timeout_after_x_seconds.is_initialized()) {
+ return false;
+ }
+
+ if (seconds_between_retries.is_initialized()) {
+ return false;
+ }
+ if (endpoints.is_initialized()) {
+ return false;
+ }
+
+ if (notifications_per_minute_by_priority.is_initialized()) {
+ return false;
+ }
+ if (vehicle_make.is_initialized()) {
+ return false;
+ }
+
+ if (vehicle_model.is_initialized()) {
+ return false;
+ }
+ if (vehicle_year.is_initialized()) {
+ return false;
+ }
+
+ return true;
+}
+void ModuleConfig::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!device_certificates.is_valid()) {
+ device_certificates.ReportErrors(
+ &report__->ReportSubobject("device_certificates"));
+ }
+ if (!preloaded_pt.is_valid()) {
+ preloaded_pt.ReportErrors(&report__->ReportSubobject("preloaded_pt"));
+ }
+ if (!exchange_after_x_ignition_cycles.is_valid()) {
+ exchange_after_x_ignition_cycles.ReportErrors(
+ &report__->ReportSubobject("exchange_after_x_ignition_cycles"));
+ }
+ if (!exchange_after_x_kilometers.is_valid()) {
+ exchange_after_x_kilometers.ReportErrors(
+ &report__->ReportSubobject("exchange_after_x_kilometers"));
+ }
+ if (!exchange_after_x_days.is_valid()) {
+ exchange_after_x_days.ReportErrors(
+ &report__->ReportSubobject("exchange_after_x_days"));
+ }
+ if (!timeout_after_x_seconds.is_valid()) {
+ timeout_after_x_seconds.ReportErrors(
+ &report__->ReportSubobject("timeout_after_x_seconds"));
+ }
+ if (!seconds_between_retries.is_valid()) {
+ seconds_between_retries.ReportErrors(
+ &report__->ReportSubobject("seconds_between_retries"));
+ }
+ if (!endpoints.is_valid()) {
+ endpoints.ReportErrors(&report__->ReportSubobject("endpoints"));
+ }
+ if (!notifications_per_minute_by_priority.is_valid()) {
+ notifications_per_minute_by_priority.ReportErrors(
+ &report__->ReportSubobject("notifications_per_minute_by_priority"));
+ }
+ if (!vehicle_make.is_valid()) {
+ vehicle_make.ReportErrors(&report__->ReportSubobject("vehicle_make"));
+ }
+ if (!vehicle_model.is_valid()) {
+ vehicle_model.ReportErrors(&report__->ReportSubobject("vehicle_model"));
+ }
+ if (!vehicle_year.is_valid()) {
+ vehicle_year.ReportErrors(&report__->ReportSubobject("vehicle_year"));
+ }
+ if (PT_PRELOADED == GetPolicyTableType()) {
+ std::string validation_info =
+ omitted_validation_info + PolicyTableTypeToString(GetPolicyTableType());
+ rpc::ValidationReport* omitted_field_report;
+ if (vehicle_make.is_initialized()) {
+ omitted_field_report = &report__->ReportSubobject("vehicle_make");
+ omitted_field_report->set_validation_info(validation_info);
+ }
+ if (vehicle_year.is_initialized()) {
+ omitted_field_report = &report__->ReportSubobject("vehicle_year");
+ omitted_field_report->set_validation_info(validation_info);
+ }
+ if (vehicle_model.is_initialized()) {
+ omitted_field_report = &report__->ReportSubobject("vehicle_model");
+ omitted_field_report->set_validation_info(validation_info);
+ }
+ }
+}
+
+void ModuleConfig::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ preloaded_pt.SetPolicyTableType(pt_type);
+ exchange_after_x_ignition_cycles.SetPolicyTableType(pt_type);
+ exchange_after_x_kilometers.SetPolicyTableType(pt_type);
+ exchange_after_x_days.SetPolicyTableType(pt_type);
+ timeout_after_x_seconds.SetPolicyTableType(pt_type);
+ seconds_between_retries.SetPolicyTableType(pt_type);
+ endpoints.SetPolicyTableType(pt_type);
+ notifications_per_minute_by_priority.SetPolicyTableType(pt_type);
+ vehicle_make.SetPolicyTableType(pt_type);
+ vehicle_model.SetPolicyTableType(pt_type);
+ vehicle_year.SetPolicyTableType(pt_type);
+}
+
+// MessageString methods
+MessageString::MessageString() : CompositeType(kUninitialized) {}
+MessageString::~MessageString() {}
+MessageString::MessageString(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , line1(impl::ValueMember(value__, "line1"))
+ , line2(impl::ValueMember(value__, "line2"))
+ , tts(impl::ValueMember(value__, "tts"))
+ , label(impl::ValueMember(value__, "label"))
+ , textBody(impl::ValueMember(value__, "textBody")) {}
+Json::Value MessageString::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("line1", line1, &result__);
+ impl::WriteJsonField("line2", line2, &result__);
+ impl::WriteJsonField("tts", tts, &result__);
+ impl::WriteJsonField("label", label, &result__);
+ impl::WriteJsonField("textBody", textBody, &result__);
+ return result__;
+}
+bool MessageString::is_valid() const {
+ if (struct_empty()) {
+ return initialization_state__ == kInitialized && Validate();
+ }
+ if (!line1.is_valid()) {
+ return false;
+ }
+ if (!line2.is_valid()) {
+ return false;
+ }
+ if (!tts.is_valid()) {
+ return false;
+ }
+ if (!label.is_valid()) {
+ return false;
+ }
+ if (!textBody.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+bool MessageString::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+bool MessageString::struct_empty() const {
+ if (line1.is_initialized()) {
+ return false;
+ }
+ if (line2.is_initialized()) {
+ return false;
+ }
+
+ if (tts.is_initialized()) {
+ return false;
+ }
+ if (label.is_initialized()) {
+ return false;
+ }
+
+ if (textBody.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+void MessageString::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!line1.is_valid()) {
+ line1.ReportErrors(&report__->ReportSubobject("line1"));
+ }
+ if (!line2.is_valid()) {
+ line2.ReportErrors(&report__->ReportSubobject("line2"));
+ }
+ if (!tts.is_valid()) {
+ tts.ReportErrors(&report__->ReportSubobject("tts"));
+ }
+ if (!label.is_valid()) {
+ label.ReportErrors(&report__->ReportSubobject("label"));
+ }
+ if (!textBody.is_valid()) {
+ textBody.ReportErrors(&report__->ReportSubobject("textBody"));
+ }
+}
+
+void MessageString::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ line1.SetPolicyTableType(pt_type);
+ line2.SetPolicyTableType(pt_type);
+ tts.SetPolicyTableType(pt_type);
+ label.SetPolicyTableType(pt_type);
+ textBody.SetPolicyTableType(pt_type);
+}
+
+// MessageLanguages methods
+MessageLanguages::MessageLanguages() : CompositeType(kUninitialized) {}
+MessageLanguages::MessageLanguages(const Languages& languages)
+ : CompositeType(kUninitialized), languages(languages) {}
+MessageLanguages::~MessageLanguages() {}
+MessageLanguages::MessageLanguages(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , languages(impl::ValueMember(value__, "languages")) {}
+Json::Value MessageLanguages::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("languages", languages, &result__);
+ return result__;
+}
+bool MessageLanguages::is_valid() const {
+ if (!languages.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+bool MessageLanguages::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+bool MessageLanguages::struct_empty() const {
+ if (languages.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+void MessageLanguages::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (PT_SNAPSHOT == GetPolicyTableType()) {
+ if (languages.is_initialized()) {
+ std::string validation_info =
+ omitted_validation_info +
+ PolicyTableTypeToString(GetPolicyTableType());
+ report__->ReportSubobject("languages")
+ .set_validation_info(validation_info);
+ }
+ }
+ if (!languages.is_valid()) {
+ languages.ReportErrors(&report__->ReportSubobject("languages"));
+ }
+}
+
+void MessageLanguages::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ languages.SetPolicyTableType(pt_type);
+}
+
+// ConsumerFriendlyMessages methods
+ConsumerFriendlyMessages::ConsumerFriendlyMessages()
+ : CompositeType(kUninitialized) {}
+ConsumerFriendlyMessages::ConsumerFriendlyMessages(const std::string& version)
+ : CompositeType(kUninitialized), version(version) {}
+ConsumerFriendlyMessages::~ConsumerFriendlyMessages() {}
+ConsumerFriendlyMessages::ConsumerFriendlyMessages(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , version(impl::ValueMember(value__, "version"))
+ , messages(impl::ValueMember(value__, "messages")) {}
+Json::Value ConsumerFriendlyMessages::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("version", version, &result__);
+ impl::WriteJsonField("messages", messages, &result__);
+ return result__;
+}
+bool ConsumerFriendlyMessages::is_valid() const {
+ if (!version.is_valid()) {
+ return false;
+ }
+ if (!messages.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+bool ConsumerFriendlyMessages::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+bool ConsumerFriendlyMessages::struct_empty() const {
+ if (version.is_initialized()) {
+ return false;
+ }
+ if (messages.is_initialized()) {
+ return false;
+ }
+
+ return true;
+}
+void ConsumerFriendlyMessages::ReportErrors(
+ rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!version.is_valid()) {
+ version.ReportErrors(&report__->ReportSubobject("version"));
+ }
+ if (PT_SNAPSHOT == GetPolicyTableType()) {
+ if (messages.is_initialized()) {
+ std::string validation_info =
+ omitted_validation_info +
+ PolicyTableTypeToString(GetPolicyTableType());
+ report__->ReportSubobject("messages")
+ .set_validation_info(validation_info);
+ }
+ }
+ if (!messages.is_valid()) {
+ messages.ReportErrors(&report__->ReportSubobject("messages"));
+ }
+}
+
+void ConsumerFriendlyMessages::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ version.SetPolicyTableType(pt_type);
+ messages.SetPolicyTableType(pt_type);
+}
+
+// ModuleMeta methods
+ModuleMeta::ModuleMeta() : CompositeType(kUninitialized) {}
+ModuleMeta::~ModuleMeta() {}
+ModuleMeta::ModuleMeta(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , pt_exchanged_at_odometer_x(
+ impl::ValueMember(value__, "pt_exchanged_at_odometer_x"))
+ , pt_exchanged_x_days_after_epoch(
+ impl::ValueMember(value__, "pt_exchanged_x_days_after_epoch"))
+ , ignition_cycles_since_last_exchange(
+ impl::ValueMember(value__, "ignition_cycles_since_last_exchange")) {}
+Json::Value ModuleMeta::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField(
+ "pt_exchanged_at_odometer_x", pt_exchanged_at_odometer_x, &result__);
+ impl::WriteJsonField("pt_exchanged_x_days_after_epoch",
+ pt_exchanged_x_days_after_epoch,
+ &result__);
+ impl::WriteJsonField("ignition_cycles_since_last_exchange",
+ ignition_cycles_since_last_exchange,
+ &result__);
+ return result__;
+}
+bool ModuleMeta::is_valid() const {
+ if (struct_empty()) {
+ return initialization_state__ == kInitialized && Validate();
+ }
+ if (!pt_exchanged_at_odometer_x.is_valid()) {
+ return false;
+ }
+ if (!pt_exchanged_x_days_after_epoch.is_valid()) {
+ return false;
+ }
+ if (!ignition_cycles_since_last_exchange.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+bool ModuleMeta::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+bool ModuleMeta::struct_empty() const {
+ if (pt_exchanged_at_odometer_x.is_initialized()) {
+ return false;
+ }
+
+ if (pt_exchanged_x_days_after_epoch.is_initialized()) {
+ return false;
+ }
+ if (ignition_cycles_since_last_exchange.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+void ModuleMeta::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!pt_exchanged_at_odometer_x.is_valid()) {
+ pt_exchanged_at_odometer_x.ReportErrors(
+ &report__->ReportSubobject("pt_exchanged_at_odometer_x"));
+ }
+ if (!pt_exchanged_x_days_after_epoch.is_valid()) {
+ pt_exchanged_x_days_after_epoch.ReportErrors(
+ &report__->ReportSubobject("pt_exchanged_x_days_after_epoch"));
+ }
+ if (!ignition_cycles_since_last_exchange.is_valid()) {
+ ignition_cycles_since_last_exchange.ReportErrors(
+ &report__->ReportSubobject("ignition_cycles_since_last_exchange"));
+ }
+}
+
+void ModuleMeta::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ pt_exchanged_at_odometer_x.SetPolicyTableType(pt_type);
+ pt_exchanged_x_days_after_epoch.SetPolicyTableType(pt_type);
+ ignition_cycles_since_last_exchange.SetPolicyTableType(pt_type);
+}
+
+// AppLevel methods
+AppLevel::AppLevel() : CompositeType(kUninitialized) {}
+
+AppLevel::AppLevel(uint16_t minutes_in_hmi_full,
+ const std::string& app_registration_language_gui,
+ const std::string& app_registration_language_vui,
+ uint16_t minutes_in_hmi_limited,
+ uint16_t minutes_in_hmi_background,
+ uint16_t minutes_in_hmi_none,
+ uint16_t count_of_user_selections,
+ uint16_t count_of_rejections_sync_out_of_memory,
+ uint16_t count_of_rejections_nickname_mismatch,
+ uint16_t count_of_rejections_duplicate_name,
+ uint16_t count_of_rejected_rpc_calls,
+ uint16_t count_of_rpcs_sent_in_hmi_none,
+ uint16_t count_of_removals_for_bad_behavior,
+ uint16_t count_of_tls_errors,
+ uint16_t count_of_run_attempts_while_revoked)
+ : CompositeType(kUninitialized)
+ , minutes_in_hmi_full(minutes_in_hmi_full)
+ , app_registration_language_gui(app_registration_language_gui)
+ , app_registration_language_vui(app_registration_language_vui)
+ , minutes_in_hmi_limited(minutes_in_hmi_limited)
+ , minutes_in_hmi_background(minutes_in_hmi_background)
+ , minutes_in_hmi_none(minutes_in_hmi_none)
+ , count_of_user_selections(count_of_user_selections)
+ , count_of_rejections_sync_out_of_memory(
+ count_of_rejections_sync_out_of_memory)
+ , count_of_rejections_nickname_mismatch(
+ count_of_rejections_nickname_mismatch)
+ , count_of_rejections_duplicate_name(count_of_rejections_duplicate_name)
+ , count_of_rejected_rpc_calls(count_of_rejected_rpc_calls)
+ , count_of_rpcs_sent_in_hmi_none(count_of_rpcs_sent_in_hmi_none)
+ , count_of_removals_for_bad_behavior(count_of_removals_for_bad_behavior)
+ , count_of_tls_errors(count_of_tls_errors)
+ , count_of_run_attempts_while_revoked(count_of_run_attempts_while_revoked) {
+}
+AppLevel::~AppLevel() {}
+AppLevel::AppLevel(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , minutes_in_hmi_full(impl::ValueMember(value__, "minutes_in_hmi_full"))
+ , app_registration_language_gui(
+ impl::ValueMember(value__, "app_registration_language_gui"))
+ , app_registration_language_vui(
+ impl::ValueMember(value__, "app_registration_language_vui"))
+ , minutes_in_hmi_limited(
+ impl::ValueMember(value__, "minutes_in_hmi_limited"))
+ , minutes_in_hmi_background(
+ impl::ValueMember(value__, "minutes_in_hmi_background"))
+ , minutes_in_hmi_none(impl::ValueMember(value__, "minutes_in_hmi_none"))
+ , count_of_user_selections(
+ impl::ValueMember(value__, "count_of_user_selections"))
+ , count_of_rejections_sync_out_of_memory(
+ impl::ValueMember(value__, "count_of_rejections_sync_out_of_memory"))
+ , count_of_rejections_nickname_mismatch(
+ impl::ValueMember(value__, "count_of_rejections_nickname_mismatch"))
+ , count_of_rejections_duplicate_name(
+ impl::ValueMember(value__, "count_of_rejections_duplicate_name"))
+ , count_of_rejected_rpc_calls(
+ impl::ValueMember(value__, "count_of_rejected_rpc_calls"))
+ , count_of_rpcs_sent_in_hmi_none(
+ impl::ValueMember(value__, "count_of_rpcs_sent_in_hmi_none"))
+ , count_of_removals_for_bad_behavior(
+ impl::ValueMember(value__, "count_of_removals_for_bad_behavior"))
+ , count_of_tls_errors(impl::ValueMember(value__, "count_of_tls_errors"))
+ , count_of_run_attempts_while_revoked(
+ impl::ValueMember(value__, "count_of_run_attempts_while_revoked")) {}
+
+Json::Value AppLevel::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("count_of_TLS_errors", count_of_tls_errors, &result__);
+ return result__;
+}
+bool AppLevel::is_valid() const {
+ if (!minutes_in_hmi_full.is_valid()) {
+ return false;
+ }
+ if (!app_registration_language_gui.is_valid()) {
+ return false;
+ }
+ if (!app_registration_language_vui.is_valid()) {
+ return false;
+ }
+ if (!minutes_in_hmi_limited.is_valid()) {
+ return false;
+ }
+ if (!minutes_in_hmi_background.is_valid()) {
+ return false;
+ }
+ if (!minutes_in_hmi_none.is_valid()) {
+ return false;
+ }
+ if (!count_of_user_selections.is_valid()) {
+ return false;
+ }
+ if (!count_of_rejections_sync_out_of_memory.is_valid()) {
+ return false;
+ }
+ if (!count_of_rejections_nickname_mismatch.is_valid()) {
+ return false;
+ }
+ if (!count_of_rejections_duplicate_name.is_valid()) {
+ return false;
+ }
+ if (!count_of_rejected_rpc_calls.is_valid()) {
+ return false;
+ }
+ if (!count_of_rpcs_sent_in_hmi_none.is_valid()) {
+ return false;
+ }
+ if (!count_of_removals_for_bad_behavior.is_valid()) {
+ return false;
+ }
+ if (!count_of_tls_errors.is_valid()) {
+ return false;
+ }
+ if (!count_of_run_attempts_while_revoked.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+bool AppLevel::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+bool AppLevel::struct_empty() const {
+ if (minutes_in_hmi_full.is_initialized()) {
+ return false;
+ }
+ if (app_registration_language_gui.is_initialized()) {
+ return false;
+ }
+
+ if (app_registration_language_vui.is_initialized()) {
+ return false;
+ }
+
+ if (minutes_in_hmi_limited.is_initialized()) {
+ return false;
+ }
+ if (minutes_in_hmi_background.is_initialized()) {
+ return false;
+ }
+
+ if (minutes_in_hmi_none.is_initialized()) {
+ return false;
+ }
+ if (count_of_user_selections.is_initialized()) {
+ return false;
+ }
+
+ if (count_of_rejections_sync_out_of_memory.is_initialized()) {
+ return false;
+ }
+ if (count_of_rejections_nickname_mismatch.is_initialized()) {
+ return false;
+ }
+
+ if (count_of_rejections_duplicate_name.is_initialized()) {
+ return false;
+ }
+ if (count_of_rejected_rpc_calls.is_initialized()) {
+ return false;
+ }
+
+ if (count_of_rpcs_sent_in_hmi_none.is_initialized()) {
+ return false;
+ }
+ if (count_of_removals_for_bad_behavior.is_initialized()) {
+ return false;
+ }
+ if (count_of_tls_errors.is_initialized()) {
+ return false;
+ }
+ if (count_of_run_attempts_while_revoked.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+void AppLevel::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (PT_PRELOADED == GetPolicyTableType() ||
+ PT_UPDATE == GetPolicyTableType()) {
+ std::string validation_info =
+ omitted_validation_info + PolicyTableTypeToString(GetPolicyTableType());
+ report__->set_validation_info(validation_info);
+ }
+}
+
+// UsageAndErrorCounts methods
+UsageAndErrorCounts::UsageAndErrorCounts() : CompositeType(kUninitialized) {}
+
+UsageAndErrorCounts::~UsageAndErrorCounts() {}
+UsageAndErrorCounts::UsageAndErrorCounts(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , app_level(impl::ValueMember(value__, "app_level")) {}
+Json::Value UsageAndErrorCounts::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("app_level", app_level, &result__);
+ return result__;
+}
+bool UsageAndErrorCounts::is_valid() const {
+ if (struct_empty()) {
+ return initialization_state__ == kInitialized && Validate();
+ }
+ if (!app_level.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+bool UsageAndErrorCounts::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+bool UsageAndErrorCounts::struct_empty() const {
+ if (app_level.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+void UsageAndErrorCounts::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (PT_PRELOADED == GetPolicyTableType() ||
+ PT_UPDATE == GetPolicyTableType()) {
+ std::string validation_info =
+ omitted_validation_info + PolicyTableTypeToString(GetPolicyTableType());
+ report__->set_validation_info(validation_info);
+ }
+ if (!app_level.is_valid()) {
+ app_level.ReportErrors(&report__->ReportSubobject("app_level"));
+ }
+}
+
+void UsageAndErrorCounts::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ app_level.SetPolicyTableType(pt_type);
+}
+
+// DeviceParams methods
+DeviceParams::DeviceParams() : CompositeType(kUninitialized) {}
+DeviceParams::~DeviceParams() {}
+DeviceParams::DeviceParams(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject)) {}
+Json::Value DeviceParams::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ return result__;
+}
+bool DeviceParams::is_valid() const {
+ if (struct_empty()) {
+ return initialization_state__ == kInitialized && Validate();
+ }
+ return Validate();
+}
+bool DeviceParams::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+bool DeviceParams::struct_empty() const {
+ return true;
+}
+void DeviceParams::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+}
+
+// PolicyTable methods
+PolicyTable::PolicyTable() : CompositeType(kUninitialized) {}
+PolicyTable::PolicyTable(
+ const ApplicationPoliciesSection& app_policies_section,
+ const FunctionalGroupings& functional_groupings,
+ const ConsumerFriendlyMessages& consumer_friendly_messages,
+ const ModuleConfig& module_config)
+ : CompositeType(kUninitialized)
+ , app_policies_section(app_policies_section)
+ , functional_groupings(functional_groupings)
+ , consumer_friendly_messages(consumer_friendly_messages)
+ , module_config(module_config) {}
+PolicyTable::~PolicyTable() {}
+PolicyTable::PolicyTable(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , app_policies_section(impl::ValueMember(value__, "app_policies"))
+ , functional_groupings(impl::ValueMember(value__, "functional_groupings"))
+ , consumer_friendly_messages(
+ impl::ValueMember(value__, "consumer_friendly_messages"))
+ , module_config(impl::ValueMember(value__, "module_config"))
+ , module_meta(impl::ValueMember(value__, "module_meta"))
+ , usage_and_error_counts(
+ impl::ValueMember(value__, "usage_and_error_counts"))
+ , device_data(impl::ValueMember(value__, "device_data")) {}
+Json::Value PolicyTable::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("app_policies", app_policies_section, &result__);
+ impl::WriteJsonField("functional_groupings", functional_groupings, &result__);
+ impl::WriteJsonField(
+ "consumer_friendly_messages", consumer_friendly_messages, &result__);
+ impl::WriteJsonField("module_config", module_config, &result__);
+ impl::WriteJsonField("module_meta", module_meta, &result__);
+ impl::WriteJsonField(
+ "usage_and_error_counts", usage_and_error_counts, &result__);
+ impl::WriteJsonField("device_data", device_data, &result__);
+ return result__;
+}
+bool PolicyTable::is_valid() const {
+ if (!app_policies_section.is_valid()) {
+ return false;
+ }
+ if (!functional_groupings.is_valid()) {
+ return false;
+ }
+ if (!consumer_friendly_messages.is_valid()) {
+ return false;
+ }
+ if (!module_config.is_valid()) {
+ return false;
+ }
+ if (!module_meta.is_valid()) {
+ return false;
+ }
+ if (!usage_and_error_counts.is_valid()) {
+ return false;
+ }
+ if (!device_data.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+bool PolicyTable::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+bool PolicyTable::struct_empty() const {
+ if (app_policies_section.is_initialized()) {
+ return false;
+ }
+ if (functional_groupings.is_initialized()) {
+ return false;
+ }
+
+ if (consumer_friendly_messages.is_initialized()) {
+ return false;
+ }
+ if (module_config.is_initialized()) {
+ return false;
+ }
+
+ if (module_meta.is_initialized()) {
+ return false;
+ }
+ if (usage_and_error_counts.is_initialized()) {
+ return false;
+ }
+
+ if (device_data.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+void PolicyTable::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (PT_PRELOADED == GetPolicyTableType() ||
+ PT_UPDATE == GetPolicyTableType()) {
+ std::string validation_info =
+ omitted_validation_info + PolicyTableTypeToString(GetPolicyTableType());
+
+ if (device_data.is_initialized()) {
+ report__->ReportSubobject("device_data")
+ .set_validation_info(validation_info);
+ }
+ }
+ if (!app_policies_section.is_valid()) {
+ app_policies_section.ReportErrors(
+ &report__->ReportSubobject("app_policies"));
+ }
+ if (!functional_groupings.is_valid()) {
+ functional_groupings.ReportErrors(
+ &report__->ReportSubobject("functional_groupings"));
+ }
+ if (!consumer_friendly_messages.is_valid()) {
+ consumer_friendly_messages.ReportErrors(
+ &report__->ReportSubobject("consumer_friendly_messages"));
+ }
+ if (!module_config.is_valid()) {
+ module_config.ReportErrors(&report__->ReportSubobject("module_config"));
+ }
+ if (!module_meta.is_valid()) {
+ module_meta.ReportErrors(&report__->ReportSubobject("module_meta"));
+ }
+ if (!usage_and_error_counts.is_valid()) {
+ usage_and_error_counts.ReportErrors(
+ &report__->ReportSubobject("usage_and_error_counts"));
+ }
+ if (!device_data.is_valid()) {
+ device_data.ReportErrors(&report__->ReportSubobject("device_data"));
+ }
+}
+
+void PolicyTable::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ app_policies_section.SetPolicyTableType(pt_type);
+ functional_groupings.SetPolicyTableType(pt_type);
+ consumer_friendly_messages.SetPolicyTableType(pt_type);
+ module_config.SetPolicyTableType(pt_type);
+ module_meta.SetPolicyTableType(pt_type);
+ usage_and_error_counts.SetPolicyTableType(pt_type);
+ device_data.SetPolicyTableType(pt_type);
+}
+
+// Table methods
+Table::Table() : CompositeType(kUninitialized) {}
+Table::Table(const PolicyTable& policy_table)
+ : CompositeType(kUninitialized), policy_table(policy_table) {}
+Table::~Table() {}
+Table::Table(const Json::Value* value__)
+ : CompositeType(InitHelper(value__, &Json::Value::isObject))
+ , policy_table(impl::ValueMember(value__, "policy_table")) {}
+Json::Value Table::ToJsonValue() const {
+ Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("policy_table", policy_table, &result__);
+ return result__;
+}
+bool Table::is_valid() const {
+ if (!policy_table.is_valid()) {
+ return false;
+ }
+ return Validate();
+}
+bool Table::is_initialized() const {
+ return (initialization_state__ != kUninitialized) || (!struct_empty());
+}
+bool Table::struct_empty() const {
+ if (policy_table.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+void Table::ReportErrors(rpc::ValidationReport* report__) const {
+ if (struct_empty()) {
+ rpc::CompositeType::ReportErrors(report__);
+ }
+ if (!policy_table.is_valid()) {
+ policy_table.ReportErrors(&report__->ReportSubobject("policy_table"));
+ }
+}
+
+void Table::SetPolicyTableType(PolicyTableType pt_type) {
+ CompositeType::SetPolicyTableType(pt_type);
+ policy_table.SetPolicyTableType(pt_type);
+}
+
+} // namespace policy_table_interface_base
+} // namespace rpc
diff --git a/src/components/policy/policy_regular/src/policy_table/validation.cc b/src/components/policy/policy_regular/src/policy_table/validation.cc
new file mode 100644
index 0000000000..e7a981e559
--- /dev/null
+++ b/src/components/policy/policy_regular/src/policy_table/validation.cc
@@ -0,0 +1,197 @@
+#include <algorithm>
+#include "policy/policy_table/types.h"
+#include "utils/logger.h"
+
+namespace {
+bool IsTypeInvalid(
+ rpc::Enum<rpc::policy_table_interface_base::RequestType> request) {
+ return !request.is_valid();
+}
+}
+
+namespace rpc {
+namespace policy_table_interface_base {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Policy")
+
+void RemoveInvalidTypes(RequestTypes& types) {
+ types.erase(std::remove_if(types.begin(), types.end(), &IsTypeInvalid),
+ types.end());
+}
+
+bool PolicyBase::Validate() const {
+ return true;
+}
+
+bool ApplicationPoliciesSection::Validate() const {
+ ApplicationPolicies::iterator it_default_policy = apps.find(kDefaultApp);
+ ApplicationPolicies::iterator it_pre_data_policy =
+ apps.find(kPreDataConsentApp);
+
+ // Default and PreData policies are mandatory
+ if (apps.end() == it_default_policy || apps.end() == it_pre_data_policy) {
+ LOG4CXX_ERROR(logger_, "Default or preData policy is not present.");
+ return false;
+ }
+
+ // Device policy is mandatory
+ if (!device.is_initialized()) {
+ LOG4CXX_ERROR(logger_, "Device policy is not present.");
+ return false;
+ }
+
+ PolicyTableType pt_type = GetPolicyTableType();
+ if (PT_PRELOADED != pt_type && PT_UPDATE != pt_type) {
+ return true;
+ }
+
+ if (!it_default_policy->second.RequestType.is_valid()) {
+ LOG4CXX_WARN(logger_,
+ "Default policy RequestTypes are not valid. Will be cleaned.");
+ RemoveInvalidTypes(*it_default_policy->second.RequestType);
+ // If preloaded does not have valid default types - validation fails
+ // Otherwise default will be empty, i.e. all types allowed
+ if (PT_PRELOADED == pt_type) {
+ if (it_default_policy->second.RequestType->empty()) {
+ LOG4CXX_ERROR(
+ logger_,
+ "Default policy RequestTypes empty after clean-up. Exiting.");
+ return false;
+ }
+ }
+ }
+
+ ApplicationPolicies::iterator iter = apps.begin();
+ ApplicationPolicies::iterator end_iter = apps.end();
+
+ while (iter != end_iter) {
+ ApplicationParams& app_params = (*iter).second;
+ bool is_request_type_omitted = !app_params.RequestType.is_initialized();
+ bool is_request_type_valid = app_params.RequestType.is_valid();
+ bool is_request_type_empty = app_params.RequestType->empty();
+
+ if (PT_PRELOADED == pt_type) {
+ if (!is_request_type_valid) {
+ LOG4CXX_WARN(logger_,
+ "App policy RequestTypes are not valid. Will be cleaned.");
+ RemoveInvalidTypes(*app_params.RequestType);
+ if (app_params.RequestType->empty()) {
+ LOG4CXX_ERROR(
+ logger_,
+ "App policy RequestTypes empty after clean-up. Exiting.");
+ return false;
+ }
+ }
+ } else {
+ if (is_request_type_omitted) {
+ LOG4CXX_WARN(logger_,
+ "App policy RequestTypes omitted."
+ " Will be replaced with default.");
+ app_params.RequestType = apps[kDefaultApp].RequestType;
+ ++iter;
+ continue;
+ }
+ if (!is_request_type_valid) {
+ LOG4CXX_WARN(logger_,
+ "App policy RequestTypes are invalid. Will be cleaned.");
+ RemoveInvalidTypes(*app_params.RequestType);
+ if (app_params.RequestType->empty()) {
+ LOG4CXX_WARN(logger_,
+ "App policy RequestTypes empty after clean-up."
+ " Will be replaced with default.");
+ app_params.RequestType = apps[kDefaultApp].RequestType;
+ ++iter;
+ continue;
+ }
+ }
+ if (is_request_type_empty) {
+ LOG4CXX_WARN(logger_, "App policy RequestTypes empty.");
+ }
+ }
+ ++iter;
+ }
+
+ return true;
+}
+
+bool ApplicationParams::Validate() const {
+ return true;
+}
+bool RpcParameters::Validate() const {
+ return true;
+}
+bool Rpcs::Validate() const {
+ return true;
+}
+
+bool ModuleConfig::Validate() const {
+ if (PT_PRELOADED == GetPolicyTableType()) {
+ if (vehicle_make.is_initialized()) {
+ return false;
+ }
+ if (vehicle_year.is_initialized()) {
+ return false;
+ }
+ if (vehicle_model.is_initialized()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool MessageString::Validate() const {
+ return true;
+}
+
+bool MessageLanguages::Validate() const {
+ if (PT_SNAPSHOT == GetPolicyTableType()) {
+ return false;
+ }
+ return true;
+}
+
+bool ConsumerFriendlyMessages::Validate() const {
+ /* According to requirements consumer_friendly_messages are optional for PTU
+ and required for PTP and PTS. So, they are allowed always */
+ if (PT_SNAPSHOT == GetPolicyTableType() && messages.is_initialized()) {
+ return false;
+ }
+ return true;
+}
+
+bool ModuleMeta::Validate() const {
+ return true;
+}
+
+bool AppLevel::Validate() const {
+ if (PT_PRELOADED == GetPolicyTableType() ||
+ PT_UPDATE == GetPolicyTableType()) {
+ return false;
+ }
+ return true;
+}
+
+bool UsageAndErrorCounts::Validate() const {
+ if (PT_PRELOADED == GetPolicyTableType() ||
+ PT_UPDATE == GetPolicyTableType()) {
+ return false;
+ }
+ return true;
+}
+bool DeviceParams::Validate() const {
+ return true;
+}
+bool PolicyTable::Validate() const {
+ if (PT_PRELOADED == GetPolicyTableType() ||
+ PT_UPDATE == GetPolicyTableType()) {
+ if (device_data.is_initialized()) {
+ return false;
+ }
+ }
+ return true;
+}
+bool Table::Validate() const {
+ return true;
+}
+} // namespace policy_table_interface_base
+} // namespace rpc
diff --git a/src/components/policy/policy_regular/src/sql_pt_ext_queries.cc b/src/components/policy/policy_regular/src/sql_pt_ext_queries.cc
new file mode 100644
index 0000000000..3fde462a32
--- /dev/null
+++ b/src/components/policy/policy_regular/src/sql_pt_ext_queries.cc
@@ -0,0 +1,268 @@
+/*
+ Copyright (c) 2013, " Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, " with or without
+ modification, " are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, " this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, "
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, " INCLUDING, " BUT NOT LIMITED TO, " THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, " INDIRECT, " INCIDENTAL, " SPECIAL, " EXEMPLARY, " OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, " BUT NOT LIMITED TO, " PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, " DATA, " OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, " WHETHER IN
+ CONTRACT, " STRICT LIABILITY, " OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, " EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "policy/sql_pt_ext_queries.h"
+
+namespace policy {
+namespace sql_pt_ext {
+
+const std::string kSelectKeepContext =
+ "SELECT `keep_context` FROM `application` WHERE `id` = ? LIMIT 1";
+
+const std::string kSelectStealFocus =
+ "SELECT `steal_focus` FROM `application` WHERE `id` = ? LIMIT 1";
+
+const std::string kSelectDefaultHmi =
+ "SELECT `default_hmi` FROM `application` WHERE `id` = ? LIMIT 1";
+
+const std::string kResetDeviceConsents = "DELETE FROM `device_consent_group`";
+
+const std::string kResetAppConsents = "DELETE FROM `consent_group`";
+
+const std::string kCountDeviceConsentGroup =
+ "SELECT COUNT (`device_id`) "
+ "FROM `device_consent_group` WHERE `device_id` = ?";
+
+const std::string kCountDevice =
+ "SELECT COUNT (`id`) "
+ "FROM `device` WHERE `id` = ?";
+
+const std::string kSelectDeviceConsentedGroup =
+ "SELECT * FROM `device_consent_group` WHERE `device_id` = ?";
+
+const std::string kUpdateDeviceConsentedGroup =
+ "UPDATE `device_consent_group` SET `is_consented` = ?, `input` = ? WHERE "
+ "(`device_id` = ? AND `functional_group_id` = ?)";
+
+const std::string kUpdateDevice =
+ "UPDATE `device` SET `hardware` = ?, `firmware_rev` = ?, `os` = ?, "
+ "`os_version` = ?, `carrier` = ?, `max_number_rfcom_ports` = ?, "
+ " `connection_type` = ? WHERE `id` = ? ";
+
+const std::string kInsertDeviceConsentedGroup =
+ "INSERT OR REPLACE INTO `device_consent_group` "
+ "(`device_id`, `functional_group_id`, `is_consented`, `input`, "
+ "`time_stamp`) "
+ "VALUES (?,?,?,?,?)";
+
+const std::string kInsertDevice =
+ "INSERT OR IGNORE INTO `device` "
+ "(`id`, `hardware`, `firmware_rev`, `os`, `os_version`, `carrier`,"
+ "`max_number_rfcom_ports`, `connection_type`) "
+ "VALUES (?,?,?,?,?,?,?,?)";
+
+const std::string kSelectDeviceData = "SELECT * FROM `device`";
+
+const std::string kSelectConsentGroup =
+ "SELECT * FROM `consent_group` WHERE `device_id` = ? ";
+
+const std::string kInsertPreconsentedGroups =
+ "INSERT INTO `preconsented_group` (`application_id`, `functional_group_id`)"
+ " SELECT ?, `id` FROM `functional_group` WHERE `name` = ? LIMIT 1";
+
+const std::string kSelectPreconsentedGroups =
+ "SELECT `f`.`name` FROM `preconsented_group` AS `p`"
+ " LEFT JOIN `functional_group` AS `f` "
+ " ON (`f`.`id` = `p`.`functional_group_id`)"
+ " WHERE `p`.`application_id` = ?";
+
+const std::string kDeletePreconsentedGroups =
+ "DELETE FROM `preconsented_group`";
+
+const std::string kSelectUsageAndErrorCount =
+ "SELECT `count_of_iap_buffer_full`, `count_sync_out_of_memory`, "
+ " `count_of_sync_reboots` "
+ "FROM `usage_and_error_count` LIMIT 1";
+
+const std::string kSelectAppLevels =
+ "SELECT `application_id`, `minutes_in_hmi_full`, `minutes_in_hmi_limited`, "
+ " `minutes_in_hmi_background`, `minutes_in_hmi_none`, "
+ " `count_of_user_selections`, "
+ " `count_of_rejections_sync_out_of_memory`, "
+ " `count_of_rejections_nickname_mismatch`, "
+ " `count_of_rejections_duplicate_name`, "
+ " `count_of_rejected_rpcs_calls`, "
+ " `count_of_rpcs_sent_in_hmi_none`, "
+ " `count_of_removals_for_bad_behavior`, "
+ " `count_of_run_attempts_while_revoked`, "
+ " `app_registration_language_gui`, "
+ " `app_registration_language_vui`, "
+ " `count_of_tls_errors` "
+ "FROM `app_level`";
+
+const std::string kUpdateGlobalCounters =
+ "UPDATE `usage_and_error_count` SET "
+ "`count_of_iap_buffer_full` = ?, "
+ "`count_sync_out_of_memory` = ?, "
+ "`count_of_sync_reboots` = ? ";
+
+const std::string kInsertDeviceData =
+ "INSERT OR IGNORE INTO `device` "
+ "(`id`, `hardware`, `firmware_rev`, `os`, `os_version`, `carrier`, "
+ "`max_number_rfcom_ports`,`connection_type`) VALUES (?,?,?,?,?,?,?,?) ";
+
+const std::string kInsertConsentGroups =
+ "INSERT OR REPLACE INTO `consent_group` "
+ "(`device_id`, `application_id`, `functional_group_id`, `is_consented`, "
+ "`input`, `time_stamp`) "
+ "VALUES (?,?,?,?,?,?)";
+
+const std::string kDeleteAppGroupConsent =
+ "DELETE FROM `consent_group` WHERE "
+ "`application_id` = ? AND `functional_group_id` = ? ";
+
+const std::string kSelectGroupId =
+ "SELECT `id` FROM `functional_group` WHERE `name` = ? ";
+
+const std::string kCountUnconsentedGroups =
+ "SELECT COUNT(`a`.`functional_group_id`) FROM `app_group` AS `a` "
+ " WHERE `a`.`application_id` = ? AND NOT EXISTS "
+ " (SELECT NULL FROM `preconsented_group` AS `p` WHERE "
+ " (`p`.`functional_group_id` = `a`.`functional_group_id` AND "
+ " `p`.`application_id` = `a`.`application_id`)) "
+ " AND NOT EXISTS (SELECT NULL FROM `consent_group` AS `c` "
+ " WHERE (`c`.`application_id` = `a`.`application_id` "
+ " AND `c`.`functional_group_id` = `a`.`functional_group_id` "
+ " AND `c`.`device_id` = ?)) AND NOT EXISTS "
+ " (SELECT NULL FROM `app_group` AS `def` WHERE "
+ " (`def`.`application_id` = ? OR "
+ " `def`.`application_id` = ?) "
+ " AND `def`.`functional_group_id` = `a`.`functional_group_id`)"
+ " AND NOT EXISTS (SELECT NULL FROM `functional_group` AS `f` "
+ " WHERE (`a`.`functional_group_id` = `f`.`id`"
+ " AND`f`.`user_consent_prompt` IS NULL))";
+
+const std::string kSelectModuleMeta = "SELECT* FROM `module_meta`";
+
+const std::string kUpdateMetaParams =
+ "UPDATE `module_meta` SET "
+ "`ccpu_version` = ?, `wers_country_code` = ?, `language` = ? ";
+
+const std::string kUpdateModuleMetaVinParam =
+ "UPDATE `module_meta` SET `vin` = ? ";
+
+const std::string kSaveModuleMeta =
+ "UPDATE `module_meta` SET `ccpu_version` = ?, `language` = ?,"
+ "`wers_country_code` = ?, `pt_exchanged_at_odometer_x` = ?,"
+ "`pt_exchanged_x_days_after_epoch` = ?,"
+ "`ignition_cycles_since_last_exchange` = ?, `vin` = ?";
+
+const std::string kSelectMetaParams =
+ "SELECT `ccpu_version`, "
+ "`wers_country_code`, `language` from `module_meta`";
+
+const std::string kUpdateMetaLanguage =
+ "UPDATE `module_meta` SET `language` = ? ";
+
+const std::string kCountAppLevel =
+ "SELECT COUNT(`application_id`) FROM `app_level`"
+ " WHERE `application_id` = ? ";
+
+const std::string kUpdateGroupPermissions =
+ "UPDATE `consent_group` "
+ "SET `is_consented` = ?, `input` = ? "
+ "WHERE(`application_id` = ? AND `functional_group_id` = ? AND `device_id` "
+ "= ?) ";
+
+const std::string kInsertApplication =
+ "INSERT OR IGNORE INTO `application`(`id`, `keep_context`, `steal_focus`, "
+ " `default_hmi`, `priority_value`, `is_revoked`, `memory_kb`, "
+ " `heart_beat_timeout_ms`, `certificate`) VALUES( ?, ?, ?, ?, ?, ?, ?, ?, "
+ "?) ";
+
+const std::string kCollectFriendlyMsg = "SELECT * FROM `message`";
+
+const std::string kSelectFriendlyMsg =
+ "SELECT `tts`, `label`, `line1`, `line2`, `textBody` FROM `message` "
+ "WHERE `message_type_name` = ? AND `language_code` = ? LIMIT 1";
+
+const std::string kSelectAppGroupsId =
+ "SELECT `functional_group_id` "
+ "FROM `app_group` WHERE `application_id` = ? ";
+
+const std::string kSelectConsentedGroupsId =
+ "SELECT `functional_group_id`, `is_consented` "
+ "FROM `consent_group` WHERE(`application_id` = ? AND `device_id` = ?) ";
+
+const std::string kCountAppConsents =
+ "SELECT COUNT(*) from `consent_group`"
+ "WHERE(`device_id` = ? AND `application_id` = ? AND "
+ "`functional_group_id` = ?) ";
+
+const std::string kSelectPreconsentedGroupsId =
+ "SELECT `functional_group_id` "
+ "FROM `preconsented_group` WHERE `application_id` = ? ";
+
+const std::string kSelectAppPolicies =
+ "SELECT `id`, `priority_value`, `default_hmi`, `keep_context`, "
+ "`steal_focus`, "
+ " `memory_kb`, `heart_beat_timeout_ms`, `certificate` FROM `application`";
+
+const std::string kSelectFunctionalGroupNames =
+ "SELECT `id`, `user_consent_prompt`, `name`"
+ " FROM `functional_group`";
+
+const std::string kDeleteDeviceConsent =
+ "DELETE FROM `device_consent_group` "
+ "WHERE `device_id` = ? ";
+
+const std::string kDeleteAppConsent =
+ "DELETE FROM `consent_group` "
+ "WHERE `device_id` = ? ";
+
+const std::string kSelectApplicationIsPreData =
+ "SELECT `is_predata` FROM `application` WHERE `id` = ? ";
+
+const std::string kUpdateIsPredata =
+ "UPDATE `application` SET `is_predata` = ? WHERE `id` = ? ";
+
+const std::string kHasAppPreloadedGroups =
+ "SELECT COUNT(`a1`.`functional_group_id`) FROM `app_group` "
+ " AS `a1` JOIN `app_group` AS `a2` "
+ " ON `a1`.`functional_group_id` = `a2`.`functional_group_id` "
+ " WHERE `a1`.`application_id` = ? AND `a2`.`application_id` = ? ";
+
+const std::string kUpdateUnpairedDevice =
+ "UPDATE `device` SET `unpaired` = ? WHERE `id` = ? ";
+
+const std::string kSelectUnpairedDevices =
+ "SELECT `id` FROM `device` WHERE `unpaired` = 1";
+
+const std::string kHasMsgLanguageCode =
+ "SELECT COUNT (`id`) FROM message "
+ "WHERE `message_type_name` = ? AND `language_code` = ? ";
+
+const std::string kDeletePreconsentedGroupsByApplicationId =
+ "DELETE FROM `preconsented_group` WHERE `application_id` = ?";
+
+} // namespace sql_pt_ext
+} // namespace policy
diff --git a/src/components/policy/policy_regular/src/sql_pt_ext_representation.cc b/src/components/policy/policy_regular/src/sql_pt_ext_representation.cc
new file mode 100644
index 0000000000..c64efaaede
--- /dev/null
+++ b/src/components/policy/policy_regular/src/sql_pt_ext_representation.cc
@@ -0,0 +1,1807 @@
+/*
+ Copyright (c) 2015, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <algorithm>
+#include <utility>
+#include "utils/logger.h"
+#include "policy/sql_pt_ext_representation.h"
+#include "policy/sql_wrapper.h"
+#include "policy/sql_pt_queries.h"
+#include "policy/sql_pt_ext_queries.h"
+#include "policy/policy_helper.h"
+#include "policy/cache_manager.h"
+
+namespace policy {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Policy")
+
+bool SQLPTExtRepresentation::CanAppKeepContext(const std::string& app_id) {
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt_ext::kSelectKeepContext)) {
+ query.Bind(0, app_id);
+ if (query.Exec()) {
+ return query.GetBoolean(0);
+ }
+ }
+ return false;
+}
+
+bool SQLPTExtRepresentation::CanAppStealFocus(const std::string& app_id) {
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt_ext::kSelectStealFocus)) {
+ query.Bind(0, app_id);
+ if (query.Exec()) {
+ return query.GetBoolean(0);
+ }
+ }
+ return false;
+}
+
+bool SQLPTExtRepresentation::ResetUserConsent() {
+ return ResetDeviceConsents() && ResetAppConsents();
+}
+
+bool SQLPTExtRepresentation::ResetDeviceConsents() {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kResetDeviceConsents)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete statement from device_consents.");
+ return false;
+ }
+ return query.Exec();
+}
+
+bool SQLPTExtRepresentation::ResetAppConsents() {
+ return utils::dbms::SQLQuery(db()).Exec(sql_pt_ext::kResetAppConsents);
+}
+
+bool SQLPTExtRepresentation::GetUserPermissionsForDevice(
+ const std::string& device_id,
+ StringArray* consented_groups,
+ StringArray* disallowed_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectDeviceConsentedGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from device consented groups");
+ return false;
+ }
+ query.Bind(0, device_id);
+ while (query.Next()) {
+ if (query.GetBoolean(2)) {
+ if (!consented_groups) {
+ continue;
+ }
+ consented_groups->push_back(query.GetString(1));
+ } else {
+ if (!disallowed_groups) {
+ continue;
+ }
+ disallowed_groups->push_back(query.GetString(1));
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GetPermissionsForApp(
+ const std::string& device_id,
+ const std::string& policy_app_id,
+ FunctionalIdType* group_types) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (!group_types) {
+ LOG4CXX_WARN(logger_, "Input parameter for group types is null.");
+ return false;
+ }
+ // Get all app groups for specified device and application
+ FunctionalGroupIDs all_groups;
+ if (!GetAllAppGroups(policy_app_id, all_groups)) {
+ return false;
+ }
+ // Get preconsented group
+ FunctionalGroupIDs preconsented_groups;
+ if (!GetPreconsentedGroups(policy_app_id, preconsented_groups)) {
+ return false;
+ }
+ // Get consented (allowed/disallowed) groups
+ FunctionalGroupIDs allowed_groups;
+ FunctionalGroupIDs disallowed_groups;
+ if (!GetConsentedGroups(
+ policy_app_id, device_id, allowed_groups, disallowed_groups)) {
+ return false;
+ }
+ // Get all default groups
+ FunctionalGroupIDs default_groups;
+ if (!GetAllAppGroups(kDefaultId, default_groups)) {
+ return false;
+ }
+
+ // Get all pre_DataConsent groups
+ FunctionalGroupIDs predataconsented_groups;
+ if (!GetAllAppGroups(kPreDataConsentId, predataconsented_groups)) {
+ return false;
+ }
+
+ // Get all device groups
+ FunctionalGroupIDs device_groups;
+ if (!GetAllAppGroups(kDeviceId, device_groups)) {
+ return false;
+ }
+
+ (*group_types)[kTypeDefault] = default_groups;
+ (*group_types)[kTypeAllowed] = allowed_groups;
+ (*group_types)[kTypeDisallowed] = disallowed_groups;
+ (*group_types)[kTypePreconsented] = preconsented_groups;
+ (*group_types)[kTypeGeneral] = all_groups;
+ (*group_types)[kTypePreDataConsented] = predataconsented_groups;
+ (*group_types)[kTypeDevice] = device_groups;
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GetDeviceGroupsFromPolicies(
+ policy_table::Strings* groups, policy_table::Strings* preconsented_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (groups) {
+ GatherAppGroup(kDeviceId, groups);
+ }
+ if (preconsented_groups) {
+ GatherPreconsentedGroup(kDeviceId, preconsented_groups);
+ }
+ return true;
+}
+
+bool SQLPTExtRepresentation::SetDeviceData(const std::string& device_id,
+ const std::string& hardware,
+ const std::string& firmware,
+ const std::string& os,
+ const std::string& os_version,
+ const std::string& carrier,
+ const uint32_t number_of_ports,
+ const std::string& connection_type) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery count_query(db());
+ if (!count_query.Prepare(sql_pt_ext::kCountDevice)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for count of device.");
+ return false;
+ }
+
+ count_query.Bind(0, device_id);
+
+ if (!count_query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect count of device.");
+ return false;
+ }
+
+ bool update = count_query.GetInteger(0);
+
+ // Update old value
+ if (update) {
+ utils::dbms::SQLQuery update_query(db());
+ if (!update_query.Prepare(sql_pt_ext::kUpdateDevice)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for udpate device.");
+ return false;
+ }
+
+ update_query.Bind(0, hardware);
+ update_query.Bind(1, firmware);
+ update_query.Bind(2, os);
+ update_query.Bind(3, os_version);
+ update_query.Bind(4, carrier);
+ update_query.Bind(5, static_cast<int>(number_of_ports));
+ update_query.Bind(6, device_id);
+ update_query.Bind(7, connection_type);
+
+ if (!update_query.Exec() || !update_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect update for device.");
+ return false;
+ }
+
+ return true;
+ }
+
+ // Insert new data
+ utils::dbms::SQLQuery insert_query(db());
+ if (!insert_query.Prepare(sql_pt_ext::kInsertDevice)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for device.");
+ return false;
+ }
+
+ insert_query.Bind(0, device_id);
+ insert_query.Bind(1, hardware);
+ insert_query.Bind(2, firmware);
+ insert_query.Bind(3, os);
+ insert_query.Bind(4, os_version);
+ insert_query.Bind(5, carrier);
+ insert_query.Bind(6, static_cast<int>(number_of_ports));
+ insert_query.Bind(7, connection_type);
+
+ if (!insert_query.Exec() || !insert_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert to device.");
+ return false;
+ }
+
+ SetPreloaded(false);
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SetUserPermissionsForDevice(
+ const std::string& device_id,
+ const StringArray& consented_groups,
+ const StringArray& disallowed_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery count_query(db());
+ if (!count_query.Prepare(sql_pt_ext::kCountDeviceConsentGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect count of device consented groups");
+ return false;
+ }
+
+ count_query.Bind(0, device_id);
+
+ if (!count_query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed count of device consented groups");
+ return false;
+ }
+
+ bool update = count_query.GetInteger(0);
+
+ // TODO(AOleynik): Split to several methods?
+ utils::dbms::SQLQuery query(db());
+ // Update old values
+ if (update) {
+ if (!query.Prepare(sql_pt_ext::kUpdateDeviceConsentedGroup)) {
+ LOG4CXX_WARN(
+ logger_,
+ "Incorrect statement for updating consented groups on device");
+ return false;
+ }
+
+ StringArray::const_iterator it_consented_groups = consented_groups.begin();
+ StringArray::const_iterator it_consented_groups_end =
+ consented_groups.end();
+ for (; it_consented_groups != it_consented_groups_end;
+ ++it_consented_groups) {
+ query.Bind(0, true);
+ query.Bind(1, std::string("GUI"));
+ query.Bind(2, device_id);
+ query.Bind(3, *it_consented_groups);
+ // TODO(AOleynik): Get this info from external data
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_,
+ "Failed update of device allowed consented groups.");
+ return false;
+ }
+ }
+
+ StringArray::const_iterator it_disallowed_groups =
+ disallowed_groups.begin();
+ StringArray::const_iterator it_disallowed_groups_end =
+ disallowed_groups.end();
+ for (; it_disallowed_groups != it_disallowed_groups_end;
+ ++it_disallowed_groups) {
+ query.Bind(0, false);
+ query.Bind(1);
+ query.Bind(2, device_id);
+ query.Bind(3, *it_disallowed_groups);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_,
+ "Failed update of device disallowed consented groups.");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ // Insert new values
+ if (!query.Prepare(sql_pt_ext::kInsertDeviceConsentedGroup)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect statement of inserting to device consented groups");
+ return false;
+ }
+
+ StringArray::const_iterator it_consented_groups = consented_groups.begin();
+ StringArray::const_iterator it_consented_groups_end = consented_groups.end();
+ for (; it_consented_groups != it_consented_groups_end;
+ ++it_consented_groups) {
+ query.Bind(0, device_id);
+ query.Bind(1, *it_consented_groups);
+ query.Bind(2, true);
+ // TODO(AOleynik): Get this info from external data
+ query.Bind(3, std::string("GUI"));
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_,
+ "Failed insert to device allowed consented groups.");
+ return false;
+ }
+ }
+
+ StringArray::const_iterator it_disallowed_groups = disallowed_groups.begin();
+ StringArray::const_iterator it_disallowed_groups_end =
+ disallowed_groups.end();
+ for (; it_disallowed_groups != it_disallowed_groups_end;
+ ++it_disallowed_groups) {
+ query.Bind(0, device_id);
+ query.Bind(1, *it_disallowed_groups);
+ query.Bind(2, false);
+ query.Bind(3);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_,
+ "Failed insert to device disallowed consented groups.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::ReactOnUserDevConsentForApp(
+ const std::string& app_id, bool is_device_allowed) {
+ bool result = true;
+ if (is_device_allowed) {
+ // If app has pre_DataConsented groups it should be 'promoted' to default
+ // If app has only pre_DataConsented flag it should be only set to false and
+ // all groups get restored automatically
+ if (IsPredataPolicy(app_id)) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kHasAppPreloadedGroups)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect statement for has app preloaded groups");
+ return false;
+ }
+ query.Bind(0, app_id);
+ query.Bind(1, kPreDataConsentId);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect select for app has predataconsted groups");
+ return false;
+ }
+ if (query.GetInteger(0) > 0) {
+ result = result && SetDefaultPolicy(app_id);
+ } else {
+ result = result && SetIsPredata(app_id, false);
+ }
+ }
+ } else {
+ // If app has default groups change them to pre_DataConsented
+ // If app has 'normal' groups leave them as is and set
+ // pre_DataConsented flag to true.
+ if (IsDefaultPolicy(app_id)) {
+ result = result && SetPredataPolicy(app_id);
+ } else {
+ result = result && SetIsPredata(app_id, true);
+ }
+ }
+ return result;
+}
+
+bool SQLPTExtRepresentation::SetUserPermissionsForApp(
+ const PermissionConsent& permissions) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ // TODO(AOleynik): Handle situation, when no application was specified, i.e.
+ // general permissions were set
+ std::vector<FunctionalGroupPermission>::const_iterator it =
+ permissions.group_permissions.begin();
+ std::vector<FunctionalGroupPermission>::const_iterator it_end =
+ permissions.group_permissions.end();
+
+ utils::dbms::SQLQuery query(db());
+ for (; it != it_end; ++it) {
+ utils::dbms::SQLQuery counter(db());
+ if (!counter.Prepare(sql_pt_ext::kCountAppConsents)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for consent group count.");
+ return false;
+ }
+
+ counter.Bind(0, permissions.device_id);
+ counter.Bind(1, permissions.policy_app_id);
+ counter.Bind(2, static_cast<int>((*it).group_id));
+ if (!counter.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrent count on consent groups.");
+ return false;
+ }
+
+ bool update_required = counter.GetInteger(0);
+
+ // Update already present consent record
+ if (update_required) {
+ if (!query.Prepare(sql_pt_ext::kUpdateGroupPermissions)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for update consent groups.");
+ return false;
+ }
+
+ // Skip consent saving, if user didn't choose any state
+ if (policy::kGroupUndefined == (*it).state) {
+ continue;
+ }
+ query.Bind(0, (*it).state == kGroupAllowed ? 1 : 0);
+ query.Bind(1, permissions.consent_source);
+ query.Bind(2, permissions.policy_app_id);
+ query.Bind(3, static_cast<int>((*it).group_id));
+ query.Bind(4, permissions.device_id);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect update on user defined permissions "
+ "for app groups.");
+ return false;
+ }
+ continue;
+ }
+
+ // Insert new consent record
+ if (!query.Prepare(sql_pt_ext::kInsertConsentGroups)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect statement for update app group permissions.");
+ return false;
+ }
+
+ // Skip consent saving, if user didn't choose any state
+ if (policy::kGroupUndefined == (*it).state) {
+ continue;
+ }
+ query.Bind(0, permissions.device_id);
+ query.Bind(1, permissions.policy_app_id);
+ query.Bind(2, static_cast<int>((*it).group_id));
+ query.Bind(3, (*it).state == kGroupAllowed ? 1 : 0);
+ query.Bind(4, permissions.consent_source);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert to user defined permissions "
+ "for app groups.");
+ return false;
+ }
+ continue;
+ }
+ return true;
+}
+
+std::vector<UserFriendlyMessage> SQLPTExtRepresentation::GetUserFriendlyMsg(
+ const std::vector<std::string>& msg_codes, const std::string& language) {
+ utils::dbms::SQLQuery query(db());
+ std::vector<UserFriendlyMessage> result;
+ if (!query.Prepare(sql_pt_ext::kSelectFriendlyMsg)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for select friendly messages.");
+ return result;
+ }
+
+ const std::string fallback_language = "en-us";
+ std::vector<std::string>::const_iterator it = msg_codes.begin();
+ std::vector<std::string>::const_iterator it_end = msg_codes.end();
+ for (; it != it_end; ++it) {
+ std::string msg_language = language;
+ // If message has no records with required language, fallback language
+ // should be used instead.
+ if (!IsMsgLanguagePresent((*it), language)) {
+ msg_language = fallback_language;
+ }
+ query.Bind(0, *it);
+ query.Bind(1, msg_language);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect select from friendly messages.");
+ return result;
+ }
+
+ UserFriendlyMessage msg;
+
+ msg.message_code = *it;
+ msg.tts = query.GetString(0);
+ msg.label = query.GetString(1);
+ msg.line1 = query.GetString(2);
+ msg.line2 = query.GetString(3);
+ msg.text_body = query.GetString(4);
+
+ result.push_back(msg);
+
+ if (!query.Reset()) {
+ LOG4CXX_WARN(logger_,
+ "Failed reset statement for selecting friendly "
+ "messages.");
+ return result;
+ }
+ }
+
+ return result;
+}
+
+bool SQLPTExtRepresentation::GatherConsumerFriendlyMessages(
+ policy_table::ConsumerFriendlyMessages* messages) const {
+ if (NULL == messages) {
+ LOG4CXX_ERROR(logger_, "NULL pointer has been passed to fill");
+ return false;
+ }
+
+ if (!SQLPTRepresentation::GatherConsumerFriendlyMessages(messages)) {
+ return false;
+ }
+
+ utils::dbms::SQLQuery query(db());
+ bool result = query.Prepare(sql_pt_ext::kCollectFriendlyMsg);
+
+ if (result) {
+ while (query.Next()) {
+ UserFriendlyMessage msg;
+
+ msg.tts = query.GetString(1);
+ msg.label = query.GetString(2);
+ msg.line1 = query.GetString(3);
+ msg.line2 = query.GetString(4);
+ msg.text_body = query.GetString(5);
+ msg.message_code = query.GetString(7);
+
+ std::string language = query.GetString(6);
+
+ *(*messages->messages)[msg.message_code].languages[language].tts =
+ msg.tts;
+ *(*messages->messages)[msg.message_code].languages[language].label =
+ msg.label;
+ *(*messages->messages)[msg.message_code].languages[language].line1 =
+ msg.line1;
+ *(*messages->messages)[msg.message_code].languages[language].line2 =
+ msg.line2;
+ *(*messages->messages)[msg.message_code].languages[language].textBody =
+ msg.text_body;
+ }
+ } else {
+ LOG4CXX_WARN(logger_, "Incorrect statement for select friendly messages.");
+ }
+ return result;
+}
+
+bool SQLPTExtRepresentation::SetMetaInfo(const std::string& ccpu_version,
+ const std::string& wers_country_code,
+ const std::string& language) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kUpdateMetaParams)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for insert to module meta.");
+ return false;
+ }
+
+ query.Bind(0, ccpu_version);
+ query.Bind(1, wers_country_code);
+ query.Bind(2, language);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert to module meta.");
+ return false;
+ }
+ return true;
+}
+
+bool SQLPTExtRepresentation::IsMetaInfoPresent() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectMetaParams)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for selecting meta info.");
+ return false;
+ }
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect select from module meta.");
+ return false;
+ }
+
+ return !query.IsNull(0) && !query.IsNull(1) && !query.IsNull(2);
+}
+
+bool SQLPTExtRepresentation::SetSystemLanguage(const std::string& language) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kUpdateMetaLanguage)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for update meta language.");
+ return false;
+ }
+
+ query.Bind(0, language);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect update for meta language.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SaveApplicationPoliciesSection(
+ const policy_table::ApplicationPoliciesSection& policies) {
+ LOG4CXX_INFO(logger_, "SaveApplicationPolicies ext");
+ utils::dbms::SQLQuery query_delete(db());
+ if (!query_delete.Exec(sql_pt::kDeleteAppGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from app_group.");
+ return false;
+ }
+
+ utils::dbms::SQLQuery query_delete_preconsented(db());
+ if (!query_delete_preconsented.Exec(sql_pt_ext::kDeletePreconsentedGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from preconsented_group.");
+ return false;
+ }
+
+ if (!query_delete.Exec(sql_pt::kDeleteApplication)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from application.");
+ return false;
+ }
+
+ if (!query_delete.Exec(sql_pt::kDeleteRequestType)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from request type.");
+ return false;
+ }
+
+ // First, all predefined apps (e.g. default, pre_DataConsent) should be saved,
+ // otherwise another app with the predefined permissions can get incorrect
+ // permissions
+ policy_table::ApplicationPolicies::const_iterator it_default =
+ policies.apps.find(kDefaultId);
+ if (policies.apps.end() != it_default) {
+ if (!SaveSpecificAppPolicy(*it_default)) {
+ return false;
+ }
+ }
+ policy_table::ApplicationPolicies::const_iterator it_pre_data_consent =
+ policies.apps.find(kPreDataConsentId);
+ if (policies.apps.end() != it_pre_data_consent) {
+ if (!SaveSpecificAppPolicy(*it_pre_data_consent)) {
+ return false;
+ }
+ }
+
+ if (!SaveDevicePolicy(policies.device)) {
+ return false;
+ }
+
+ policy_table::ApplicationPolicies::const_iterator it;
+ for (it = policies.apps.begin(); it != policies.apps.end(); ++it) {
+ // Skip saving of predefined app, since they should be saved before
+ if (IsPredefinedApp(*it)) {
+ continue;
+ }
+ if (!SaveSpecificAppPolicy(*it)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SaveSpecificAppPolicy(
+ const policy_table::ApplicationPolicies::value_type& app) {
+ if (app.second.is_string()) {
+ if (kDefaultId.compare(app.second.get_string()) == 0) {
+ if (!SetDefaultPolicy(app.first)) {
+ return false;
+ }
+ if (!SaveRequestType(app.first, *app.second.RequestType)) {
+ return false;
+ }
+ } else if (kPreDataConsentId.compare(app.second.get_string()) == 0) {
+ if (!SetPredataPolicy(app.first)) {
+ return false;
+ }
+ if (!SaveRequestType(app.first, *app.second.RequestType)) {
+ return false;
+ }
+ }
+
+ // Stop saving other params, since predefined permissions already set
+ return true;
+ }
+
+ SetIsDefault(app.first, false);
+ SetIsPredata(app.first, false);
+
+ utils::dbms::SQLQuery app_query(db());
+ if (!app_query.Prepare(sql_pt_ext::kInsertApplication)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement into application.");
+ return false;
+ }
+
+ app_query.Bind(0, app.first);
+ app_query.Bind(1, app.second.keep_context);
+ app_query.Bind(2, app.second.steal_focus);
+ app_query.Bind(
+ 3, std::string(policy_table::EnumToJsonString(app.second.default_hmi)));
+ app_query.Bind(
+ 4, std::string(policy_table::EnumToJsonString(app.second.priority)));
+ app_query.Bind(5, app.second.is_null());
+ app_query.Bind(6, *app.second.memory_kb);
+ app_query.Bind(7, static_cast<int64_t>(*app.second.heart_beat_timeout_ms));
+ app.second.certificate.is_initialized()
+ ? app_query.Bind(8, *app.second.certificate)
+ : app_query.Bind(8, std::string());
+
+ if (!app_query.Exec() || !app_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into application.");
+ return false;
+ }
+
+ if (!SaveAppGroup(app.first, app.second.groups)) {
+ return false;
+ }
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ if (!SaveNickname(app.first, *app.second.nicknames)) {
+ return false;
+ }
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ if (!SaveAppType(app.first, *app.second.AppHMIType)) {
+ return false;
+ }
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ if (!SavePreconsentedGroup(app.first, *app.second.preconsented_groups)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool policy::SQLPTExtRepresentation::SaveDevicePolicy(
+ const policy_table::DevicePolicy& device) {
+ dbms::SQLQuery app_query(db());
+ if (!app_query.Prepare(sql_pt_ext::kInsertApplication)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement into application (device).");
+ return false;
+ }
+ app_query.Bind(0, kDeviceId);
+ app_query.Bind(1, device.keep_context);
+ app_query.Bind(2, device.steal_focus);
+ app_query.Bind(
+ 3, std::string(policy_table::EnumToJsonString(device.default_hmi)));
+ app_query.Bind(4,
+ std::string(policy_table::EnumToJsonString(device.priority)));
+ app_query.Bind(5, false);
+ app_query.Bind(6, 0);
+ app_query.Bind(7, 0);
+ app_query.Bind(8, std::string());
+
+ if (!app_query.Exec() || !app_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into application.");
+ return false;
+ }
+
+ if (!SaveAppGroup(kDeviceId, device.groups)) {
+ return false;
+ }
+ if (!SavePreconsentedGroup(kDeviceId, *device.preconsented_groups)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GatherApplicationPoliciesSection(
+ policy_table::ApplicationPoliciesSection* policies) const {
+ LOG4CXX_INFO(logger_, "Gather applications policies");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectAppPolicies)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app_policies");
+ return false;
+ }
+
+ while (query.Next()) {
+ rpc::Nullable<policy_table::ApplicationParams> params;
+ const std::string& app_id = query.GetString(0);
+ if (IsApplicationRevoked(app_id)) {
+ params.set_to_null();
+ (*policies).apps[app_id] = params;
+ continue;
+ }
+ if (IsDefaultPolicy(app_id)) {
+ (*policies).apps[app_id].set_to_string(kDefaultId);
+ }
+ if (IsPredataPolicy(app_id)) {
+ (*policies).apps[app_id].set_to_string(kPreDataConsentId);
+ }
+ if (kDeviceId == app_id) {
+ policy_table::DevicePolicy device_policy;
+ policy_table::Priority priority;
+ policy_table::EnumFromJsonString(query.GetString(1), &priority);
+ device_policy.priority = priority;
+ policy_table::HmiLevel hmi;
+ policy_table::EnumFromJsonString(query.GetString(2), &hmi);
+ device_policy.default_hmi = hmi;
+ device_policy.keep_context = query.GetBoolean(3);
+ device_policy.steal_focus = query.GetBoolean(4);
+ if (!GatherAppGroup(app_id, &device_policy.groups)) {
+ return false;
+ }
+ GatherPreconsentedGroup(app_id, &*device_policy.preconsented_groups);
+ (*policies).device = device_policy;
+ continue;
+ }
+ policy_table::Priority priority;
+ policy_table::EnumFromJsonString(query.GetString(1), &priority);
+ params.priority = priority;
+ policy_table::HmiLevel hmi;
+ policy_table::EnumFromJsonString(query.GetString(2), &hmi);
+ params.default_hmi = hmi;
+ params.keep_context = query.GetBoolean(3);
+ params.steal_focus = query.GetBoolean(4);
+ *params.memory_kb = query.GetInteger(5);
+ *params.heart_beat_timeout_ms = query.GetUInteger(6);
+ if (!query.IsNull(7)) {
+ *params.certificate = query.GetString(7);
+ }
+ if (!GatherAppGroup(app_id, &params.groups)) {
+ return false;
+ }
+ if (!GatherNickName(app_id, &*params.nicknames)) {
+ return false;
+ }
+ if (!GatherAppType(app_id, &*params.AppHMIType)) {
+ return false;
+ }
+ if (!GatherRequestType(app_id, &*params.RequestType)) {
+ return false;
+ }
+ GatherPreconsentedGroup(app_id, &*params.preconsented_groups);
+ (*policies).apps[app_id] = params;
+ }
+ return true;
+}
+
+void SQLPTExtRepresentation::GatherPreconsentedGroup(
+ const std::string& app_id, policy_table::Strings* groups) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectPreconsentedGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from preconsented group");
+ return;
+ }
+
+ query.Bind(0, app_id);
+ while (query.Next()) {
+ groups->push_back(query.GetString(0));
+ }
+}
+
+bool SQLPTExtRepresentation::GatherUsageAndErrorCounts(
+ policy_table::UsageAndErrorCounts* counts) const {
+ LOG4CXX_INFO(logger_, "Gather Usage and Error Counts.");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectUsageAndErrorCount) || !query.Exec()) {
+ LOG4CXX_INFO(logger_, "Failed select from user_and_error_count");
+ return false;
+ }
+
+ *counts->count_of_iap_buffer_full = query.GetInteger(0);
+ *counts->count_sync_out_of_memory = query.GetInteger(1);
+ *counts->count_of_sync_reboots = query.GetInteger(2);
+
+ return GatherAppLevels(&*counts->app_level);
+}
+
+bool SQLPTExtRepresentation::GatherAppLevels(
+ policy_table::AppLevels* apps) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectAppLevels)) {
+ LOG4CXX_INFO(logger_,
+ "Failed select from app_level. SQLError = "
+ << query.LastError().text());
+ return false;
+ }
+ while (query.Next()) {
+ policy_table::AppLevel level;
+ // value of time fields database is seconds
+ level.minutes_in_hmi_full = query.GetInteger(1);
+ level.minutes_in_hmi_limited = query.GetInteger(2);
+ level.minutes_in_hmi_background = query.GetInteger(3);
+ level.minutes_in_hmi_none = query.GetInteger(4);
+ level.count_of_user_selections = query.GetInteger(5);
+ level.count_of_rejections_sync_out_of_memory = query.GetInteger(6);
+ level.count_of_rejections_nickname_mismatch = query.GetInteger(7);
+ level.count_of_rejections_duplicate_name = query.GetInteger(8);
+ level.count_of_rejected_rpc_calls = query.GetInteger(9);
+ level.count_of_rpcs_sent_in_hmi_none = query.GetInteger(10);
+ level.count_of_removals_for_bad_behavior = query.GetInteger(11);
+ level.count_of_run_attempts_while_revoked = query.GetInteger(12);
+ level.app_registration_language_gui = query.GetString(13);
+ level.app_registration_language_vui = query.GetString(14);
+ level.count_of_tls_errors = query.GetInteger(15);
+ (*apps)[query.GetString(0)] = level;
+ }
+
+ return true;
+}
+
+void SQLPTExtRepresentation::GatherDeviceData(
+ policy_table::DeviceData* data) const {
+ LOG4CXX_INFO(logger_, "Gather device data.");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectDeviceData)) {
+ LOG4CXX_WARN(logger_, "Incorrect select statement for device data.");
+ return;
+ }
+ data->mark_initialized();
+ while (query.Next()) {
+ policy_table::DeviceParams* specific_device = &(*data)[query.GetString(0)];
+ *specific_device->hardware = query.GetString(1);
+ *specific_device->firmware_rev = query.GetString(2);
+ *specific_device->os = query.GetString(3);
+ *specific_device->os_version = query.GetString(4);
+ *specific_device->carrier = query.GetString(5);
+ *specific_device->max_number_rfcom_ports = query.GetInteger(6);
+
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ GatherConsentGroup(query.GetString(0),
+ &(*specific_device->user_consent_records));
+ }
+}
+
+void SQLPTExtRepresentation::GatherConsentGroup(
+ const std::string& device_id,
+ policy_table::UserConsentRecords* records) const {
+ LOG4CXX_INFO(logger_, "Gather consent records.");
+ utils::dbms::SQLQuery query(db());
+ // Fill data for device
+ if (!query.Prepare(sql_pt_ext::kSelectDeviceConsentedGroup)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect select statement for device consented groups.");
+ return;
+ }
+
+ query.Bind(0, device_id);
+
+ // Fill device_data -> user_consent_records -> "device"
+ while (query.Next()) {
+ policy_table::ConsentRecords* device_consent_records =
+ &(*records)[kDeviceId];
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ policy_table::ConsentGroups& consent_groups =
+ *device_consent_records->consent_groups;
+ consent_groups[query.GetString(1)] = query.GetBoolean(2);
+ policy_table::Input input;
+ policy_table::EnumFromJsonString(query.GetString(3), &input);
+ *device_consent_records->input = input;
+ *device_consent_records->time_stamp = query.GetString(4);
+ }
+
+ if (!query.Reset()) {
+ return;
+ }
+
+ // Fill data for applications
+ if (!query.Prepare(sql_pt_ext::kSelectConsentGroup)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect select statement for app consented groups.");
+ return;
+ }
+
+ query.Bind(0, device_id);
+
+ // Fill device_data -> user_consent_records -> <app_id>
+ while (query.Next()) {
+ policy_table::ConsentRecords* app_consent_records =
+ &(*records)[query.GetString(1)];
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ policy_table::ConsentGroups& consent_groups =
+ *app_consent_records->consent_groups;
+
+ consent_groups[query.GetString(2)] = query.GetBoolean(3);
+ policy_table::Input input;
+ policy_table::EnumFromJsonString(query.GetString(4), &input);
+ *app_consent_records->input = input;
+ *app_consent_records->time_stamp = query.GetString(5);
+ }
+}
+
+bool SQLPTExtRepresentation::SaveDeviceData(
+ const policy_table::DeviceData& devices) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery drop_device_query(db());
+ const std::string drop_device = "DELETE FROM `device`";
+ if (!drop_device_query.Exec(drop_device)) {
+ LOG4CXX_WARN(logger_, "Could not clear device table.");
+ return false;
+ }
+
+ utils::dbms::SQLQuery drop_device_consents_query(db());
+ const std::string drop_device_consents = "DELETE FROM `device_consent_group`";
+ if (!drop_device_consents_query.Exec(drop_device_consents)) {
+ LOG4CXX_WARN(logger_, "Could not clear device consents.");
+ return false;
+ }
+
+ utils::dbms::SQLQuery drop_user_consents_query(db());
+ const std::string drop_user_consents = "DELETE FROM `consent_group`";
+ if (!drop_user_consents_query.Exec(drop_user_consents)) {
+ LOG4CXX_WARN(logger_, "Could not clear user consents.");
+ return false;
+ }
+
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kInsertDeviceData)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for device data.");
+ return false;
+ }
+
+ policy_table::DeviceData::const_iterator it = devices.begin();
+ policy_table::DeviceData::const_iterator it_end = devices.end();
+ for (; it != it_end; ++it) {
+ query.Bind(0, it->first);
+ query.Bind(1, *(it->second.hardware));
+ query.Bind(2, *(it->second.firmware_rev));
+ query.Bind(3, *(it->second.os));
+ query.Bind(4, *(it->second.os_version));
+ query.Bind(5, *(it->second.carrier));
+ query.Bind(6, *(it->second.max_number_rfcom_ports));
+ query.Bind(7, *(it->second.connection_type));
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into device data.");
+ return false;
+ }
+
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ if (!SaveConsentGroup(it->first, *it->second.user_consent_records)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SaveConsentGroup(
+ const std::string& device_id,
+ const policy_table::UserConsentRecords& records) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+
+ policy_table::UserConsentRecords::const_iterator it = records.begin();
+ policy_table::UserConsentRecords::const_iterator it_end = records.end();
+ for (; it != it_end; ++it) {
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ policy_table::ConsentGroups::const_iterator it_groups =
+ it->second.consent_groups->begin();
+ policy_table::ConsentGroups::const_iterator it_groups_end =
+ it->second.consent_groups->end();
+ for (; it_groups != it_groups_end; ++it_groups) {
+ if (kDeviceId == it->first) {
+ if (!query.Prepare(sql_pt_ext::kInsertDeviceConsentedGroup)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement for device consent group.");
+ return false;
+ }
+ query.Bind(0, device_id);
+ query.Bind(1, it_groups->first);
+ query.Bind(2, it_groups->second);
+ query.Bind(
+ 3,
+ std::string(policy_table::EnumToJsonString(*(it->second.input))));
+ query.Bind(4, std::string(*(it->second.time_stamp)));
+ LOG4CXX_INFO(logger_,
+ "Device:"
+ << "time stamp "
+ << std::string(*(it->second.time_stamp)) << " group "
+ << it_groups->first << " consent "
+ << it_groups->second);
+ } else {
+ if (!query.Prepare(sql_pt_ext::kInsertConsentGroups)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement for consent group.");
+ return false;
+ }
+ query.Bind(0, device_id);
+ query.Bind(1, it->first);
+ query.Bind(2, it_groups->first);
+ query.Bind(3, it_groups->second);
+ query.Bind(
+ 4,
+ std::string(policy_table::EnumToJsonString(*(it->second.input))));
+ query.Bind(5, std::string(*(it->second.time_stamp)));
+ LOG4CXX_INFO(logger_,
+ "Device:"
+ << "time stamp "
+ << std::string(*(it->second.time_stamp)) << " group "
+ << it_groups->first << " consent "
+ << it_groups->second);
+ }
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into consent group.");
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SavePreconsentedGroup(
+ const std::string& app_id, const policy_table::Strings& groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kInsertPreconsentedGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for preconsented groups");
+ return false;
+ }
+
+ policy_table::Strings::const_iterator it;
+ for (it = groups.begin(); it != groups.end(); ++it) {
+ query.Bind(0, app_id);
+ query.Bind(1, *it);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into preconsented groups.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void SQLPTExtRepresentation::GatherModuleMeta(
+ policy_table::ModuleMeta* meta) const {
+ LOG4CXX_INFO(logger_, "Gather Module Meta Info");
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt_ext::kSelectModuleMeta) && query.Next()) {
+ *meta->ccpu_version = query.GetString(0);
+ *meta->language = query.GetString(1);
+ *meta->wers_country_code = query.GetString(2);
+ *meta->pt_exchanged_at_odometer_x = query.GetInteger(3);
+ *meta->pt_exchanged_x_days_after_epoch = query.GetInteger(4);
+ *meta->ignition_cycles_since_last_exchange = query.GetInteger(5);
+ *meta->vin = query.GetString(6);
+ }
+}
+
+void SQLPTExtRepresentation::Increment(const std::string& type) const {
+ utils::dbms::SQLQuery query(db());
+ std::string update_counter =
+ "UPDATE `usage_and_error_count` SET `" + type + "` = `" + type + "` + 1";
+ if (!query.Exec(update_counter)) {
+ LOG4CXX_INFO(logger_, "Failed updating global counter");
+ }
+}
+
+bool SQLPTExtRepresentation::IsExistAppLevel(const std::string& app_id) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kCountAppLevel)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement of count app_level");
+ return false;
+ }
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Failed count app_level");
+ return false;
+ }
+ return query.GetInteger(0) > 0;
+}
+
+bool SQLPTExtRepresentation::GetAllAppGroups(const std::string& policy_app_id,
+ FunctionalGroupIDs& all_groups) {
+ LOG4CXX_INFO(logger_, "GetAllAppGroups for '" << policy_app_id << "'");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectAppGroupsId)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for select app groups id.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+
+ while (query.Next()) {
+ all_groups.push_back(query.GetInteger(0));
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GetConsentedGroups(
+ const std::string& policy_app_id,
+ const std::string& device_id,
+ FunctionalGroupIDs& allowed_groups,
+ FunctionalGroupIDs& disallowed_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectConsentedGroupsId)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for select consent groups id.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+ query.Bind(1, device_id);
+
+ while (query.Next()) {
+ if (query.GetBoolean(1)) {
+ allowed_groups.push_back(query.GetInteger(0));
+ } else {
+ disallowed_groups.push_back(query.GetInteger(0));
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GetPreconsentedGroups(
+ const std::string& policy_app_id, FunctionalGroupIDs& preconsented_groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectPreconsentedGroupsId)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect statement for select preconsented groups id.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+
+ while (query.Next()) {
+ preconsented_groups.push_back(query.GetInteger(0));
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::GetFunctionalGroupNames(
+ FunctionalGroupNames& names) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectFunctionalGroupNames)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect statement for select functional groups names.");
+ return false;
+ }
+
+ while (query.Next()) {
+ // Some of functional grous doesn't have filled user_consent_prompt
+ if (query.IsNull(1)) {
+ names[query.GetInteger(0)] =
+ std::make_pair<std::string, std::string>("", query.GetString(2));
+ } else {
+ names[query.GetInteger(0)] = std::make_pair<std::string, std::string>(
+ query.GetString(1), query.GetString(2));
+ }
+ }
+
+ return true;
+}
+
+void SQLPTExtRepresentation::FillFunctionalGroupPermissions(
+ FunctionalGroupIDs& ids,
+ FunctionalGroupNames& names,
+ GroupConsent state,
+ std::vector<FunctionalGroupPermission>& permissions) {
+ FunctionalGroupIDs::const_iterator it = ids.begin();
+ FunctionalGroupIDs::const_iterator it_end = ids.end();
+ for (; it != it_end; ++it) {
+ FunctionalGroupPermission current_group;
+ current_group.group_id = *it;
+ current_group.group_alias = names[*it].first;
+ current_group.group_name = names[*it].second;
+ current_group.state = state;
+ permissions.push_back(current_group);
+ }
+}
+
+void SQLPTExtRepresentation::Increment(const std::string& app_id,
+ const std::string& type) const {
+ utils::dbms::SQLQuery query(db());
+ std::string sql_counter;
+ if (IsExistAppLevel(app_id)) {
+ // update
+ sql_counter = "UPDATE `app_level` SET `" + type + "` = `" + type +
+ "` + 1 WHERE `application_id` = ?";
+ } else {
+ // insert
+ sql_counter = "INSERT INTO `app_level` (`application_id`, `" + type +
+ "`) "
+ "VALUES (?, 1)";
+ }
+ if (!query.Prepare(sql_counter)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement of update app counter");
+ return;
+ }
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Failed updating app counter");
+ }
+}
+
+void SQLPTExtRepresentation::Set(const std::string& app_id,
+ const std::string& type,
+ const std::string& value) const {
+ utils::dbms::SQLQuery query(db());
+ std::string sql_info;
+ if (IsExistAppLevel(app_id)) {
+ // update
+ sql_info = "UPDATE `app_level` SET `" + type +
+ "` = ? "
+ "WHERE `application_id` = ?";
+ } else {
+ // insert
+ sql_info = "INSERT INTO `app_level` (`" + type +
+ "`, `application_id`) "
+ "VALUES (?, ?)";
+ }
+ if (!query.Prepare(sql_info)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement of update app info");
+ return;
+ }
+ query.Bind(0, value);
+ query.Bind(1, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Failed updating app info");
+ }
+}
+
+void SQLPTExtRepresentation::Add(const std::string& app_id,
+ const std::string& type,
+ int seconds) const {
+ utils::dbms::SQLQuery query(db());
+ std::string sql_stopwatch;
+ if (IsExistAppLevel(app_id)) {
+ // update
+ sql_stopwatch = "UPDATE `app_level` SET `" + type + "` = `" + type +
+ "` + ? WHERE `application_id` = ?";
+ } else {
+ // insert
+ sql_stopwatch = "INSERT INTO `app_level` (`" + type +
+ "`, `application_id`) "
+ "VALUES (?, ?)";
+ }
+ if (!query.Prepare(sql_stopwatch)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement of update app stopwatch");
+ return;
+ }
+ query.Bind(0, seconds);
+ query.Bind(1, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Failed updating app stopwatch");
+ }
+}
+
+bool SQLPTExtRepresentation::GetDefaultHMI(const std::string& policy_app_id,
+ std::string* default_hmi) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectDefaultHmi)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement for default hmi.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Error during default hmi getting.");
+ return false;
+ }
+
+ if (query.IsNull(0)) {
+ default_hmi->clear();
+ return true;
+ }
+
+ default_hmi->assign(query.GetString(0));
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::CountUnconsentedGroups(
+ const std::string& policy_app_id,
+ const std::string& device_id,
+ int* result) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kCountUnconsentedGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect select for unconsented groups.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+ query.Bind(1, device_id);
+ query.Bind(2, kDefaultId);
+ query.Bind(3, kPreDataConsentId);
+
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Error during executing unconsented groups.");
+ return false;
+ }
+ *result = query.GetInteger(0);
+ return true;
+}
+
+bool SQLPTExtRepresentation::IsMsgLanguagePresent(const std::string& message,
+ const std::string& language) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kHasMsgLanguageCode)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for message language check.");
+ return false;
+ }
+
+ query.Bind(0, message);
+ query.Bind(1, language);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed to check message language code.");
+ return false;
+ }
+
+ return query.GetInteger(0) != 0;
+}
+
+bool SQLPTExtRepresentation::SaveMessageString(
+ const std::string& type,
+ const std::string& lang,
+ const policy_table::MessageString& strings) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertMessageString)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for message.");
+ return false;
+ }
+
+ query.Bind(0, *strings.tts);
+ query.Bind(1, *strings.label);
+ query.Bind(2, *strings.line1);
+ query.Bind(3, *strings.line2);
+ query.Bind(4, lang);
+ query.Bind(5, type);
+ query.Bind(6, *strings.textBody);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into message.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SaveUsageAndErrorCounts(
+ const policy_table::UsageAndErrorCounts& counts) {
+ return SaveAppCounters(*counts.app_level) && SaveGlobalCounters(counts);
+}
+
+bool SQLPTExtRepresentation::SaveModuleMeta(
+ const policy_table::ModuleMeta& meta) {
+ utils::dbms::SQLQuery query(db());
+
+ if (!query.Prepare(sql_pt_ext::kSaveModuleMeta)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for module_meta.");
+ return false;
+ }
+ const int64_t odometer = *(meta.pt_exchanged_at_odometer_x);
+
+ query.Bind(0, *(meta.ccpu_version));
+ query.Bind(1, *(meta.language));
+ query.Bind(2, *(meta.wers_country_code));
+ query.Bind(3, odometer);
+ query.Bind(4, *(meta.pt_exchanged_x_days_after_epoch));
+ query.Bind(5, *(meta.ignition_cycles_since_last_exchange));
+ query.Bind(6, *(meta.vin));
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect update for module_meta.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::SaveAppCounters(
+ const rpc::policy_table_interface_base::AppLevels& app_levels) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteAppLevel)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from app level.");
+ return false;
+ }
+ if (!query.Prepare(sql_pt::kInsertAppLevel)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for app level.");
+ return false;
+ }
+
+ policy_table::AppLevels::const_iterator it;
+ for (it = app_levels.begin(); it != app_levels.end(); ++it) {
+ query.Bind(0, it->first);
+ query.Bind(1, it->second.minutes_in_hmi_full);
+ query.Bind(2, it->second.minutes_in_hmi_limited);
+ query.Bind(3, it->second.minutes_in_hmi_background);
+ query.Bind(4, it->second.minutes_in_hmi_none);
+ query.Bind(5, it->second.count_of_user_selections);
+ query.Bind(6, it->second.count_of_rejections_sync_out_of_memory);
+ query.Bind(7, it->second.count_of_rejections_nickname_mismatch);
+ query.Bind(8, it->second.count_of_rejections_duplicate_name);
+ query.Bind(9, it->second.count_of_rejected_rpc_calls);
+ query.Bind(10, it->second.count_of_rpcs_sent_in_hmi_none);
+ query.Bind(11, it->second.count_of_removals_for_bad_behavior);
+ query.Bind(12, it->second.count_of_run_attempts_while_revoked);
+ query.Bind(13, it->second.app_registration_language_gui);
+ query.Bind(14, it->second.app_registration_language_vui);
+ query.Bind(15, it->second.count_of_tls_errors);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into app level.");
+ return false;
+ }
+ }
+ return true;
+}
+
+bool SQLPTExtRepresentation::SaveGlobalCounters(
+ const rpc::policy_table_interface_base::UsageAndErrorCounts& counts) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kUpdateGlobalCounters)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for global counters.");
+ return false;
+ }
+
+ query.Bind(0, *counts.count_of_iap_buffer_full);
+ query.Bind(1, *counts.count_sync_out_of_memory);
+ query.Bind(2, *counts.count_of_sync_reboots);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into global counters.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTExtRepresentation::CleanupUnpairedDevices(
+ const DeviceIds& device_ids) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery delete_device_query(db());
+ if (!delete_device_query.Prepare(sql_pt::kDeleteDevice)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for device delete.");
+ return true;
+ }
+
+ utils::dbms::SQLQuery delete_device_consent_query(db());
+ if (!delete_device_consent_query.Prepare(sql_pt_ext::kDeleteDeviceConsent)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for delete device consent.");
+ return false;
+ }
+
+ utils::dbms::SQLQuery delete_app_consent_query(db());
+ if (!delete_app_consent_query.Prepare(sql_pt_ext::kDeleteAppConsent)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement for delete app consent.");
+ return false;
+ }
+
+ DeviceIds::const_iterator it = device_ids.begin();
+ DeviceIds::const_iterator it_end = device_ids.end();
+ for (; it != it_end; ++it) {
+ delete_device_query.Bind(0, (*it));
+ if (!delete_device_query.Exec() || !delete_device_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Failed to delete from device");
+ return false;
+ }
+
+ delete_device_consent_query.Bind(0, (*it));
+ if (!delete_device_consent_query.Exec() ||
+ !delete_device_consent_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Failed to delete from device consent.");
+ return false;
+ }
+
+ delete_app_consent_query.Bind(0, (*it));
+ if (!delete_app_consent_query.Exec() || !delete_app_consent_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Failed to delete from app consent.");
+ return false;
+ }
+ }
+ return true;
+}
+
+bool SQLPTExtRepresentation::SetDefaultPolicy(const std::string& app_id) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kDeleteAppGroupByApplicationId)) {
+ LOG4CXX_ERROR(logger_, "Incorrect statement to delete from app_group.");
+ return false;
+ }
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_ERROR(logger_, "Failed deleting from app_group.");
+ return false;
+ }
+
+ if (!query.Prepare(sql_pt_ext::kDeletePreconsentedGroupsByApplicationId)) {
+ LOG4CXX_ERROR(logger_, "Incorrect statement to delete from app_group.");
+ return false;
+ }
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_ERROR(logger_, "Failed deleting from app_group.");
+ return false;
+ }
+
+ if (!CopyApplication(kDefaultId, app_id)) {
+ return false;
+ }
+
+ SetPreloaded(false);
+
+ policy_table::Strings default_groups;
+ policy_table::Strings default_preconsented_groups;
+ GatherAppGroup(kDefaultId, &default_groups);
+ GatherPreconsentedGroup(kDefaultId, &default_preconsented_groups);
+ if (SaveAppGroup(app_id, default_groups) &&
+ SavePreconsentedGroup(app_id, default_preconsented_groups)) {
+ return SetIsDefault(app_id, true) && SetIsPredata(app_id, false);
+ }
+
+ return false;
+}
+
+bool SQLPTExtRepresentation::SetPredataPolicy(const std::string& app_id) {
+ LOG4CXX_INFO(logger_,
+ "SQLPTExtRepresentation::SetPredataPolicy for " << app_id);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kDeleteAppGroupByApplicationId)) {
+ LOG4CXX_ERROR(logger_, "Incorrect statement to delete from app_group.");
+ return false;
+ }
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_ERROR(logger_, "Failed deleting from app_group.");
+ return false;
+ }
+
+ if (!query.Prepare(sql_pt_ext::kDeletePreconsentedGroupsByApplicationId)) {
+ LOG4CXX_ERROR(logger_, "Incorrect statement to delete from app_group.");
+ return false;
+ }
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_ERROR(logger_, "Failed deleting from app_group.");
+ return false;
+ }
+
+ if (!CopyApplication(kPreDataConsentId, app_id)) {
+ return false;
+ }
+
+ SetPreloaded(false);
+
+ policy_table::Strings predataconsent_groups;
+ policy_table::Strings predataconsent_preconsented_groups;
+ GatherAppGroup(kPreDataConsentId, &predataconsent_groups);
+ GatherPreconsentedGroup(kPreDataConsentId, &predataconsent_groups);
+ if (SaveAppGroup(app_id, predataconsent_groups) &&
+ SavePreconsentedGroup(app_id, predataconsent_groups)) {
+ return SetIsDefault(app_id, false) && SetIsPredata(app_id, true);
+ }
+ return false;
+}
+
+bool SQLPTExtRepresentation::IsPredataPolicy(const std::string& app_id) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectApplicationIsPreData)) {
+ LOG4CXX_WARN(logger_, "Incorrect select application is pre_dataConsented");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed select application is pre_dataConsented");
+ return false;
+ }
+ return query.IsNull(0) ? false : query.GetBoolean(0);
+}
+
+bool SQLPTExtRepresentation::SetIsPredata(const std::string& app_id,
+ bool is_pre_data) {
+ LOG4CXX_TRACE(logger_, "Set flag is_predata of application");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kUpdateIsPredata)) {
+ LOG4CXX_WARN(logger_, "Incorect statement for updating is_predata");
+ return false;
+ }
+
+ query.Bind(0, is_pre_data);
+ query.Bind(1, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed update is_predata");
+ return false;
+ }
+ return true;
+}
+
+bool SQLPTExtRepresentation::SetUnpairedDevice(const std::string& device_id,
+ bool unpaired) const {
+ LOG4CXX_TRACE(logger_, "Set unpaired device: " << device_id);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kUpdateUnpairedDevice)) {
+ LOG4CXX_WARN(logger_, "Incorect statement for updating unpaired device");
+ return false;
+ }
+
+ query.Bind(0, unpaired);
+ query.Bind(1, device_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed update unpaired device");
+ return false;
+ }
+ return true;
+}
+
+bool SQLPTExtRepresentation::UnpairedDevicesList(DeviceIds* device_ids) const {
+ LOG4CXX_TRACE(logger_, "Get list of unpaired devices");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kSelectUnpairedDevices)) {
+ LOG4CXX_WARN(logger_, "Incorect statement for selecting unpaired devices");
+ return false;
+ }
+
+ while (query.Next()) {
+ device_ids->push_back(query.GetString(0));
+ }
+ return true;
+}
+
+bool SQLPTExtRepresentation::SetVINValue(const std::string& value) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kUpdateModuleMetaVinParam)) {
+ LOG4CXX_WARN(logger_, "Incorect statement for updating module_meta params");
+ return false;
+ }
+
+ query.Bind(0, value);
+ const bool result = query.Exec();
+
+ if (!result) {
+ LOG4CXX_WARN(logger_, "Failed update module_meta");
+ }
+ return result;
+}
+
+bool SQLPTExtRepresentation::RemoveAppConsentForGroup(
+ const std::string& policy_app_id,
+ const std::string& functional_group_name) const {
+ utils::dbms::SQLQuery query_group_id(db());
+ if (!query_group_id.Prepare(sql_pt_ext::kSelectGroupId)) {
+ LOG4CXX_WARN(logger_, "Incorect statement for select group name.");
+ return false;
+ }
+
+ query_group_id.Bind(0, functional_group_name);
+
+ if (!query_group_id.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed to select group id.");
+ return false;
+ }
+
+ const int id = query_group_id.GetInteger(0);
+
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt_ext::kDeleteAppGroupConsent)) {
+ LOG4CXX_WARN(logger_, "Incorect statement for remove app consent.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+ query.Bind(1, id);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed to remove app consent.");
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace policy
diff --git a/src/components/policy/policy_regular/src/sql_pt_queries.cc b/src/components/policy/policy_regular/src/sql_pt_queries.cc
new file mode 100644
index 0000000000..df4bc74cc2
--- /dev/null
+++ b/src/components/policy/policy_regular/src/sql_pt_queries.cc
@@ -0,0 +1,712 @@
+/*
+ Copyright (c) 2015, " Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, " with or without
+ modification, " are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, " this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, "
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, " INCLUDING, " BUT NOT LIMITED TO, " THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, " INDIRECT, " INCIDENTAL, " SPECIAL, " EXEMPLARY, " OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, " BUT NOT LIMITED TO, " PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, " DATA, " OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, " WHETHER IN
+ CONTRACT, " STRICT LIABILITY, " OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, " EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "policy/sql_pt_queries.h"
+
+namespace policy {
+namespace sql_pt {
+
+const std::string kSelectPriority =
+ "SELECT `priority_value` FROM `application` WHERE `id` = ? LIMIT 1";
+const std::string kCreateSchema =
+ "BEGIN; "
+ "CREATE TABLE IF NOT EXISTS `device`( "
+ " `id` VARCHAR(100) PRIMARY KEY NOT NULL, "
+ " `hardware` VARCHAR(45), "
+ " `firmware_rev` VARCHAR(45), "
+ " `os` VARCHAR(45), "
+ " `os_version` VARCHAR(45), "
+ " `carrier` VARCHAR(45), "
+ " `max_number_rfcom_ports` INTEGER,"
+ " `connection_type` VARCHAR(45), "
+ " `unpaired` BOOL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `usage_and_error_count`( "
+ " `count_of_iap_buffer_full` INTEGER, "
+ " `count_sync_out_of_memory` INTEGER, "
+ " `count_of_sync_reboots` INTEGER "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `module_meta`( "
+ " `pt_exchanged_at_odometer_x` INTEGER NOT NULL DEFAULT 0, "
+ " `pt_exchanged_x_days_after_epoch` INTEGER NOT NULL DEFAULT 0, "
+ " `ignition_cycles_since_last_exchange` INTEGER NOT NULL DEFAULT 0, "
+ " `flag_update_required` BOOL NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `module_config`( "
+ " `preloaded_pt` BOOL NOT NULL, "
+ " `is_first_run` BOOL NOT NULL, "
+ " `exchange_after_x_ignition_cycles` INTEGER NOT NULL, "
+ " `exchange_after_x_kilometers` INTEGER NOT NULL, "
+ " `exchange_after_x_days` INTEGER NOT NULL, "
+ " `timeout_after_x_seconds` INTEGER NOT NULL, "
+ " `certificate` TEXT, "
+ " `vehicle_make` VARCHAR(45), "
+ " `vehicle_model` VARCHAR(45), "
+ " `vehicle_year` VARCHAR(4) "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `functional_group`( "
+ " `id` INTEGER PRIMARY KEY NOT NULL, "
+ " `user_consent_prompt` TEXT, "
+ " `name` VARCHAR(100) NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `priority`( "
+ " `value` VARCHAR(45) PRIMARY KEY NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `hmi_level`( "
+ " `value` VARCHAR(45) PRIMARY KEY NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `notifications_by_priority`( "
+ " `priority_value` VARCHAR(45) PRIMARY KEY NOT NULL, "
+ " `value` INTEGER NOT NULL, "
+ " CONSTRAINT `fk_notifications_by_priority_priority1` "
+ " FOREIGN KEY(`priority_value`) "
+ " REFERENCES `priority`(`value`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`notifications_by_priority.fk_notifications_by_priority_priority1_idx` "
+ " ON `notifications_by_priority`(`priority_value`); "
+ "CREATE TABLE IF NOT EXISTS `language`( "
+ " `code` VARCHAR(25) PRIMARY KEY NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `message_type`( "
+ " `name` VARCHAR(45) PRIMARY KEY NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `version`( "
+ " `number` VARCHAR(45) NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `rpc`( "
+ " `id` INTEGER PRIMARY KEY NOT NULL, "
+ " `name` VARCHAR(45) NOT NULL, "
+ " `parameter` VARCHAR(45), "
+ " `hmi_level_value` VARCHAR(45) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " CONSTRAINT `fk_rpc_hmi_level1` "
+ " FOREIGN KEY(`hmi_level_value`) "
+ " REFERENCES `hmi_level`(`value`), "
+ " CONSTRAINT `fk_rpc_functional_group1` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `rpc.fk_rpc_hmi_level1_idx` "
+ " ON `rpc`(`hmi_level_value`); "
+ "CREATE INDEX IF NOT EXISTS `rpc.fk_rpc_functional_group1_idx` "
+ " ON `rpc`(`functional_group_id`); "
+ "CREATE INDEX `rpc.select_rpc_name_hmi_level` "
+ " ON `rpc`(`name`,`hmi_level_value`);"
+ "CREATE TABLE IF NOT EXISTS `application`( "
+ " `id` VARCHAR(45) PRIMARY KEY NOT NULL, "
+ " `keep_context` BOOLEAN, "
+ " `steal_focus` BOOLEAN, "
+ " `default_hmi` VARCHAR(45), "
+ " `priority_value` VARCHAR(45), "
+ " `is_revoked` BOOLEAN, "
+ " `is_default` BOOLEAN, "
+ " `is_predata` BOOLEAN, "
+ " `memory_kb` INTEGER NOT NULL, "
+ " `heart_beat_timeout_ms` INTEGER NOT NULL, "
+ " `certificate` VARCHAR(45), "
+ " CONSTRAINT `fk_application_hmi_level1` "
+ " FOREIGN KEY(`default_hmi`) "
+ " REFERENCES `hmi_level`(`value`), "
+ " CONSTRAINT `fk_application_priorities1` "
+ " FOREIGN KEY(`priority_value`) "
+ " REFERENCES `priority`(`value`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `application.fk_application_hmi_level1_idx` "
+ " ON `application`(`default_hmi`); "
+ "CREATE INDEX IF NOT EXISTS `application.fk_application_priorities1_idx` "
+ " ON `application`(`priority_value`); "
+ "CREATE TABLE IF NOT EXISTS `app_group`( "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " PRIMARY KEY(`application_id`,`functional_group_id`), "
+ " CONSTRAINT `fk_application_has_functional_group_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`), "
+ " CONSTRAINT `fk_application_has_functional_group_functional_group1` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`app_group.fk_application_has_functional_group_functional_group1_idx` "
+ " ON `app_group`(`functional_group_id`); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`app_group.fk_application_has_functional_group_application1_idx` "
+ " ON `app_group`(`application_id`); "
+ "CREATE TABLE IF NOT EXISTS `preconsented_group`( "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " PRIMARY KEY(`application_id`,`functional_group_id`), "
+ " CONSTRAINT `fk_application_has_functional_group_application2` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`), "
+ " CONSTRAINT `fk_application_has_functional_group_functional_group2` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`preconsented_group.fk_application_has_functional_group_functional_group2_"
+ "idx` "
+ " ON `preconsented_group`(`functional_group_id`); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`preconsented_group.fk_application_has_functional_group_application2_idx` "
+ " ON `preconsented_group`(`application_id`); "
+ "CREATE TABLE IF NOT EXISTS `seconds_between_retry`( "
+ " `index` INTEGER PRIMARY KEY NOT NULL, "
+ " `value` INTEGER NOT NULL "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `device_consent_group`( "
+ " `device_id` VARCHAR(100) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " `is_consented` BOOL NOT NULL, "
+ " `input` VARCHAR(45), "
+ " `time_stamp` VARCHAR(45), "
+ " PRIMARY KEY(`device_id`,`functional_group_id`), "
+ " CONSTRAINT `fk_device_has_functional_group_device1` "
+ " FOREIGN KEY(`device_id`) "
+ " REFERENCES `device`(`id`), "
+ " CONSTRAINT `fk_device_has_functional_group_functional_group1` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`device_consent_group.fk_device_has_functional_group_functional_group1_"
+ "idx` "
+ " ON `device_consent_group`(`functional_group_id`); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`device_consent_group.fk_device_has_functional_group_device1_idx` "
+ " ON `device_consent_group`(`device_id`); "
+ "CREATE TABLE IF NOT EXISTS `app_level`( "
+ " `application_id` VARCHAR(45) PRIMARY KEY NOT NULL, "
+ " `minutes_in_hmi_full` INTEGER DEFAULT 0, "
+ " `minutes_in_hmi_limited` INTEGER DEFAULT 0, "
+ " `minutes_in_hmi_background` INTEGER DEFAULT 0, "
+ " `minutes_in_hmi_none` INTEGER DEFAULT 0, "
+ " `count_of_user_selections` INTEGER DEFAULT 0, "
+ " `count_of_rejections_sync_out_of_memory` INTEGER DEFAULT 0, "
+ " `count_of_rejections_nickname_mismatch` INTEGER DEFAULT 0, "
+ " `count_of_rejections_duplicate_name` INTEGER DEFAULT 0, "
+ " `count_of_rejected_rpcs_calls` INTEGER DEFAULT 0, "
+ " `count_of_rpcs_sent_in_hmi_none` INTEGER DEFAULT 0, "
+ " `count_of_removals_for_bad_behavior` INTEGER DEFAULT 0, "
+ " `count_of_run_attempts_while_revoked` INTEGER DEFAULT 0, "
+ " `count_of_tls_errors` INTEGER DEFAULT 0, "
+ " `app_registration_language_gui` VARCHAR(25), "
+ " `app_registration_language_vui` VARCHAR(25), "
+ " CONSTRAINT `fk_app_levels_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`), "
+ " CONSTRAINT `fk_app_level_language1` "
+ " FOREIGN KEY(`app_registration_language_gui`) "
+ " REFERENCES `language`(`code`), "
+ " CONSTRAINT `fk_app_level_language2` "
+ " FOREIGN KEY(`app_registration_language_vui`) "
+ " REFERENCES `language`(`code`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `app_level.fk_app_levels_application1_idx` "
+ " ON `app_level`(`application_id`); "
+ "CREATE INDEX IF NOT EXISTS `app_level.fk_app_level_language1_idx` "
+ " ON `app_level`(`app_registration_language_gui`); "
+ "CREATE INDEX IF NOT EXISTS `app_level.fk_app_level_language2_idx` "
+ " ON `app_level`(`app_registration_language_vui`); "
+ "CREATE TABLE IF NOT EXISTS `nickname`( "
+ " `name` VARCHAR(100) NOT NULL, "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " PRIMARY KEY(`name`,`application_id`), "
+ " CONSTRAINT `fk_nickname_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `nickname.fk_nickname_application1_idx` "
+ " ON `nickname`(`application_id`); "
+ "CREATE TABLE IF NOT EXISTS `app_type`( "
+ " `name` VARCHAR(50) NOT NULL, "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " PRIMARY KEY(`name`,`application_id`), "
+ " CONSTRAINT `fk_app_type_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`) "
+ "); "
+ "CREATE TABLE IF NOT EXISTS `request_type`( "
+ " `request_type` VARCHAR(50) NOT NULL, "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " PRIMARY KEY(`request_type`,`application_id`), "
+ " CONSTRAINT `fk_app_type_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `app_type.fk_app_type_application1_idx` "
+ " ON `app_type`(`application_id`); "
+ "CREATE TABLE IF NOT EXISTS `consent_group`( "
+ " `device_id` VARCHAR(100) NOT NULL, "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " `functional_group_id` INTEGER NOT NULL, "
+ " `is_consented` BOOL NOT NULL, "
+ " `input` VARCHAR(45), "
+ " `time_stamp` VARCHAR(45), "
+ " PRIMARY KEY(`application_id`,`functional_group_id`,`device_id`), "
+ " CONSTRAINT `fk_consent_group_device1` "
+ " FOREIGN KEY(`device_id`) "
+ " REFERENCES `device`(`id`), "
+ " CONSTRAINT `fk_consent_group_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`), "
+ " CONSTRAINT `fk_consent_group_functional_group1` "
+ " FOREIGN KEY(`functional_group_id`) "
+ " REFERENCES `functional_group`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`consent_group.fk_consent_group_device1_idx` "
+ " ON `device_consent_group`(`device_id`); "
+ "CREATE INDEX IF NOT EXISTS "
+ "`consent_group.fk_consent_group_functional_group1_idx` "
+ " ON `consent_group`(`functional_group_id`); "
+ "CREATE TABLE IF NOT EXISTS `endpoint`( "
+ " `service` VARCHAR(100) NOT NULL, "
+ " `url` VARCHAR(100) NOT NULL, "
+ " `application_id` VARCHAR(45) NOT NULL, "
+ " CONSTRAINT `fk_endpoint_application1` "
+ " FOREIGN KEY(`application_id`) "
+ " REFERENCES `application`(`id`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `endpoint.fk_endpoint_application1_idx` "
+ " ON `endpoint`(`application_id`); "
+ "CREATE TABLE IF NOT EXISTS `message`( "
+ " `id` INTEGER PRIMARY KEY NOT NULL, "
+ " `tts` TEXT, "
+ " `label` TEXT, "
+ " `line1` TEXT, "
+ " `line2` TEXT, "
+ " `textBody` TEXT, "
+ " `language_code` VARCHAR(25) NOT NULL, "
+ " `message_type_name` VARCHAR(45) NOT NULL, "
+ " CONSTRAINT `fk_messages_languages1` "
+ " FOREIGN KEY(`language_code`) "
+ " REFERENCES `language`(`code`), "
+ " CONSTRAINT `fk_message_consumer_friendly_messages1` "
+ " FOREIGN KEY(`message_type_name`) "
+ " REFERENCES `message_type`(`name`) "
+ "); "
+ "CREATE INDEX IF NOT EXISTS `message.fk_messages_languages1_idx` "
+ " ON `message`(`language_code`);"
+ "CREATE INDEX IF NOT EXISTS "
+ "`message.fk_message_consumer_friendly_messages1_idx` "
+ " ON `message`(`message_type_name`);"
+ "CREATE TABLE IF NOT EXISTS `_internal_data`( "
+ " `db_version_hash` INTEGER "
+ " ); "
+ "COMMIT;";
+
+const std::string kInsertInitData =
+ "INSERT OR IGNORE INTO `usage_and_error_count` ( "
+ " `count_of_iap_buffer_full`, `count_sync_out_of_memory`, "
+ " `count_of_sync_reboots`) VALUES (0, 0, 0); "
+ "INSERT OR IGNORE INTO `module_meta` (`pt_exchanged_at_odometer_x`, "
+ " `pt_exchanged_x_days_after_epoch`, "
+ "`ignition_cycles_since_last_exchange`,"
+ " `flag_update_required`) "
+ " VALUES (0, 0, 0, 0); "
+ "INSERT OR IGNORE INTO `module_config` (`preloaded_pt`, `is_first_run`,"
+ " `exchange_after_x_ignition_cycles`, `exchange_after_x_kilometers`, "
+ " `exchange_after_x_days`, `timeout_after_x_seconds`) "
+ " VALUES(1, 0, 0, 0, 0, 0); "
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('EMERGENCY'); "
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('NAVIGATION'); "
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('VOICECOMMUNICATION'); "
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('COMMUNICATION'); "
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('NORMAL'); "
+ "INSERT OR IGNORE INTO `priority`(`value`) VALUES ('NONE'); "
+ "INSERT OR IGNORE INTO `hmi_level`(`value`) VALUES ('FULL'); "
+ "INSERT OR IGNORE INTO `hmi_level`(`value`) VALUES ('LIMITED'); "
+ "INSERT OR IGNORE INTO `hmi_level`(`value`) VALUES ('BACKGROUND'); "
+ "INSERT OR IGNORE INTO `hmi_level`(`value`) VALUES ('NONE'); "
+ "INSERT OR IGNORE INTO `version` (`number`) VALUES('0'); "
+ "INSERT OR IGNORE INTO `_internal_data` (`db_version_hash`) VALUES(0); "
+ "";
+
+const std::string kDropSchema =
+ "BEGIN; "
+ "DROP INDEX IF EXISTS `message.fk_messages_languages1_idx`; "
+ "DROP INDEX IF EXISTS "
+ "`message.fk_message_consumer_friendly_messages1_idx`; "
+ "DROP TABLE IF EXISTS `message`; "
+ "DROP INDEX IF EXISTS `endpoint.fk_endpoint_application1_idx`; "
+ "DROP TABLE IF EXISTS `endpoint`; "
+ "DROP INDEX IF EXISTS `consent_group.fk_consent_group_device1_idx`; "
+ "DROP INDEX IF EXISTS "
+ "`consent_group.fk_consent_group_functional_group1_idx`; "
+ "DROP TABLE IF EXISTS `consent_group`; "
+ "DROP INDEX IF EXISTS `app_type.fk_app_type_application1_idx`; "
+ "DROP TABLE IF EXISTS `app_type`; "
+ "DROP INDEX IF EXISTS `nickname.fk_nickname_application1_idx`; "
+ "DROP TABLE IF EXISTS `nickname`; "
+ "DROP INDEX IF EXISTS `app_level.fk_app_level_language2_idx`; "
+ "DROP INDEX IF EXISTS `app_level.fk_app_level_language1_idx`; "
+ "DROP INDEX IF EXISTS `app_level.fk_app_levels_application1_idx`; "
+ "DROP TABLE IF EXISTS `app_level`; "
+ "DROP INDEX IF EXISTS "
+ "`device_consent_group.fk_device_has_functional_group_device1_idx`; "
+ "DROP INDEX IF EXISTS "
+ "`device_consent_group.fk_device_has_functional_group_functional_group1_"
+ "idx`; "
+ "DROP TABLE IF EXISTS `device_consent_group`; "
+ "DROP TABLE IF EXISTS `seconds_between_retry`; "
+ "DROP INDEX IF EXISTS "
+ "`preconsented_group.fk_application_has_functional_group_application2_idx`;"
+ " "
+ "DROP INDEX IF EXISTS "
+ "`preconsented_group.fk_application_has_functional_group_functional_group2_"
+ "idx`; "
+ "DROP TABLE IF EXISTS `preconsented_group`; "
+ "DROP INDEX IF EXISTS "
+ "`app_group.fk_application_has_functional_group_application1_idx`; "
+ "DROP INDEX IF EXISTS "
+ "`app_group.fk_application_has_functional_group_functional_group1_idx`; "
+ "DROP TABLE IF EXISTS `app_group`; "
+ "DROP INDEX IF EXISTS `application.fk_application_priorities1_idx`; "
+ "DROP INDEX IF EXISTS `application.fk_application_hmi_level1_idx`; "
+ "DROP TABLE IF EXISTS `application`; "
+ "DROP INDEX IF EXISTS `rpc.select_rpc_name_hmi_level`; "
+ "DROP INDEX IF EXISTS `rpc.fk_rpc_functional_group1_idx`; "
+ "DROP INDEX IF EXISTS `rpc.fk_rpc_hmi_level1_idx`; "
+ "DROP TABLE IF EXISTS `rpc`; "
+ "DROP TABLE IF EXISTS `version`; "
+ "DROP TABLE IF EXISTS `message_type`; "
+ "DROP TABLE IF EXISTS `language`; "
+ "DROP INDEX IF EXISTS "
+ "`notifications_by_priority.fk_notifications_by_priority_priority1_idx`; "
+ "DROP TABLE IF EXISTS `notifications_by_priority`; "
+ "DROP TABLE IF EXISTS `hmi_level`; "
+ "DROP TABLE IF EXISTS `priority`; "
+ "DROP TABLE IF EXISTS `functional_group`; "
+ "DROP TABLE IF EXISTS `module_config`; "
+ "DROP TABLE IF EXISTS `module_meta`; "
+ "DROP TABLE IF EXISTS `usage_and_error_count`; "
+ "DROP TABLE IF EXISTS `device`; "
+ "DROP TABLE IF EXISTS `_internal_data`; "
+ "COMMIT; "
+ "VACUUM;";
+
+const std::string kDeleteData =
+ "BEGIN; "
+ "DELETE FROM `message`; "
+ "DELETE FROM `endpoint`; "
+ "DELETE FROM `consent_group`; "
+ "DELETE FROM `app_type`; "
+ "DELETE FROM `nickname`; "
+ "DELETE FROM `app_level`; "
+ "DELETE FROM `device_consent_group`; "
+ "DELETE FROM `seconds_between_retry`; "
+ "DELETE FROM `preconsented_group`; "
+ "DELETE FROM `app_group`; "
+ "DELETE FROM `application`; "
+ "DELETE FROM `rpc`; "
+ "DELETE FROM `version`; "
+ "DELETE FROM `message_type`; "
+ "DELETE FROM `language`; "
+ "DELETE FROM `notifications_by_priority`; "
+ "DELETE FROM `hmi_level`; "
+ "DELETE FROM `priority`; "
+ "DELETE FROM `functional_group`; "
+ "DELETE FROM `module_config`; "
+ "DELETE FROM `module_meta`; "
+ "DELETE FROM `usage_and_error_count`; "
+ "DELETE FROM `device`; "
+ "COMMIT; "
+ "VACUUM;";
+
+const std::string kCheckDBIntegrity = "PRAGMA integrity_check";
+
+const std::string kCheckPgNumber = "PRAGMA page_count";
+
+const std::string kSelectRpc =
+ "SELECT DISTINCT `rpc`.`parameter` FROM `rpc` "
+ " JOIN `app_group` AS `g` ON (`g`.`functional_group_id` = "
+ "`rpc`.`functional_group_id` "
+ " AND (`g`.`application_id` = ?)) "
+ "WHERE `rpc`.`hmi_level_value` = ? AND `rpc`.`name` = ?";
+
+const std::string kSelectPreloaded =
+ "SELECT `preloaded_pt` FROM `module_config` "
+ "WHERE `preloaded_pt` = 1 LIMIT 1";
+
+const std::string kUpdatePreloaded =
+ "UPDATE `module_config` SET `preloaded_pt` = ?";
+
+const std::string kIsFirstRun = "SELECT `is_first_run` FROM `module_config` ";
+
+const std::string kSetNotFirstRun =
+ "UPDATE `module_config` SET `is_first_run`= 0 ";
+
+const std::string kSelectEndpoint =
+ "SELECT `url`, `application_id` FROM `endpoint` WHERE `service` = ? ";
+
+const std::string kSelectLockScreenIcon =
+ "SELECT `url` FROM `endpoint` WHERE `service` = ? AND `application_id` = ?";
+
+const std::string kInsertFunctionalGroup =
+ "INSERT INTO `functional_group` (`id`, `name`, `user_consent_prompt`) "
+ " VALUES (?, ?, ?)";
+
+const std::string kInsertRpc =
+ "INSERT INTO `rpc` (`name`, `hmi_level_value`, `functional_group_id`) "
+ " VALUES (?, ?, ?)";
+
+const std::string kInsertRpcWithParameter =
+ "INSERT INTO `rpc` (`name`, `hmi_level_value`, `parameter`, "
+ "`functional_group_id`) "
+ " VALUES (?, ?, ?, ?)";
+
+const std::string kInsertApplication =
+ "INSERT OR IGNORE INTO `application` (`id`, `priority_value`, "
+ "`is_revoked`, `memory_kb`,"
+ " `heart_beat_timeout_ms`, `certificate`) VALUES (?,?,?,?,?,?)";
+
+const std::string kInsertAppGroup =
+ "INSERT INTO `app_group` (`application_id`, `functional_group_id`)"
+ " SELECT ?, `id` FROM `functional_group` WHERE `name` = ? LIMIT 1";
+
+const std::string kInsertNickname =
+ "INSERT OR IGNORE INTO `nickname` (`application_id`, `name`) VALUES (?, ?)";
+
+const std::string kInsertAppType =
+ "INSERT OR IGNORE INTO `app_type` (`application_id`, `name`) VALUES (?, ?)";
+
+const std::string kInsertRequestType =
+ "INSERT OR IGNORE INTO `request_type` (`application_id`, `request_type`) "
+ "VALUES (?, ?)";
+
+const std::string kUpdateVersion = "UPDATE `version` SET `number`= ?";
+
+const std::string kInsertMessageType =
+ "INSERT OR IGNORE INTO `message_type` (`name`) VALUES (?)";
+
+const std::string kInsertLanguage =
+ "INSERT OR IGNORE INTO `language` (`code`) VALUES (?)";
+
+const std::string kInsertMessageString =
+ "INSERT INTO `message` (`language_code`, `message_type_name`) "
+ "VALUES (?, ?)";
+
+const std::string kUpdateModuleConfig =
+ "UPDATE `module_config` SET `preloaded_pt` = ?, "
+ " `exchange_after_x_ignition_cycles` = ?,"
+ " `exchange_after_x_kilometers` = ?, `exchange_after_x_days` = ?, "
+ " `timeout_after_x_seconds` = ?, `certificate` = ?, `vehicle_make` = ?, "
+ " `vehicle_model` = ?, `vehicle_year` = ?";
+
+const std::string kInsertEndpoint =
+ "INSERT INTO `endpoint` (`service`, `url`, `application_id`) "
+ " VALUES (?, ?, ?)";
+
+const std::string kInsertSecondsBetweenRetry =
+ "INSERT INTO `seconds_between_retry` (`index`, `value`) VALUES (?, ?)";
+
+const std::string kInsertNotificationsByPriority =
+ "INSERT OR REPLACE INTO `notifications_by_priority` (`priority_value`, "
+ "`value`) "
+ " VALUES (?, ?)";
+
+const std::string kInsertDeviceData =
+ "INSERT OR IGNORE INTO `device` (`id`) VALUES (?)";
+
+const std::string kInsertAppLevel =
+ "INSERT INTO `app_level` (`application_id`, `count_of_tls_errors`) "
+ "VALUES(?,?)";
+
+const std::string kDeleteSecondsBetweenRetries =
+ "DELETE FROM `seconds_between_retry`";
+
+const std::string kDeleteEndpoint = "DELETE FROM `endpoint`";
+
+const std::string kDeleteAppLevel = "DELETE FROM `app_level`";
+
+const std::string kDeleteMessageString = "DELETE FROM `message`";
+
+const std::string kDeleteFunctionalGroup = "DELETE FROM `functional_group`";
+
+const std::string kDeleteRpc = "DELETE FROM `rpc`";
+
+const std::string kDeleteAppGroup = "DELETE FROM `app_group`";
+
+const std::string kSelectModuleConfig =
+ "SELECT `preloaded_pt`, `exchange_after_x_ignition_cycles`, "
+ " `exchange_after_x_kilometers`, `exchange_after_x_days`, "
+ " `timeout_after_x_seconds`, `certificate`, `vehicle_make`,"
+ " `vehicle_model`, `vehicle_year` "
+ " FROM `module_config`";
+
+const std::string kSelectEndpoints =
+ "SELECT `url`, `service`, `application_id` FROM `endpoint` ";
+
+const std::string kSelectNotificationsPerMin =
+ "SELECT `priority_value`, `value` FROM notifications_by_priority";
+
+const std::string kSelectNotificationsPerPriority =
+ "SELECT `value` FROM notifications_by_priority WHERE `priority_value` = ? ";
+
+const std::string kSelectAppLevels =
+ "SELECT `application_id`, `count_of_tls_errors` "
+ "FROM `app_level`";
+
+const std::string kSelectDeviceData = "SELECT * FROM `device`";
+
+const std::string kSelectFunctionalGroups =
+ "SELECT `id`,`name`, `user_consent_prompt` "
+ "FROM `functional_group`";
+
+const std::string kSelectAllRpcs =
+ "SELECT `name`, `hmi_level_value`, `parameter` "
+ "FROM `rpc` WHERE `functional_group_id` = ? ";
+
+const std::string kSelectUserMsgsVersion =
+ "SELECT DISTINCT `number` FROM `version`";
+
+const std::string kSelectAppPolicies =
+ "SELECT `id`, `priority_value`, `memory_kb`, "
+ " `heart_beat_timeout_ms`, `certificate` FROM `application`";
+
+const std::string kCollectFriendlyMsg = "SELECT * FROM `message`";
+
+const std::string kSelectAppGroups =
+ "SELECT `f`.`name` FROM `app_group` AS `a`"
+ " LEFT JOIN `functional_group` AS `f` "
+ " ON (`f`.`id` = `a`.`functional_group_id`)"
+ " WHERE `a`.`application_id` = ?";
+
+const std::string kSelectNicknames =
+ "SELECT DISTINCT `name` FROM `nickname` "
+ "WHERE `application_id` = ?";
+
+const std::string kSelectAppTypes =
+ "SELECT DISTINCT `name` FROM `app_type` "
+ "WHERE `application_id` = ?";
+
+const std::string kSelectRequestTypes =
+ "SELECT DISTINCT `request_type` FROM `request_type` WHERE `application_id` "
+ "= ?";
+
+const std::string kSelectSecondsBetweenRetries =
+ "SELECT `value` FROM `seconds_between_retry` ORDER BY `index`";
+
+const std::string kSelectIgnitionCycles =
+ "SELECT `c`.`exchange_after_x_ignition_cycles`, "
+ " `m`.`ignition_cycles_since_last_exchange` "
+ " FROM `module_config` AS `c`, `module_meta` AS `m` "
+ "LIMIT 1";
+
+const std::string kSelectKilometers =
+ "SELECT `c`.`exchange_after_x_kilometers`, "
+ " `m`.`pt_exchanged_at_odometer_x` "
+ " FROM `module_config` AS `c`, `module_meta` AS `m` "
+ "LIMIT 1";
+
+const std::string kSelectDays =
+ "SELECT `c`.`exchange_after_x_days`, "
+ " `m`.`pt_exchanged_x_days_after_epoch` "
+ " FROM `module_config` AS `c`, `module_meta` AS `m` "
+ "LIMIT 1";
+
+const std::string kIncrementIgnitionCycles =
+ "UPDATE `module_meta` SET `ignition_cycles_since_last_exchange` = 1 + "
+ " `ignition_cycles_since_last_exchange`";
+
+const std::string kResetIgnitionCycles =
+ "UPDATE `module_meta` SET `ignition_cycles_since_last_exchange` = 0";
+
+const std::string kSelectTimeoutResponse =
+ "SELECT `timeout_after_x_seconds` FROM `module_config` LIMIT 1";
+
+const std::string kUpdateFlagUpdateRequired =
+ "UPDATE `module_meta` SET `flag_update_required` = ?";
+
+const std::string kSelectFlagUpdateRequired =
+ "SELECT `flag_update_required` FROM `module_meta` LIMIT 1";
+
+const std::string kUpdateCountersSuccessfulUpdate =
+ "UPDATE `module_meta` SET `pt_exchanged_at_odometer_x` = ?,"
+ "`pt_exchanged_x_days_after_epoch` = ?";
+
+const std::string kDeleteApplication = "DELETE FROM `application`";
+
+const std::string kDeleteRequestType = "DELETE FROM `request_type`";
+
+const std::string kSelectApplicationRevoked =
+ "SELECT `is_revoked` FROM `application` WHERE `id` = ?";
+
+const std::string kUpdateApplicationCustomData =
+ "UPDATE `application` SET `is_revoked` = ?, `is_default` = ?,"
+ "`is_predata` = ? WHERE `id` = ?";
+
+const std::string kSelectApplicationRepresented =
+ "SELECT COUNT(`id`) FROM `application` WHERE `id` = ?";
+
+const std::string kSelectApplicationIsDefault =
+ "SELECT `is_default` FROM `application` WHERE `id` = ?";
+
+const std::string kUpdateIsDefault =
+ "UPDATE `application` SET `is_default` = ? WHERE `id` = ?";
+
+const std::string kDeleteDevice = "DELETE FROM `device` WHERE `id` = ?";
+
+const std::string kDeleteAppGroupByApplicationId =
+ "DELETE FROM `app_group` WHERE `application_id` = ?";
+
+const std::string kInsertApplicationFull =
+ "INSERT OR IGNORE INTO `application` (`id`, `keep_context`, `steal_focus`, "
+ " `default_hmi`, `priority_value`, `is_revoked`, `is_default`, "
+ "`is_predata`, "
+ " `memory_kb`, `heart_beat_timeout_ms`, `certificate`) "
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+const std::string kSelectApplicationFull =
+ "SELECT `keep_context`, `steal_focus`, `default_hmi`, `priority_value`, "
+ " `is_revoked`, `is_default`, `is_predata`, `memory_kb`,"
+ " `heart_beat_timeout_ms`, `certificate` FROM `application` WHERE `id` = "
+ "?";
+
+const std::string kSelectDBVersion =
+ "SELECT `db_version_hash` from `_internal_data`";
+
+const std::string kUpdateDBVersion =
+ "UPDATE `_internal_data` SET `db_version_hash` = ? ";
+
+const std::string kSaveModuleMeta =
+ "UPDATE `module_meta` SET "
+ "`pt_exchanged_at_odometer_x` = ?, "
+ "`pt_exchanged_x_days_after_epoch` = ?, "
+ "`ignition_cycles_since_last_exchange` = ? ";
+
+const std::string kSelectModuleMeta = "SELECT* FROM `module_meta`";
+
+} // namespace sql_pt
+} // namespace policy
diff --git a/src/components/policy/policy_regular/src/sql_pt_representation.cc b/src/components/policy/policy_regular/src/sql_pt_representation.cc
new file mode 100644
index 0000000000..e94c853414
--- /dev/null
+++ b/src/components/policy/policy_regular/src/sql_pt_representation.cc
@@ -0,0 +1,1755 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sstream>
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "utils/logger.h"
+#include "utils/date_time.h"
+#include "utils/file_system.h"
+#include "utils/gen_hash.h"
+#include "policy/sql_pt_representation.h"
+#include "policy/sql_wrapper.h"
+#include "policy/sql_pt_queries.h"
+#include "policy/policy_helper.h"
+#include "policy/cache_manager.h"
+#include "config_profile/profile.h"
+
+namespace policy {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Policy")
+
+namespace {
+template <typename T, typename K>
+void InsertUnique(K value, T* array) {
+ uint32_t i = 0;
+ for (; i < array->size() && array->at(i) != value; ++i) {
+ continue;
+ }
+ if (array->size() == i) {
+ array->push_back(value);
+ }
+}
+} // namespace
+
+const std::string SQLPTRepresentation::kDatabaseName = "policy";
+
+SQLPTRepresentation::SQLPTRepresentation()
+ : db_(new utils::dbms::SQLDatabase(kDatabaseName)) {}
+
+SQLPTRepresentation::~SQLPTRepresentation() {
+ db_->Close();
+ delete db_;
+}
+
+void SQLPTRepresentation::CheckPermissions(const PTString& app_id,
+ const PTString& hmi_level,
+ const PTString& rpc,
+ CheckPermissionResult& result) {
+ utils::dbms::SQLQuery query(db());
+
+ if (!query.Prepare(sql_pt::kSelectRpc)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect select statement from rpcs"
+ << query.LastError().text());
+ return;
+ }
+ query.Bind(0, app_id);
+ query.Bind(1, hmi_level);
+ query.Bind(2, rpc);
+
+ bool ret = query.Next();
+ result.hmi_level_permitted = ret ? kRpcAllowed : kRpcDisallowed;
+ LOG4CXX_INFO(logger_,
+ "Level is " << (result.hmi_level_permitted == kRpcAllowed
+ ? "permitted"
+ : "not permitted"));
+ std::string parameter;
+ while (ret) {
+ if (!query.IsNull(0)) {
+ parameter = query.GetString(0);
+ result.list_of_allowed_params.insert(parameter);
+ }
+ ret = query.Next();
+ }
+}
+
+bool SQLPTRepresentation::IsPTPreloaded() {
+ utils::dbms::SQLQuery query(db());
+ return query.Prepare(sql_pt::kSelectPreloaded) && query.Next();
+}
+
+int SQLPTRepresentation::IgnitionCyclesBeforeExchange() {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectIgnitionCycles) || !query.Exec()) {
+ LOG4CXX_WARN(logger_, "Can not select ignition cycles");
+ return 0;
+ }
+ int limit = query.GetInteger(0);
+ int current = query.GetInteger(1);
+
+ if (limit < 0 || current < 0 || current > limit) {
+ return 0;
+ }
+
+ return limit - current;
+}
+
+int SQLPTRepresentation::KilometersBeforeExchange(int current) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectKilometers) || !query.Exec()) {
+ LOG4CXX_WARN(logger_, "Can not select kilometers");
+ return 0;
+ }
+ int limit = query.GetInteger(0);
+ int last = query.GetInteger(1);
+
+ if (limit < 0 || last < 0 || current < 0 || current < last ||
+ limit < (current - last)) {
+ return 0;
+ }
+
+ return limit - (current - last);
+}
+
+bool SQLPTRepresentation::SetCountersPassedForSuccessfulUpdate(
+ int kilometers, int days_after_epoch) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kUpdateCountersSuccessfulUpdate)) {
+ LOG4CXX_WARN(logger_,
+ "Wrong update query for counters on successful update.");
+ return false;
+ }
+ query.Bind(0, kilometers);
+ query.Bind(1, days_after_epoch);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed to update counters on successful update.");
+ return false;
+ }
+ return true;
+}
+
+int SQLPTRepresentation::DaysBeforeExchange(int current) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectDays) || !query.Exec()) {
+ LOG4CXX_WARN(logger_, "Can not select days");
+ return 0;
+ }
+ int limit = query.GetInteger(0);
+ int last = query.GetInteger(1);
+
+ if (0 == last) {
+ return limit;
+ }
+
+ if (limit < 0 || last < 0 || current < 0 || current < last ||
+ limit < (current - last)) {
+ return 0;
+ }
+
+ return limit - (current - last);
+}
+
+int SQLPTRepresentation::TimeoutResponse() {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectTimeoutResponse) || !query.Exec()) {
+ LOG4CXX_INFO(logger_, "Can not select timeout response for retry sequence");
+ const int defaultTimeout = 30 * date_time::DateTime::MILLISECONDS_IN_SECOND;
+ return defaultTimeout;
+ }
+ return query.GetInteger(0) * date_time::DateTime::MILLISECONDS_IN_SECOND;
+}
+
+bool SQLPTRepresentation::SecondsBetweenRetries(std::vector<int>* seconds) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectSecondsBetweenRetries)) {
+ LOG4CXX_INFO(logger_,
+ "Incorrect select statement from seconds between retries");
+ return false;
+ }
+ while (query.Next()) {
+ seconds->push_back(query.GetInteger(0));
+ }
+ return true;
+}
+
+std::vector<UserFriendlyMessage> SQLPTRepresentation::GetUserFriendlyMsg(
+ const std::vector<std::string>& msg_codes, const std::string& language) {
+ std::vector<UserFriendlyMessage> result;
+ std::vector<std::string>::const_iterator it = msg_codes.begin();
+ std::vector<std::string>::const_iterator it_end = msg_codes.end();
+ for (; it != it_end; ++it) {
+ UserFriendlyMessage msg;
+ msg.message_code = *it;
+ result.push_back(msg);
+ }
+ return result;
+}
+
+EndpointUrls SQLPTRepresentation::GetUpdateUrls(int service_type) {
+ LOG4CXX_INFO(logger_,
+ "SQLPTRepresentation::GetUpdateUrls for " << service_type);
+ utils::dbms::SQLQuery query(db());
+ EndpointUrls ret;
+ if (query.Prepare(sql_pt::kSelectEndpoint)) {
+ query.Bind(0, service_type);
+ while (query.Next()) {
+ EndpointData data;
+
+ data.url.push_back(query.GetString(0));
+ if (!query.IsNull(1)) {
+ data.app_id = query.GetString(1);
+ }
+ ret.push_back(data);
+ }
+ } else {
+ LOG4CXX_WARN(logger_, "Invalid select endpoints statement.");
+ }
+ return ret;
+}
+
+std::string SQLPTRepresentation::GetLockScreenIconUrl() const {
+ utils::dbms::SQLQuery query(db());
+ std::string ret;
+ if (query.Prepare(sql_pt::kSelectLockScreenIcon)) {
+ query.Bind(0, std::string("lock_screen_icon_url"));
+ query.Bind(1, std::string("default"));
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect select from notifications by priority.");
+ return ret;
+ }
+
+ if (!query.IsNull(0)) {
+ ret = query.GetString(0);
+ }
+
+ } else {
+ LOG4CXX_WARN(logger_, "Invalid select endpoints statement.");
+ }
+ return ret;
+}
+
+int SQLPTRepresentation::GetNotificationsNumber(const std::string& priority) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectNotificationsPerPriority)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect select statement for priority "
+ "notification number.");
+ return 0;
+ }
+ query.Bind(0, priority);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect select from notifications by priority.");
+ return 0;
+ }
+
+ if (!query.IsNull(0)) {
+ return query.GetInteger(0);
+ }
+
+ return 0;
+}
+
+bool SQLPTRepresentation::GetPriority(const std::string& policy_app_id,
+ std::string* priority) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (NULL == priority) {
+ LOG4CXX_WARN(logger_, "Input priority parameter is null.");
+ return false;
+ }
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectPriority)) {
+ LOG4CXX_INFO(logger_, "Incorrect statement for priority.");
+ return false;
+ }
+
+ query.Bind(0, policy_app_id);
+
+ if (!query.Exec()) {
+ LOG4CXX_INFO(logger_, "Error during select priority.");
+ return false;
+ }
+
+ if (query.IsNull(0)) {
+ priority->clear();
+ return true;
+ }
+
+ priority->assign(query.GetString(0));
+
+ return true;
+}
+
+InitResult SQLPTRepresentation::Init(const PolicySettings* settings) {
+ settings_ = settings;
+ LOG4CXX_AUTO_TRACE(logger_);
+#ifdef BUILD_TESTS
+ open_counter_ = 0;
+#endif // BUILD_TESTS
+ std::string path = get_settings().app_storage_folder();
+ if (!path.empty()) {
+ db_->set_path(path + "/");
+ }
+ if (!db_->Open()) {
+ LOG4CXX_ERROR(logger_, "Failed opening database.");
+ LOG4CXX_INFO(logger_, "Starting opening retries.");
+ const uint16_t attempts = get_settings().attempts_to_open_policy_db();
+ LOG4CXX_DEBUG(logger_, "Total attempts number is: " << attempts);
+ bool is_opened = false;
+ const uint16_t open_attempt_timeout_ms =
+ get_settings().open_attempt_timeout_ms();
+ const useconds_t sleep_interval_mcsec = open_attempt_timeout_ms * 1000;
+ LOG4CXX_DEBUG(logger_,
+ "Open attempt timeout(ms) is: " << open_attempt_timeout_ms);
+ for (int i = 0; i < attempts; ++i) {
+ usleep(sleep_interval_mcsec);
+ LOG4CXX_INFO(logger_, "Attempt: " << i + 1);
+#ifdef BUILD_TESTS
+ ++open_counter_;
+#endif // BUILD_TESTS
+ if (db_->Open()) {
+ LOG4CXX_INFO(logger_, "Database opened.");
+ is_opened = true;
+ break;
+ }
+ }
+ if (!is_opened) {
+ LOG4CXX_ERROR(logger_,
+ "Open retry sequence failed. Tried "
+ << attempts << " attempts with "
+ << open_attempt_timeout_ms
+ << " open timeout(ms) for each.");
+ return InitResult::FAIL;
+ }
+ }
+#ifndef __QNX__
+ if (!db_->IsReadWrite()) {
+ LOG4CXX_ERROR(logger_, "There are no read/write permissions for database");
+ return InitResult::FAIL;
+ }
+
+#endif // __QNX__
+ utils::dbms::SQLQuery check_pages(db());
+ if (!check_pages.Prepare(sql_pt::kCheckPgNumber) || !check_pages.Next()) {
+ LOG4CXX_WARN(logger_, "Incorrect pragma for page counting.");
+ } else {
+ if (0 < check_pages.GetInteger(0)) {
+ utils::dbms::SQLQuery db_check(db());
+ if (!db_check.Prepare(sql_pt::kCheckDBIntegrity)) {
+ LOG4CXX_WARN(logger_, "Incorrect pragma for integrity check.");
+ } else {
+ while (db_check.Next()) {
+ if (db_check.GetString(0).compare("ok") == 0) {
+ utils::dbms::SQLQuery check_first_run(db());
+ if (check_first_run.Prepare(sql_pt::kIsFirstRun) &&
+ check_first_run.Next()) {
+ LOG4CXX_INFO(logger_,
+ "Selecting is first run "
+ << check_first_run.GetBoolean(0));
+ if (check_first_run.GetBoolean(0)) {
+ utils::dbms::SQLQuery set_not_first_run(db());
+ set_not_first_run.Exec(sql_pt::kSetNotFirstRun);
+ return InitResult::SUCCESS;
+ }
+ } else {
+ LOG4CXX_WARN(logger_, "Incorrect select is first run");
+ }
+ return InitResult::EXISTS;
+ } else {
+ LOG4CXX_ERROR(logger_,
+ "Existing policy table representation is invlaid.");
+ // TODO(PV): add handle
+ return InitResult::FAIL;
+ }
+ }
+ }
+ }
+ }
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kCreateSchema)) {
+ LOG4CXX_ERROR(
+ logger_,
+ "Failed creating schema of database: " << query.LastError().text());
+ return InitResult::FAIL;
+ }
+ if (!query.Exec(sql_pt::kInsertInitData)) {
+ LOG4CXX_ERROR(
+ logger_,
+ "Failed insert init data to database: " << query.LastError().text());
+ return InitResult::FAIL;
+ }
+ return InitResult::SUCCESS;
+}
+
+bool SQLPTRepresentation::Close() {
+ db_->Close();
+ return db_->LastError().number() == utils::dbms::OK;
+}
+
+const VehicleInfo SQLPTRepresentation::GetVehicleInfo() const {
+ policy_table::ModuleConfig module_config;
+ GatherModuleConfig(&module_config);
+ VehicleInfo vehicle_info;
+ vehicle_info.vehicle_make = *module_config.vehicle_make;
+ vehicle_info.vehicle_model = *module_config.vehicle_model;
+ vehicle_info.vehicle_year = *module_config.vehicle_year;
+ return vehicle_info;
+}
+
+bool SQLPTRepresentation::Drop() {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDropSchema)) {
+ LOG4CXX_WARN(logger_,
+ "Failed dropping database: " << query.LastError().text());
+ return false;
+ }
+ return true;
+}
+
+void SQLPTRepresentation::WriteDb() {
+ db_->Backup();
+}
+
+bool SQLPTRepresentation::Clear() {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteData)) {
+ LOG4CXX_ERROR(logger_,
+ "Failed clearing database: " << query.LastError().text());
+ return false;
+ }
+ if (!query.Exec(sql_pt::kInsertInitData)) {
+ LOG4CXX_ERROR(
+ logger_,
+ "Failed insert init data to database: " << query.LastError().text());
+ return false;
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::RefreshDB() {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDropSchema)) {
+ LOG4CXX_WARN(logger_,
+ "Failed dropping database: " << query.LastError().text());
+ return false;
+ }
+ if (!query.Exec(sql_pt::kCreateSchema)) {
+ LOG4CXX_ERROR(
+ logger_,
+ "Failed creating schema of database: " << query.LastError().text());
+ return false;
+ }
+ if (!query.Exec(sql_pt::kInsertInitData)) {
+ LOG4CXX_ERROR(
+ logger_,
+ "Failed insert init data to database: " << query.LastError().text());
+ return false;
+ }
+ return true;
+}
+
+utils::SharedPtr<policy_table::Table> SQLPTRepresentation::GenerateSnapshot()
+ const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::SharedPtr<policy_table::Table> table = new policy_table::Table();
+ GatherModuleMeta(&*table->policy_table.module_meta);
+ GatherModuleConfig(&table->policy_table.module_config);
+ GatherUsageAndErrorCounts(&*table->policy_table.usage_and_error_counts);
+ GatherDeviceData(&*table->policy_table.device_data);
+ GatherFunctionalGroupings(&table->policy_table.functional_groupings);
+ GatherConsumerFriendlyMessages(
+ &*table->policy_table.consumer_friendly_messages);
+ GatherApplicationPoliciesSection(&table->policy_table.app_policies_section);
+ return table;
+}
+
+void SQLPTRepresentation::GatherModuleMeta(
+ policy_table::ModuleMeta* meta) const {
+ LOG4CXX_INFO(logger_, "Gather Module Meta Info");
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt::kSelectModuleMeta) && query.Next()) {
+ *meta->pt_exchanged_at_odometer_x = query.GetInteger(0);
+ *meta->pt_exchanged_x_days_after_epoch = query.GetInteger(1);
+ *meta->ignition_cycles_since_last_exchange = query.GetInteger(2);
+ }
+}
+
+void SQLPTRepresentation::GatherModuleConfig(
+ policy_table::ModuleConfig* config) const {
+ LOG4CXX_INFO(logger_, "Gather Configuration Info");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectModuleConfig) || !query.Next()) {
+ LOG4CXX_WARN(logger_, "Incorrect select statement for module config");
+ } else {
+ *config->preloaded_pt = query.GetBoolean(0);
+ config->exchange_after_x_ignition_cycles = query.GetInteger(1);
+ config->exchange_after_x_kilometers = query.GetInteger(2);
+ config->exchange_after_x_days = query.GetInteger(3);
+ config->timeout_after_x_seconds = query.GetInteger(4);
+ *config->certificate = query.GetString(5);
+ *config->vehicle_make = query.GetString(6);
+ *config->vehicle_model = query.GetString(7);
+ *config->vehicle_year = query.GetString(8);
+ *config->preloaded_date = query.GetString(9);
+ }
+
+ utils::dbms::SQLQuery endpoints(db());
+ if (!endpoints.Prepare(sql_pt::kSelectEndpoints)) {
+ LOG4CXX_WARN(logger_, "Incorrect select statement for endpoints");
+ } else {
+ while (endpoints.Next()) {
+ const std::string& url = endpoints.GetString(0);
+ const std::string& service = endpoints.GetString(1);
+ const std::string& app_id = endpoints.GetString(2);
+ config->endpoints[service][app_id].push_back(url);
+ }
+ }
+
+ utils::dbms::SQLQuery notifications(db());
+ if (!notifications.Prepare(sql_pt::kSelectNotificationsPerMin)) {
+ LOG4CXX_WARN(logger_, "Incorrect select statement for notifications");
+ } else {
+ while (notifications.Next()) {
+ config->notifications_per_minute_by_priority[notifications.GetString(0)] =
+ notifications.GetInteger(1);
+ }
+ }
+ utils::dbms::SQLQuery seconds(db());
+ if (!seconds.Prepare(sql_pt::kSelectSecondsBetweenRetries)) {
+ LOG4CXX_INFO(logger_,
+ "Incorrect select statement from seconds between retries");
+ } else {
+ while (seconds.Next()) {
+ config->seconds_between_retries.push_back(seconds.GetInteger(0));
+ }
+ }
+}
+
+bool SQLPTRepresentation::GatherUsageAndErrorCounts(
+ policy_table::UsageAndErrorCounts* counts) const {
+ LOG4CXX_INFO(logger_, "Gather Usage and Error Counts.");
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt::kSelectAppLevels)) {
+ policy_table::AppLevel app_level;
+ app_level.mark_initialized();
+ while (query.Next()) {
+ app_level.count_of_tls_errors = query.GetInteger(1);
+ const std::string app_id = query.GetString(0);
+ (*counts->app_level)[app_id] = app_level;
+ }
+ return true;
+ }
+ return false;
+}
+
+void SQLPTRepresentation::GatherDeviceData(
+ policy_table::DeviceData* data) const {
+ LOG4CXX_INFO(logger_, "Gather device data.");
+ data->mark_initialized();
+
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(sql_pt::kSelectDeviceData)) {
+ policy_table::DeviceParams device_data;
+ device_data.mark_initialized();
+ while (query.Next()) {
+ const std::string device_id = query.GetString(0);
+ (*data)[device_id] = device_data;
+ }
+ }
+}
+
+bool SQLPTRepresentation::GatherFunctionalGroupings(
+ policy_table::FunctionalGroupings* groups) const {
+ LOG4CXX_INFO(logger_, "Gather Functional Groupings info");
+ utils::dbms::SQLQuery func_group(db());
+ if (!func_group.Prepare(sql_pt::kSelectFunctionalGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from functional_groupings");
+ return false;
+ }
+ utils::dbms::SQLQuery rpcs(db());
+ if (!rpcs.Prepare(sql_pt::kSelectAllRpcs)) {
+ LOG4CXX_WARN(logger_, "Incorrect select all from rpc");
+ return false;
+ }
+ while (func_group.Next()) {
+ policy_table::Rpcs rpcs_tbl;
+ if (!func_group.IsNull(2)) {
+ *rpcs_tbl.user_consent_prompt = func_group.GetString(2);
+ }
+ int func_id = func_group.GetInteger(0);
+ rpcs.Bind(0, func_id);
+ while (rpcs.Next()) {
+ if (!rpcs.IsNull(1)) {
+ policy_table::HmiLevel level;
+ if (policy_table::EnumFromJsonString(rpcs.GetString(1), &level)) {
+ InsertUnique(level, &rpcs_tbl.rpcs[rpcs.GetString(0)].hmi_levels);
+ }
+ }
+ if (!rpcs.IsNull(2)) {
+ policy_table::Parameter param;
+ if (policy_table::EnumFromJsonString(rpcs.GetString(2), &param)) {
+ InsertUnique(param, &(*rpcs_tbl.rpcs[rpcs.GetString(0)].parameters));
+ }
+ }
+ }
+ if (!rpcs_tbl.rpcs.is_initialized()) {
+ rpcs_tbl.rpcs.set_to_null();
+ }
+ rpcs.Reset();
+ (*groups)[func_group.GetString(1)] = rpcs_tbl;
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::GatherConsumerFriendlyMessages(
+ policy_table::ConsumerFriendlyMessages* messages) const {
+ LOG4CXX_INFO(logger_, "Gather Consumer Friendly Messages");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectUserMsgsVersion) || !query.Next()) {
+ LOG4CXX_WARN(logger_, "Incorrect select from consumer_friendly_messages");
+ return false;
+ }
+
+ messages->version = query.GetString(0);
+
+ if (query.Prepare(sql_pt::kCollectFriendlyMsg)) {
+ while (query.Next()) {
+ UserFriendlyMessage msg;
+ msg.message_code = query.GetString(7);
+ std::string language = query.GetString(6);
+
+ (*messages->messages)[msg.message_code].languages[language];
+ }
+ } else {
+ LOG4CXX_WARN(logger_, "Incorrect statement for select friendly messages.");
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::GatherApplicationPoliciesSection(
+ policy_table::ApplicationPoliciesSection* policies) const {
+ LOG4CXX_INFO(logger_, "Gather applications policies");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectAppPolicies)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app_policies");
+ return false;
+ }
+
+ while (query.Next()) {
+ rpc::Nullable<policy_table::ApplicationParams> params;
+ const std::string& app_id = query.GetString(0);
+ if (IsApplicationRevoked(app_id)) {
+ params.set_to_null();
+ (*policies).apps[app_id] = params;
+ continue;
+ }
+ if (IsDefaultPolicy(app_id)) {
+ (*policies).apps[app_id].set_to_string(kDefaultId);
+ }
+ if (IsPredataPolicy(app_id)) {
+ (*policies).apps[app_id].set_to_string(kPreDataConsentId);
+ }
+ if (kDeviceId == app_id) {
+ // Priority is only SDL-specific item for device
+ policy_table::Priority priority;
+ policy_table::EnumFromJsonString(query.GetString(1), &priority);
+ (*policies).device.priority = priority;
+ continue;
+ }
+ policy_table::Priority priority;
+ policy_table::EnumFromJsonString(query.GetString(1), &priority);
+ params.priority = priority;
+
+ *params.memory_kb = query.GetInteger(2);
+
+ *params.heart_beat_timeout_ms = query.GetUInteger(3);
+ if (!query.IsNull(3)) {
+ *params.certificate = query.GetString(4);
+ }
+ if (!GatherAppGroup(app_id, &params.groups)) {
+ return false;
+ }
+ if (!GatherNickName(app_id, &*params.nicknames)) {
+ return false;
+ }
+ if (!GatherAppType(app_id, &*params.AppHMIType)) {
+ return false;
+ }
+ if (!GatherRequestType(app_id, &*params.RequestType)) {
+ return false;
+ }
+
+ (*policies).apps[app_id] = params;
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::Save(const policy_table::Table& table) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ db_->BeginTransaction();
+ if (!SaveFunctionalGroupings(table.policy_table.functional_groupings)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ if (!SaveApplicationPoliciesSection(
+ table.policy_table.app_policies_section)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ if (!SaveModuleConfig(table.policy_table.module_config)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ if (!SaveConsumerFriendlyMessages(
+ *table.policy_table.consumer_friendly_messages)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+
+ if (!SaveDeviceData(*table.policy_table.device_data)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ if (!SaveUsageAndErrorCounts(*table.policy_table.usage_and_error_counts)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ if (!SaveModuleMeta(*table.policy_table.module_meta)) {
+ db_->RollbackTransaction();
+ return false;
+ }
+ db_->CommitTransaction();
+ return true;
+}
+
+bool SQLPTRepresentation::SaveFunctionalGroupings(
+ const policy_table::FunctionalGroupings& groups) {
+ utils::dbms::SQLQuery query_delete(db());
+ if (!query_delete.Exec(sql_pt::kDeleteRpc)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from rpc.");
+ return false;
+ }
+
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteFunctionalGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from seconds between retries.");
+ return false;
+ }
+ if (!query.Prepare(sql_pt::kInsertFunctionalGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for functional groups");
+ return false;
+ }
+
+ policy_table::FunctionalGroupings::const_iterator it;
+
+ for (it = groups.begin(); it != groups.end(); ++it) {
+ // Since we uses this id in other tables, we have to be sure
+ // that id for certain group will be same in case when
+ // we drop records from the table and add them again.
+ // That's why we use hash as a primary key insted of
+ // simple auto incremental index.
+ const long int id = abs(CacheManager::GenerateHash(it->first));
+ // SQLite's Bind doesn support 'long' type
+ // So we need to explicitly cast it to int64_t
+ // to avoid ambiguity.
+ query.Bind(0, static_cast<int64_t>(id));
+ query.Bind(1, it->first);
+ it->second.user_consent_prompt.is_initialized()
+ ? query.Bind(2, *(it->second.user_consent_prompt))
+ : query.Bind(2);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into functional groups");
+ return false;
+ }
+
+ if (!SaveRpcs(query.LastInsertId(), it->second.rpcs)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::SaveRpcs(int64_t group_id,
+ const policy_table::Rpc& rpcs) {
+ utils::dbms::SQLQuery query(db());
+ utils::dbms::SQLQuery query_parameter(db());
+ if (!query.Prepare(sql_pt::kInsertRpc) ||
+ !query_parameter.Prepare(sql_pt::kInsertRpcWithParameter)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for rpc");
+ return false;
+ }
+
+ policy_table::Rpc::const_iterator it;
+ for (it = rpcs.begin(); it != rpcs.end(); ++it) {
+ const policy_table::HmiLevels& hmi_levels = it->second.hmi_levels;
+ // TODO(IKozyrenko): Check logic if optional container is missing
+ const policy_table::Parameters& parameters = *it->second.parameters;
+ policy_table::HmiLevels::const_iterator hmi_it;
+ policy_table::Parameters::const_iterator ps_it;
+ for (hmi_it = hmi_levels.begin(); hmi_it != hmi_levels.end(); ++hmi_it) {
+ if (!parameters.empty()) {
+ for (ps_it = parameters.begin(); ps_it != parameters.end(); ++ps_it) {
+ query_parameter.Bind(0, it->first);
+ query_parameter.Bind(
+ 1, std::string(policy_table::EnumToJsonString(*hmi_it)));
+ query_parameter.Bind(
+ 2, std::string(policy_table::EnumToJsonString(*ps_it)));
+ query_parameter.Bind(3, group_id);
+ if (!query_parameter.Exec() || !query_parameter.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into rpc with parameter");
+ return false;
+ }
+ }
+ } else {
+ query.Bind(0, it->first);
+ query.Bind(1, std::string(policy_table::EnumToJsonString(*hmi_it)));
+ query.Bind(2, group_id);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into rpc");
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveApplicationPoliciesSection(
+ const policy_table::ApplicationPoliciesSection& policies) {
+ utils::dbms::SQLQuery query_delete(db());
+ if (!query_delete.Exec(sql_pt::kDeleteAppGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from app_group.");
+ return false;
+ }
+ if (!query_delete.Exec(sql_pt::kDeleteApplication)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from application.");
+ return false;
+ }
+
+ if (!query_delete.Exec(sql_pt::kDeleteRequestType)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from request type.");
+ return false;
+ }
+
+ // All predefined apps (e.g. default, pre_DataConsent) should be saved first,
+ // otherwise another app with the predefined permissions can get incorrect
+ // permissions
+ policy_table::ApplicationPolicies::const_iterator it_default =
+ policies.apps.find(kDefaultId);
+ if (policies.apps.end() != it_default) {
+ if (!SaveSpecificAppPolicy(*it_default)) {
+ return false;
+ }
+ }
+ policy_table::ApplicationPolicies::const_iterator it_pre_data_consented =
+ policies.apps.find(kPreDataConsentId);
+ if (policies.apps.end() != it_pre_data_consented) {
+ if (!SaveSpecificAppPolicy(*it_pre_data_consented)) {
+ return false;
+ }
+ }
+
+ if (!SaveDevicePolicy(policies.device)) {
+ return false;
+ }
+
+ policy_table::ApplicationPolicies::const_iterator it;
+ for (it = policies.apps.begin(); it != policies.apps.end(); ++it) {
+ // Skip saving of predefined app, since they should be saved before
+ if (IsPredefinedApp(*it)) {
+ continue;
+ }
+ if (!SaveSpecificAppPolicy(*it)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveSpecificAppPolicy(
+ const policy_table::ApplicationPolicies::value_type& app) {
+ utils::dbms::SQLQuery app_query(db());
+ if (!app_query.Prepare(sql_pt::kInsertApplication)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement into application (device).");
+ return false;
+ }
+
+ app_query.Bind(0, app.first);
+ app_query.Bind(
+ 1, std::string(policy_table::EnumToJsonString(app.second.priority)));
+ app_query.Bind(2, app.second.is_null());
+ app_query.Bind(3, *app.second.memory_kb);
+ app_query.Bind(4, static_cast<int64_t>(*app.second.heart_beat_timeout_ms));
+ app.second.certificate.is_initialized()
+ ? app_query.Bind(5, *app.second.certificate)
+ : app_query.Bind(5);
+ if (!app_query.Exec() || !app_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into application.");
+ return false;
+ }
+
+ if (app.second.is_string()) {
+ if (kDefaultId.compare(app.second.get_string()) == 0) {
+ if (!SetDefaultPolicy(app.first)) {
+ return false;
+ }
+ // Stop saving other params, since predefined permissions already set
+ return true;
+ }
+ }
+
+ if (!SaveAppGroup(app.first, app.second.groups)) {
+ return false;
+ }
+ if (!SaveNickname(app.first, *app.second.nicknames)) {
+ return false;
+ }
+ if (!SaveAppType(app.first, *app.second.AppHMIType)) {
+ return false;
+ }
+
+ if (!SaveRequestType(app.first, *app.second.RequestType)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool policy::SQLPTRepresentation::SaveDevicePolicy(
+ const policy_table::DevicePolicy& device) {
+ utils::dbms::SQLQuery app_query(db());
+ if (!app_query.Prepare(sql_pt::kInsertApplication)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement into application.");
+ return false;
+ }
+
+ app_query.Bind(0, kDeviceId);
+ app_query.Bind(1,
+ std::string(policy_table::EnumToJsonString(device.priority)));
+ app_query.Bind(2, false);
+ app_query.Bind(3, 0);
+ app_query.Bind(4, 0);
+ app_query.Bind(5);
+
+ if (!app_query.Exec() || !app_query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into application.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveAppGroup(
+ const std::string& app_id, const policy_table::Strings& app_groups) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertAppGroup)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for app group");
+ return false;
+ }
+ LOG4CXX_INFO(logger_, "SaveAppGroup");
+ policy_table::Strings::const_iterator it;
+ for (it = app_groups.begin(); it != app_groups.end(); ++it) {
+ std::string ssss = *it;
+ LOG4CXX_INFO(logger_, "Group: " << ssss);
+ query.Bind(0, app_id);
+ query.Bind(1, *it);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert into app group."
+ << query.LastError().text());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveNickname(const std::string& app_id,
+ const policy_table::Strings& nicknames) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertNickname)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for nickname");
+ return false;
+ }
+
+ policy_table::Strings::const_iterator it;
+ for (it = nicknames.begin(); it != nicknames.end(); ++it) {
+ query.Bind(0, app_id);
+ query.Bind(1, *it);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into nickname.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveAppType(const std::string& app_id,
+ const policy_table::AppHMITypes& types) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertAppType)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for app type");
+ return false;
+ }
+
+ policy_table::AppHMITypes::const_iterator it;
+ for (it = types.begin(); it != types.end(); ++it) {
+ query.Bind(0, app_id);
+ query.Bind(1, std::string(policy_table::EnumToJsonString(*it)));
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into app type.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveRequestType(
+ const std::string& app_id, const policy_table::RequestTypes& types) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertRequestType)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for request types.");
+ return false;
+ }
+
+ policy_table::RequestTypes::const_iterator it;
+ for (it = types.begin(); it != types.end(); ++it) {
+ query.Bind(0, app_id);
+ query.Bind(1, std::string(policy_table::EnumToJsonString(*it)));
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into request types.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveModuleMeta(const policy_table::ModuleMeta& meta) {
+ utils::dbms::SQLQuery query(db());
+
+ if (!query.Prepare(sql_pt::kSaveModuleMeta)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for module_meta.");
+ return false;
+ }
+ const int64_t odometer = *(meta.pt_exchanged_at_odometer_x);
+
+ query.Bind(0, odometer);
+ query.Bind(1, *(meta.pt_exchanged_x_days_after_epoch));
+ query.Bind(2, *(meta.ignition_cycles_since_last_exchange));
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect update for module_meta.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveModuleConfig(
+ const policy_table::ModuleConfig& config) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kUpdateModuleConfig)) {
+ LOG4CXX_WARN(logger_, "Incorrect update statement for module config");
+ return false;
+ }
+
+ bool is_preloaded =
+ config.preloaded_pt.is_initialized() && *config.preloaded_pt;
+
+ query.Bind(0, is_preloaded);
+ query.Bind(1, config.exchange_after_x_ignition_cycles);
+ query.Bind(2, config.exchange_after_x_kilometers);
+ query.Bind(3, config.exchange_after_x_days);
+ query.Bind(4, config.timeout_after_x_seconds);
+ query.Bind(5, (*config.certificate));
+ config.vehicle_make.is_initialized() ? query.Bind(6, *(config.vehicle_make))
+ : query.Bind(6);
+ config.vehicle_model.is_initialized() ? query.Bind(7, *(config.vehicle_model))
+ : query.Bind(7);
+ config.vehicle_year.is_initialized() ? query.Bind(8, *(config.vehicle_year))
+ : query.Bind(8);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect update module config");
+ return false;
+ }
+
+ if (!SaveSecondsBetweenRetries(config.seconds_between_retries)) {
+ return false;
+ }
+
+ if (!SaveNumberOfNotificationsPerMinute(
+ config.notifications_per_minute_by_priority)) {
+ return false;
+ }
+
+ if (!SaveServiceEndpoints(config.endpoints)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveServiceEndpoints(
+ const policy_table::ServiceEndpoints& endpoints) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteEndpoint)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from endpoint.");
+ return false;
+ }
+
+ if (!query.Prepare(sql_pt::kInsertEndpoint)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for endpoint");
+ return false;
+ }
+
+ policy_table::ServiceEndpoints::const_iterator it;
+ for (it = endpoints.begin(); it != endpoints.end(); ++it) {
+ const policy_table::URLList& apps = it->second;
+ policy_table::URLList::const_iterator app_it;
+ for (app_it = apps.begin(); app_it != apps.end(); ++app_it) {
+ const policy_table::URL& urls = app_it->second;
+ policy_table::URL::const_iterator url_it;
+ for (url_it = urls.begin(); url_it != urls.end(); ++url_it) {
+ query.Bind(0, it->first);
+ query.Bind(1, *url_it);
+ query.Bind(2, app_it->first);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into endpoint");
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveConsumerFriendlyMessages(
+ const policy_table::ConsumerFriendlyMessages& messages) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ // According CRS-2419 If there is no “consumer_friendly_messages” key,
+ // the current local consumer_friendly_messages section shall be maintained in
+ // the policy table. So it won't be changed/updated
+ if (messages.messages.is_initialized()) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteMessageString)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from message.");
+ return false;
+ }
+
+ if (query.Prepare(sql_pt::kUpdateVersion)) {
+ query.Bind(0, messages.version);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect update into version.");
+ return false;
+ }
+ } else {
+ LOG4CXX_WARN(logger_, "Incorrect update statement for version.");
+ return false;
+ }
+
+ policy_table::Messages::const_iterator it;
+ for (it = messages.messages->begin(); it != messages.messages->end();
+ ++it) {
+ if (!SaveMessageType(it->first)) {
+ return false;
+ }
+ const policy_table::Languages& langs = it->second.languages;
+ policy_table::Languages::const_iterator lang_it;
+ for (lang_it = langs.begin(); lang_it != langs.end(); ++lang_it) {
+ if (!SaveLanguage(lang_it->first)) {
+ return false;
+ }
+ if (!SaveMessageString(it->first, lang_it->first, lang_it->second)) {
+ return false;
+ }
+ }
+ }
+ } else {
+ LOG4CXX_INFO(logger_, "Messages list is empty");
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveMessageType(const std::string& type) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertMessageType)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for message type.");
+ return false;
+ }
+
+ query.Bind(0, type);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into message type.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveLanguage(const std::string& code) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertLanguage)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for language.");
+ return false;
+ }
+
+ query.Bind(0, code);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into language.");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveMessageString(
+ const std::string& type,
+ const std::string& lang,
+ const policy_table::MessageString& strings) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertMessageString)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for message.");
+ return false;
+ }
+
+ query.Bind(0, lang);
+ query.Bind(1, type);
+
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into message.");
+ return false;
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::SaveSecondsBetweenRetries(
+ const policy_table::SecondsBetweenRetries& seconds) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteSecondsBetweenRetries)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from seconds between retries.");
+ return false;
+ }
+ if (!query.Prepare(sql_pt::kInsertSecondsBetweenRetry)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement for seconds between retries.");
+ return false;
+ }
+
+ for (uint32_t i = 0; i < seconds.size(); ++i) {
+ query.Bind(0, static_cast<int>(i));
+ query.Bind(1, seconds[i]);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into seconds between retries.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveNumberOfNotificationsPerMinute(
+ const policy_table::NumberOfNotificationsPerMinute& notifications) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertNotificationsByPriority)) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect insert statement for notifications by priority.");
+ return false;
+ }
+
+ policy_table::NumberOfNotificationsPerMinute::const_iterator it;
+ for (it = notifications.begin(); it != notifications.end(); ++it) {
+ query.Bind(0, it->first);
+ query.Bind(1, it->second);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into notifications by priority.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveDeviceData(
+ const policy_table::DeviceData& devices) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertDeviceData)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for device data.");
+ return false;
+ }
+
+ policy_table::DeviceData::const_iterator it;
+ for (it = devices.begin(); it != devices.end(); ++it) {
+ query.Bind(0, it->first);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into device data.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::SaveUsageAndErrorCounts(
+ const policy_table::UsageAndErrorCounts& counts) {
+ const_cast<policy_table::UsageAndErrorCounts&>(counts).mark_initialized();
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kDeleteAppLevel)) {
+ LOG4CXX_WARN(logger_, "Incorrect delete from app level.");
+ return false;
+ }
+ if (!query.Prepare(sql_pt::kInsertAppLevel)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement for app level.");
+ return false;
+ }
+
+ policy_table::AppLevels::const_iterator it;
+ const policy_table::AppLevels& app_levels = *counts.app_level;
+ const_cast<policy_table::AppLevels&>(*counts.app_level).mark_initialized();
+ for (it = app_levels.begin(); it != app_levels.end(); ++it) {
+ query.Bind(0, it->first);
+ query.Bind(1, it->second.count_of_tls_errors);
+ if (!query.Exec() || !query.Reset()) {
+ LOG4CXX_WARN(logger_, "Incorrect insert into app level.");
+ return false;
+ }
+ }
+ return true;
+}
+
+void SQLPTRepresentation::IncrementIgnitionCycles() {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kIncrementIgnitionCycles)) {
+ LOG4CXX_WARN(logger_, "Failed incrementing ignition cycles");
+ }
+}
+
+void SQLPTRepresentation::ResetIgnitionCycles() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Exec(sql_pt::kResetIgnitionCycles)) {
+ LOG4CXX_WARN(logger_, "Failed to reset ignition cycles number.");
+ }
+}
+
+bool SQLPTRepresentation::UpdateRequired() const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectFlagUpdateRequired) || !query.Exec()) {
+ LOG4CXX_WARN(logger_,
+ "Failed select update required flag from module meta");
+ return false;
+ }
+ return query.GetBoolean(0);
+}
+
+void SQLPTRepresentation::SaveUpdateRequired(bool value) {
+ utils::dbms::SQLQuery query(db());
+ // TODO(AOleynik): Quick fix, will be reworked
+ if (!query.Prepare(/*sql_pt::kUpdateFlagUpdateRequired*/
+ "UPDATE `module_meta` SET `flag_update_required` = ?")) {
+ LOG4CXX_WARN(logger_,
+ "Incorrect update into module meta (update_required): "
+ << strerror(errno));
+ return;
+ }
+ query.Bind(0, value);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed update module meta (update_required)");
+ }
+}
+
+bool SQLPTRepresentation::GetInitialAppData(const std::string& app_id,
+ StringArray* nicknames,
+ StringArray* app_types) {
+ LOG4CXX_INFO(logger_, "Getting initial application data.");
+ utils::dbms::SQLQuery app_names(db());
+ if (!app_names.Prepare(sql_pt::kSelectNicknames)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app nicknames");
+ return false;
+ }
+ utils::dbms::SQLQuery app_hmi_types(db());
+ if (!app_hmi_types.Prepare(sql_pt::kSelectAppTypes)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app types");
+ return false;
+ }
+ app_names.Bind(0, app_id);
+ while (app_names.Next()) {
+ nicknames->push_back(app_names.GetString(0));
+ }
+ app_names.Reset();
+ app_hmi_types.Bind(0, app_id);
+ while (app_hmi_types.Next()) {
+ app_types->push_back(app_hmi_types.GetString(0));
+ }
+ app_hmi_types.Reset();
+ return true;
+}
+
+bool SQLPTRepresentation::GetFunctionalGroupings(
+ policy_table::FunctionalGroupings& groups) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return GatherFunctionalGroupings(&groups);
+}
+
+bool SQLPTRepresentation::GatherAppType(
+ const std::string& app_id, policy_table::AppHMITypes* app_types) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectAppTypes)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app types");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ while (query.Next()) {
+ policy_table::AppHMIType type;
+ if (!policy_table::EnumFromJsonString(query.GetString(0), &type)) {
+ return false;
+ }
+ app_types->push_back(type);
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::GatherRequestType(
+ const std::string& app_id,
+ policy_table::RequestTypes* request_types) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectRequestTypes)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from request types.");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ while (query.Next()) {
+ policy_table::RequestType type;
+ if (!policy_table::EnumFromJsonString(query.GetString(0), &type)) {
+ return false;
+ }
+ request_types->push_back(type);
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::GatherNickName(
+ const std::string& app_id, policy_table::Strings* nicknames) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectNicknames)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app nicknames");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ while (query.Next()) {
+ nicknames->push_back(query.GetString(0));
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::GatherAppGroup(
+ const std::string& app_id, policy_table::Strings* app_groups) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectAppGroups)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from app groups");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ while (query.Next()) {
+ app_groups->push_back(query.GetString(0));
+ }
+ return true;
+}
+
+bool SQLPTRepresentation::SaveApplicationCustomData(const std::string& app_id,
+ bool is_revoked,
+ bool is_default,
+ bool is_predata) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kUpdateApplicationCustomData)) {
+ LOG4CXX_WARN(logger_, "Incorrect update in application");
+ return false;
+ }
+
+ query.Bind(0, is_revoked);
+ query.Bind(1, is_default);
+ query.Bind(2, is_predata);
+ query.Bind(3, app_id);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed update in application");
+ return false;
+ }
+
+ return true;
+}
+
+bool SQLPTRepresentation::IsApplicationRevoked(
+ const std::string& app_id) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectApplicationRevoked)) {
+ LOG4CXX_WARN(logger_, "Incorrect select from is_revoked of application");
+ }
+
+ query.Bind(0, app_id);
+
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed select is_revoked of application");
+ return false;
+ }
+ return query.IsNull(0) ? false : query.GetBoolean(0);
+}
+bool SQLPTRepresentation::IsApplicationRepresented(
+ const std::string& app_id) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectApplicationRepresented)) {
+ LOG4CXX_WARN(logger_, "Incorrect select application by id");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed select application by id");
+ return false;
+ }
+ return query.GetInteger(0) != 0;
+}
+
+bool SQLPTRepresentation::IsDefaultPolicy(const std::string& app_id) const {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectApplicationIsDefault)) {
+ LOG4CXX_WARN(logger_, "Incorrect select application by id");
+ return false;
+ }
+
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed select application by id");
+ return false;
+ }
+ return query.IsNull(0) ? false : query.GetBoolean(0);
+}
+
+bool SQLPTRepresentation::IsPredataPolicy(const std::string& app_id) const {
+ return false;
+}
+
+bool SQLPTRepresentation::SetDefaultPolicy(const std::string& app_id) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kDeleteAppGroupByApplicationId)) {
+ LOG4CXX_ERROR(logger_, "Incorrect statement to delete from app_group.");
+ return false;
+ }
+ query.Bind(0, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_ERROR(logger_, "Failed deleting from app_group.");
+ return false;
+ }
+
+ if (!CopyApplication(kDefaultId, app_id)) {
+ return false;
+ }
+
+ SetPreloaded(false);
+
+ policy_table::Strings default_groups;
+ if (!GatherAppGroup(kDefaultId, &default_groups) ||
+ !SaveAppGroup(app_id, default_groups)) {
+ return false;
+ }
+ policy_table::RequestTypes request_types;
+ if (!GatherRequestType(kDefaultId, &request_types) ||
+ !SaveRequestType(app_id, request_types)) {
+ return false;
+ }
+ policy_table::AppHMITypes app_types;
+ if (!GatherAppType(kDefaultId, &app_types) ||
+ !SaveAppType(app_id, app_types)) {
+ return false;
+ }
+ return SetIsDefault(app_id, true);
+}
+
+bool SQLPTRepresentation::SetIsDefault(const std::string& app_id,
+ bool is_default) const {
+ LOG4CXX_TRACE(logger_, "Set flag is_default of application");
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kUpdateIsDefault)) {
+ LOG4CXX_WARN(logger_, "Incorect statement for updating is_default");
+ return false;
+ }
+
+ query.Bind(0, is_default);
+ query.Bind(1, app_id);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed update is_default");
+ return false;
+ }
+ return true;
+}
+
+void SQLPTRepresentation::RemoveDB() const {
+ file_system::DeleteFile(db_->get_path());
+}
+
+bool SQLPTRepresentation::IsDBVersionActual() const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kSelectDBVersion) || !query.Exec()) {
+ LOG4CXX_ERROR(logger_,
+ "Failed to get DB version: " << query.LastError().text());
+ return false;
+ }
+
+ const int32_t saved_db_version = query.GetInteger(0);
+ const int32_t current_db_version = GetDBVersion();
+ LOG4CXX_DEBUG(logger_,
+ "Saved DB version is: " << saved_db_version
+ << ". Current DB vesion is: "
+ << current_db_version);
+
+ return current_db_version == saved_db_version;
+}
+
+bool SQLPTRepresentation::UpdateDBVersion() const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kUpdateDBVersion)) {
+ LOG4CXX_ERROR(logger_,
+ "Incorrect DB version query: " << query.LastError().text());
+ return false;
+ }
+
+ const int32_t db_version = GetDBVersion();
+ LOG4CXX_DEBUG(logger_, "DB version will be updated to: " << db_version);
+ query.Bind(0, db_version);
+
+ if (!query.Exec()) {
+ LOG4CXX_ERROR(logger_,
+ "DB version getting failed: " << query.LastError().text());
+ return false;
+ }
+
+ return true;
+}
+
+const int32_t SQLPTRepresentation::GetDBVersion() const {
+ return utils::Djb2HashFromString(sql_pt::kCreateSchema);
+}
+
+utils::dbms::SQLDatabase* SQLPTRepresentation::db() const {
+#ifdef __QNX__
+ utils::dbms::SQLDatabase* db = new utils::dbms::SQLDatabase(kDatabaseName);
+ db->Open();
+ return db;
+#else
+ return db_;
+#endif
+}
+
+bool SQLPTRepresentation::CopyApplication(const std::string& source,
+ const std::string& destination) {
+ utils::dbms::SQLQuery source_app(db());
+ if (!source_app.Prepare(sql_pt::kSelectApplicationFull)) {
+ LOG4CXX_WARN(logger_, "Incorrect select statement from application.");
+ return false;
+ }
+ source_app.Bind(0, source);
+ if (!source_app.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed selecting from application.");
+ return false;
+ }
+
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kInsertApplicationFull)) {
+ LOG4CXX_WARN(logger_, "Incorrect insert statement into application.");
+ return false;
+ }
+ query.Bind(0, destination);
+ source_app.IsNull(0) ? query.Bind(1)
+ : query.Bind(1, source_app.GetBoolean(0));
+ source_app.IsNull(1) ? query.Bind(2)
+ : query.Bind(2, source_app.GetBoolean(1));
+ source_app.IsNull(2) ? query.Bind(3) : query.Bind(3, source_app.GetString(2));
+ source_app.IsNull(3) ? query.Bind(4) : query.Bind(4, source_app.GetString(3));
+ source_app.IsNull(4) ? query.Bind(5)
+ : query.Bind(5, source_app.GetBoolean(4));
+ source_app.IsNull(5) ? query.Bind(6)
+ : query.Bind(6, source_app.GetBoolean(5));
+ source_app.IsNull(6) ? query.Bind(7)
+ : query.Bind(7, source_app.GetBoolean(6));
+ query.Bind(8, source_app.GetInteger(7));
+ query.Bind(9, source_app.GetInteger(8));
+ source_app.IsNull(9) ? query.Bind(10)
+ : query.Bind(10, source_app.GetString(9));
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed inserting into application.");
+ return false;
+ }
+ return true;
+}
+
+void SQLPTRepresentation::SetPreloaded(bool value) {
+ utils::dbms::SQLQuery query(db());
+ if (!query.Prepare(sql_pt::kUpdatePreloaded)) {
+ LOG4CXX_WARN(logger_, "Incorrect statement of updating preloaded.");
+ return;
+ }
+
+ query.Bind(0, value);
+ if (!query.Exec()) {
+ LOG4CXX_WARN(logger_, "Failed updating preloaded.");
+ return;
+ }
+}
+
+bool SQLPTRepresentation::SetVINValue(const std::string& value) {
+ return true;
+}
+
+} // namespace policy
diff --git a/src/components/policy/policy_regular/src/status.cc b/src/components/policy/policy_regular/src/status.cc
new file mode 100644
index 0000000000..8d65c606d0
--- /dev/null
+++ b/src/components/policy/policy_regular/src/status.cc
@@ -0,0 +1,141 @@
+/*
+ Copyright (c) 2016, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "policy/status.h"
+#include "policy/update_status_manager_interface.h"
+#include "utils/make_shared.h"
+
+policy::UpToDateStatus::UpToDateStatus()
+ : Status("UP_TO_DATE", policy::PolicyTableStatus::StatusUpToDate) {}
+
+void policy::UpToDateStatus::ProcessEvent(UpdateStatusManagerInterface* manager,
+ policy::UpdateEvent event) {
+ switch (event) {
+ case kOnNewAppRegistered:
+ case kOnResetPolicyTableRequireUpdate:
+ case kScheduleUpdate:
+ case kOnResetRetrySequence:
+ manager->SetNextStatus(utils::MakeShared<UpdateNeededStatus>());
+ break;
+ default:
+ break;
+ }
+}
+
+policy::UpdateNeededStatus::UpdateNeededStatus()
+ : Status("UPDATE_NEEDED", policy::PolicyTableStatus::StatusUpdateRequired) {
+}
+
+void policy::UpdateNeededStatus::ProcessEvent(
+ policy::UpdateStatusManagerInterface* manager, policy::UpdateEvent event) {
+ switch (event) {
+ case kOnUpdateSentOut:
+ manager->SetNextStatus(utils::MakeShared<UpdatingStatus>());
+ break;
+ case kOnResetPolicyTableRequireUpdate:
+ manager->SetNextStatus(utils::MakeShared<UpToDateStatus>());
+ manager->SetPostponedStatus(utils::MakeShared<UpdateNeededStatus>());
+ break;
+ case kOnResetPolicyTableNoUpdate:
+ manager->SetNextStatus(utils::MakeShared<UpToDateStatus>());
+ break;
+ case kOnNewAppRegistered:
+ manager->SetNextStatus(utils::MakeShared<UpdateNeededStatus>());
+ break;
+ default:
+ break;
+ }
+}
+
+bool policy::UpdateNeededStatus::IsUpdateRequired() const {
+ return true;
+}
+
+policy::UpdatingStatus::UpdatingStatus()
+ : Status("UPDATING", policy::PolicyTableStatus::StatusUpdatePending) {}
+
+void policy::UpdatingStatus::ProcessEvent(
+ policy::UpdateStatusManagerInterface* manager, policy::UpdateEvent event) {
+ switch (event) {
+ case kOnValidUpdateReceived:
+ case kOnResetPolicyTableNoUpdate:
+ manager->SetNextStatus(utils::MakeShared<UpToDateStatus>());
+ break;
+ case kOnNewAppRegistered:
+ manager->SetPostponedStatus(utils::MakeShared<UpdateNeededStatus>());
+ break;
+ case kOnWrongUpdateReceived:
+ case kOnUpdateTimeout:
+ manager->SetNextStatus(utils::MakeShared<UpdateNeededStatus>());
+ break;
+ case kOnResetPolicyTableRequireUpdate:
+ manager->SetNextStatus(utils::MakeShared<UpToDateStatus>());
+ manager->SetPostponedStatus(utils::MakeShared<UpdateNeededStatus>());
+ break;
+ case kScheduleUpdate:
+ case kOnResetRetrySequence:
+ manager->SetPostponedStatus(utils::MakeShared<UpdateNeededStatus>());
+ break;
+ default:
+ break;
+ }
+}
+
+bool policy::UpdatingStatus::IsUpdatePending() const {
+ return true;
+}
+
+bool policy::UpdatingStatus::IsUpdateRequired() const {
+ return true;
+}
+
+policy::Status::Status(const std::string& string_status,
+ const policy::PolicyTableStatus enum_status)
+ : string_status_(string_status), enum_status_(enum_status) {}
+
+policy::Status::~Status() {}
+
+const std::string policy::Status::get_status_string() const {
+ return string_status_;
+}
+
+policy::PolicyTableStatus policy::Status::get_status() const {
+ return enum_status_;
+}
+
+bool policy::Status::IsUpdateRequired() const {
+ return false;
+}
+
+bool policy::Status::IsUpdatePending() const {
+ return false;
+}
diff --git a/src/components/policy/policy_regular/src/update_status_manager.cc b/src/components/policy/policy_regular/src/update_status_manager.cc
new file mode 100644
index 0000000000..941113c753
--- /dev/null
+++ b/src/components/policy/policy_regular/src/update_status_manager.cc
@@ -0,0 +1,190 @@
+/*
+ Copyright (c) 2014, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "policy/update_status_manager.h"
+#include "policy/policy_listener.h"
+#include "utils/logger.h"
+#include "utils/make_shared.h"
+
+namespace policy {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Policy")
+
+UpdateStatusManager::UpdateStatusManager()
+ : listener_(NULL)
+ , current_status_(utils::MakeShared<UpToDateStatus>())
+ , last_processed_event_(kNoEvent)
+ , apps_search_in_progress_(false)
+ , app_registered_from_non_consented_device_(true) {}
+
+UpdateStatusManager::~UpdateStatusManager() {}
+
+void UpdateStatusManager::ProcessEvent(UpdateEvent event) {
+ sync_primitives::AutoLock lock(status_lock_);
+ current_status_->ProcessEvent(this, event);
+ last_processed_event_ = event;
+ DoTransition();
+}
+
+void UpdateStatusManager::SetNextStatus(utils::SharedPtr<Status> status) {
+ next_status_ = status;
+}
+
+void UpdateStatusManager::SetPostponedStatus(utils::SharedPtr<Status> status) {
+ postponed_status_ = status;
+}
+
+void UpdateStatusManager::set_listener(PolicyListener* listener) {
+ listener_ = listener;
+}
+
+void UpdateStatusManager::OnUpdateSentOut() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ ProcessEvent(kOnUpdateSentOut);
+}
+
+void UpdateStatusManager::OnUpdateTimeoutOccurs() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ ProcessEvent(kOnUpdateTimeout);
+}
+
+void UpdateStatusManager::OnValidUpdateReceived() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ ProcessEvent(kOnValidUpdateReceived);
+}
+
+void UpdateStatusManager::OnWrongUpdateReceived() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ ProcessEvent(kOnWrongUpdateReceived);
+}
+
+void UpdateStatusManager::OnResetDefaultPT(bool is_update_required) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (is_update_required) {
+ ProcessEvent(kOnResetPolicyTableRequireUpdate);
+ return;
+ }
+ ProcessEvent(kOnResetPolicyTableNoUpdate);
+}
+
+void UpdateStatusManager::OnResetRetrySequence() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ ProcessEvent(kOnResetRetrySequence);
+}
+
+void UpdateStatusManager::OnNewApplicationAdded(const DeviceConsent consent) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (kDeviceAllowed != consent) {
+ app_registered_from_non_consented_device_ = true;
+ return;
+ }
+ app_registered_from_non_consented_device_ = false;
+ ProcessEvent(kOnNewAppRegistered);
+}
+
+void UpdateStatusManager::OnPolicyInit(bool is_update_required) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (is_update_required) {
+ current_status_.reset(new UpToDateStatus());
+ ProcessEvent(kScheduleUpdate);
+ }
+}
+
+void UpdateStatusManager::OnDeviceConsented() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (app_registered_from_non_consented_device_) {
+ ProcessEvent(kOnNewAppRegistered);
+ }
+}
+
+bool UpdateStatusManager::IsUpdateRequired() const {
+ return current_status_->IsUpdateRequired();
+}
+
+bool UpdateStatusManager::IsUpdatePending() const {
+ return current_status_->IsUpdatePending();
+}
+
+void UpdateStatusManager::ScheduleUpdate() {
+ ProcessEvent(kScheduleUpdate);
+}
+
+void UpdateStatusManager::ScheduleManualUpdate() {
+ ProcessEvent(kScheduleManualUpdate);
+}
+
+std::string UpdateStatusManager::StringifiedUpdateStatus() const {
+ return current_status_->get_status_string();
+}
+
+void policy::UpdateStatusManager::OnAppsSearchStarted() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(apps_search_in_progress_lock_);
+ apps_search_in_progress_ = true;
+}
+
+void policy::UpdateStatusManager::OnAppsSearchCompleted() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(apps_search_in_progress_lock_);
+ apps_search_in_progress_ = false;
+}
+
+bool policy::UpdateStatusManager::IsAppsSearchInProgress() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(apps_search_in_progress_lock_);
+ return apps_search_in_progress_;
+}
+
+void UpdateStatusManager::DoTransition() {
+ DCHECK_OR_RETURN_VOID(listener_);
+ if (!next_status_) {
+ return;
+ }
+
+ current_status_ = next_status_;
+ next_status_.reset();
+ LOG4CXX_DEBUG(logger_, "last_processed_event_ = " << last_processed_event_);
+ if (last_processed_event_ != kScheduleManualUpdate) {
+ listener_->OnUpdateStatusChanged(current_status_->get_status_string());
+ }
+ if (!postponed_status_) {
+ return;
+ }
+
+ current_status_ = postponed_status_;
+ if (last_processed_event_ != kScheduleManualUpdate) {
+ listener_->OnUpdateStatusChanged(current_status_->get_status_string());
+ }
+ postponed_status_.reset();
+}
+
+} // namespace policy
diff --git a/src/components/policy/policy_regular/src/usage_statistics/counter.cc b/src/components/policy/policy_regular/src/usage_statistics/counter.cc
new file mode 100644
index 0000000000..60e34a929d
--- /dev/null
+++ b/src/components/policy/policy_regular/src/usage_statistics/counter.cc
@@ -0,0 +1,122 @@
+/*
+ Copyright (c) 2013, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_POLICY_INCLUDE_POLICY_STATISTICS_MANAGER_H_
+#define SRC_COMPONENTS_POLICY_INCLUDE_POLICY_STATISTICS_MANAGER_H_
+
+#include <cassert>
+#include "policy/usage_statistics/counter.h"
+#include "utils/date_time.h"
+#include "utils/make_shared.h"
+#include "utils/timer_task_impl.h"
+
+namespace usage_statistics {
+
+GlobalCounter::GlobalCounter(
+ utils::SharedPtr<StatisticsManager> statistics_manager,
+ GlobalCounterId counter_type)
+ : counter_type_(counter_type), statistics_manager_(statistics_manager) {}
+
+void GlobalCounter::operator++() const {
+ if (statistics_manager_) {
+ statistics_manager_->Increment(counter_type_);
+ }
+}
+
+AppCounter::AppCounter(utils::SharedPtr<StatisticsManager> statistics_manager,
+ const std::string& app_id,
+ AppCounterId counter_type)
+ : app_id_(app_id)
+ , counter_type_(counter_type)
+ , statistics_manager_(statistics_manager) {}
+
+void AppCounter::operator++() const {
+ if (statistics_manager_) {
+ statistics_manager_->Increment(app_id_, counter_type_);
+ }
+}
+
+AppInfo::AppInfo(utils::SharedPtr<StatisticsManager> statistics_manager,
+ const std::string& app_id,
+ AppInfoId info_type)
+ : app_id_(app_id)
+ , info_type_(info_type)
+ , statistics_manager_(statistics_manager) {}
+
+void AppInfo::Update(const std::string& new_info) const {
+ if (statistics_manager_) {
+ statistics_manager_->Set(app_id_, info_type_, new_info);
+ }
+}
+
+AppStopwatchImpl::AppStopwatchImpl(
+ utils::SharedPtr<StatisticsManager> statistics_manager,
+ const std::string& app_id)
+ : app_id_(app_id)
+ , stopwatch_type_(SECONDS_HMI_NONE)
+ , statistics_manager_(statistics_manager)
+ , timer_("HMI levels timer",
+ new timer::TimerTaskImpl<AppStopwatchImpl>(
+ this, &AppStopwatchImpl::WriteTime))
+ , time_out_(60) {}
+
+AppStopwatchImpl::AppStopwatchImpl(
+ utils::SharedPtr<StatisticsManager> statistics_manager,
+ const std::string& app_id,
+ uint32_t timeout)
+ : app_id_(app_id)
+ , stopwatch_type_(SECONDS_HMI_NONE)
+ , statistics_manager_(statistics_manager)
+ , timer_("HMI levels timer",
+ new timer::TimerTaskImpl<AppStopwatchImpl>(
+ this, &AppStopwatchImpl::WriteTime))
+ , time_out_(timeout) {}
+
+void AppStopwatchImpl::Start(AppStopwatchId stopwatch_type) {
+ stopwatch_type_ = stopwatch_type;
+ timer_.Start(time_out_ * date_time::DateTime::MILLISECONDS_IN_SECOND,
+ timer::kPeriodic);
+}
+
+void AppStopwatchImpl::Switch(AppStopwatchId stopwatch_type) {
+ Start(stopwatch_type);
+}
+
+void AppStopwatchImpl::WriteTime() {
+ if (statistics_manager_) {
+ statistics_manager_->Add(app_id_, stopwatch_type_, time_out_);
+ }
+}
+
+} // namespace usage_statistics
+
+#endif // SRC_COMPONENTS_POLICY_INCLUDE_POLICY_STATISTICS_MANAGER_H_